All Products
Search
Document Center

PolarDB:ip4r

Last Updated:Oct 27, 2024

This topic presents the background information, data types, and usage of the ip4r extension.

Prerequisites

A PolarDB for PostgreSQL cluster that runs one of the following versions is created:

  • PostgreSQL 14 (revision version 14.9.13.0 or later)

  • PostgreSQL 11 (revision version 1.1.36 or later)

Note

You can execute one of the following statements to view the revision version of a PolarDB for PostgreSQL cluster:

  • PostgreSQL 14

    SELECT version();
  • PostgreSQL 11

    SHOW polar_version;

Overview

ip4r is a third-party extension supported by PolarDB for PostgreSQL. It offers data types to store IPv4 or IPv6 addresses. Different from the inet/cidr data types offered by PostgreSQL, the ip4r extension supports index scans when a query uses the >>= (contains or equals) operator. In addition, the ip4r extension has the following advantages over the built-in network address types of PostgreSQL:

  • Less semantic overload: It offers specialized data types for handling a netblock and a particular IP address.

  • Lower overheads: PostgreSQL uses variable-length data types to store both IPv6 and IPv4 addresses. This leads to large overheads in use cases that involve IPv4 addresses only. The ip4r extension offers fixed-length data types tailored for IPv4 or IPv6 addresses.

Data type

ip4r provides a wide range of data types to store and represent IPv4 and IPv6 addresses:

Data type

Description

ip4

A single IPv4 address

ip4r

An IPv4 netblock

ip6

A single IPv6 address

ip6r

An IPv6 netblock

ipaddress

A single IPv4 or IPv6 address

iprange

An IPv4 or IPv6 netblock

Data types for single IP addresses and type conversion

The following three data types are used to store single IP addresses:

  • ip4: Accepts input in the form of nnn.nnn.nnn.nnn. It stores an IP address as a 32-bit unsigned integer.

  • ip6: Accepts input in the form of standard hexadecimal representation for an IPv6 address. It stores an IP address as two 64-bit values.

  • ipaddress: Accepts input which is valid for either ip4 or ip6.

The following table describes type conversions for the preceding three types in ip4r.

Note

ipX in the table represents any of the preceding three data types.

Source type

Destination type

Syntax

ipX

text

text(ipX) or ipX::text (explicit)

text

ipX

ipX(text) or text::ipX (explicit)

ipX

cidr

cidr(ipX) or ipX::cidr (assignment)

inet

ipX

ipX(inet) or inet::ipX (assignment)

ipX

numeric

to_numeric(ipX) or ipX::numeric (explicit)

numeric

ipX

ipX(numeric) or bigint::ipX (explicit)

ip4

bigint

to_bigint(ip4) or ip4::bigint (explicit)

bigint

ip4

ip4(bigint) or bigint::ip4 (explicit)

ip4

float8

to_double(ip4) or ip4::float8 (explicit)

float8

ip4

ip4(float8) or float8::ip4 (explicit)

ipX

varbit

to_bit(ipX) or ipX::varbit (explicit)

bit(32)

ip4

ip4(bit) or bit::ip4 (explicit)

bit(128)

ip6

ip6(bit) or bit::ip6 (explicit)

varbit

ipX

ipX(varbit) or varbit::ipX (explicit)

ipX

bytea

to_bytea(ipX) or ipX::bytea (explicit)

bytea

ipX

ipX(bytea) or bytea::ipX (explicit)

ipX

ipXr

ipXr(ipX) or ipX::ipXr (implicit)

ip4

ipaddress

ipaddress(ip4) or ip4::ipaddress (implicit)

ip6

ipaddress

ipaddress(ip6) or ip6::ipaddress (implicit)

ipaddress

ip4

ip4(ipaddress) or ipaddress::ip4 (assignment)

ipaddress

ip6

ip6(ipaddress) or ipaddress::ip6 (assignment)

Data types for netblocks and type conversion

The following three data types are used to store a netblock:

  • ip4r: Used to store an IPv4 netblock, such as 192.0.2.100–192.0.2.200. Also accepts input in the form of CIDR blocks such as 192.0.2.0/24, which is equivalent to 192.0.2.0–192.0.2.255.

  • ip6r: Used to store an IPv6 netblock, such as 2001::1234–2001::2000:0000. Also accepts input in the form of CIDR blocks such as 2001::/112, which is equivalent to 2001::–2001::ffff.

  • iprange: Accepts input which is valid for either ip4r or ip6r.

The following table describes type conversions for the preceding three types in ip4r.

Note

ipXr represents any of the above three data types.

Source type

Destination type

Syntax

ipX

ipXr

ipXr(ipX) or ipX::ipXr (implicit)

ipXr

text

text(ipXr) or ipXr::text (explicit)

text

ipXr

ipXr(text) or text::ipXr (explicit)

ipXr

cidr

cidr(ipXr) or ipXr::cidr (explicit)

cidr

ipXr

ipXr(cidr) or cidr::ipXr (assignment)

ipXr

varbit

to_bit(ipXr) or ipXr::varbit (explicit)

varbit

ip4r

ip4r(varbit) or varbit::ip4r (explicit)

varbit

ip6r

ip6r(varbit) or varbit::ip6r (explicit)

Usage

Create the ip4r extension

CREATE EXTENSION ip4r;

Create a test table and import data to the table

CREATE TABLE ipranges (r iprange, r4 ip4r, r6 ip6r);
INSERT INTO ipranges
    SELECT r, null, r
    FROM (
        SELECT ip6r(regexp_replace(ls, E'(....(?!$))', E'\\1:', 'g')::ip6,
               regexp_replace(substring(ls FOR n + 1) || substring(us FROM n + 2),
               E'(....(?!$))', E'\\1:', 'g')::ip6) AS r
        FROM (
            SELECT md5(i || ' lower 1') AS ls,
                   md5(i || ' upper 1') AS us,
                   (i % 11) + (i/11 % 11) + (i/121 % 11) AS n
            FROM generate_series(1,13310) i) s1) s2;

Create a GiST index

CREATE INDEX ipranges_r ON ipranges USING gist (r);

Use the >>= (contains or equals) operator

EXPLAIN (COSTS OFF) SELECT * FROM ipranges WHERE r >>= '5555::' ORDER BY r;
                     QUERY PLAN
-----------------------------------------------------
 Sort
   Sort Key: r
   ->  Bitmap Heap Scan on ipranges
         Recheck Cond: (r >>= '5555::'::iprange)
         ->  Bitmap Index Scan on ipranges_r
               Index Cond: (r >>= '5555::'::iprange)
(6 rows)

Remove the extension

DROP EXTENSION ip4r;