Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
435 changes: 435 additions & 0 deletions src/backend/utils/adt/network.c

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions src/include/catalog/pg_amproc.dat
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@
amproc => 'in_range(float4,float4,float8,bool,bool)' },
{ amprocfamily => 'btree/network_ops', amproclefttype => 'inet',
amprocrighttype => 'inet', amprocnum => '1', amproc => 'network_cmp' },
{ amprocfamily => 'btree/network_ops', amproclefttype => 'inet',
amprocrighttype => 'inet', amprocnum => '2',
amproc => 'network_sortsupport' },
{ amprocfamily => 'btree/integer_ops', amproclefttype => 'int2',
amprocrighttype => 'int2', amprocnum => '1', amproc => 'btint2cmp' },
{ amprocfamily => 'btree/integer_ops', amproclefttype => 'int2',
Expand Down
3 changes: 3 additions & 0 deletions src/include/catalog/pg_proc.dat
Original file line number Diff line number Diff line change
Expand Up @@ -3898,6 +3898,9 @@
{ oid => '3551',
proname => 'network_overlap', prorettype => 'bool',
proargtypes => 'inet inet', prosrc => 'network_overlap' },
{ oid => '3424', descr => 'sort support',
proname => 'network_sortsupport', prorettype => 'void',
proargtypes => 'internal', prosrc => 'network_sortsupport' },

# inet/cidr functions
{ oid => '598', descr => 'abbreviated display of inet value',
Expand Down
3 changes: 3 additions & 0 deletions src/include/utils/inet.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,7 @@ extern inet *cidr_set_masklen_internal(const inet *src, int bits);
extern int bitncmp(const unsigned char *l, const unsigned char *r, int n);
extern int bitncommon(const unsigned char *l, const unsigned char *r, int n);

/* exported so we can access it from `test/modules/test_inet` */
extern Datum network_abbrev_convert_var(const inet *original);

#endif /* INET_H */
1 change: 1 addition & 0 deletions src/test/modules/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ SUBDIRS = \
test_bloomfilter \
test_ddl_deparse \
test_extensions \
test_inet \
test_parser \
test_pg_dump \
test_predtest \
Expand Down
4 changes: 4 additions & 0 deletions src/test/modules/test_inet/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Generated subdirectories
/log/
/results/
/tmp_check/
21 changes: 21 additions & 0 deletions src/test/modules/test_inet/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# src/test/modules/test_inet/Makefile

MODULE_big = test_inet
OBJS = test_inet.o $(WIN32RES)
PGFILEDESC = "test_inet - test code for the inet type"

EXTENSION = test_inet
DATA = test_inet--1.0.sql

REGRESS = test_inet

ifdef USE_PGXS
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
else
subdir = src/test/modules/test_inet
top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/contrib/contrib-global.mk
endif
61 changes: 61 additions & 0 deletions src/test/modules/test_inet/expected/test_inet.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
CREATE EXTENSION test_inet;
--
-- These tests return a bit-level representation of the abbreviated key for the
-- given inet value. Because a lot of fairly tricky bit manipulation is done to
-- assemble these abbreviated keys, they're here to help give us confidence
-- that we got everything right.
--
SELECT *
FROM (VALUES
('0.0.0.0/0'::inet, '0', test_inet_abbrev_convert('0.0.0.0/0')),
-- with 1 in the least signification position, not enough subnet bits in
-- abbreviated key to store it, which is why the result comes out as 0
('0.0.0.1/0'::inet, '0', test_inet_abbrev_convert('0.0.0.1/0')),
('255.0.0.0/0'::inet, '1fe0000', test_inet_abbrev_convert('255.0.0.0/0')),
('255.255.255.255/0'::inet, '1ffffff', test_inet_abbrev_convert('255.255.255.255/0')),
('0.0.0.0/1'::inet, '2000000', test_inet_abbrev_convert('0.0.0.0/1')),
('0.0.0.0/32'::inet, '40000000', test_inet_abbrev_convert('0.0.0.0/32')),
('0.0.0.1/32'::inet, 'c0000000', test_inet_abbrev_convert('0.0.0.1/32')),
('255.255.255.255/1'::inet, '4000000003ffffff', test_inet_abbrev_convert('255.255.255.255/1')),
('255.255.255.255/16'::inet, '7fff80002000ffff', test_inet_abbrev_convert('255.255.255.255/16')),
-- note all netmask bits except the one most significant bit (reserved for
-- IP family) are 1s
('255.255.255.255/32'::inet, '7fffffffc0000000', test_inet_abbrev_convert('255.255.255.255/32')),
-- only the most significant bit is a 1
('::/0'::inet, '8000000000000000', test_inet_abbrev_convert('::/0')),
('::1/0'::inet, '8000000000000000', test_inet_abbrev_convert('::1/0')),
-- the boundary of bits in the netmask, all of which are are too
-- insignificant to fit into the abbreviated key
('::1:ffff:ffff:ffff:ffff/128'::inet, '8000000000000000', test_inet_abbrev_convert('::1:ffff:ffff:ffff:ffff/128')),
-- but add just one and we get a value in the abbreviated key
('::2:ffff:ffff:ffff:ffff/128'::inet, '8000000000000001', test_inet_abbrev_convert('::2:ffff:ffff:ffff:ffff/128')),
('ffff:ffff:ffff:fffd::/128'::inet, 'fffffffffffffffe', test_inet_abbrev_convert('ffff:ffff:ffff:fffd::/128')),
-- abbreviated key representation comes out as the maximum possible value;
-- to disambiguate between this and higher numbers, Postgres will have to
-- fall back to authoritative comparison
('ffff:ffff:ffff:fffe::/128'::inet, 'ffffffffffffffff', test_inet_abbrev_convert('ffff:ffff:ffff:fffe::/128')),
('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128'::inet, 'ffffffffffffffff', test_inet_abbrev_convert('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128'))
)
AS t (original, abbrev_expected, abbrev_actual)
ORDER BY original;
original | abbrev_expected | abbrev_actual
-----------------------------------------+------------------+------------------
0.0.0.0/0 | 0 | 0
0.0.0.1/0 | 0 | 0
255.0.0.0/0 | 1fe0000 | 1fe0000
255.255.255.255/0 | 1ffffff | 1ffffff
0.0.0.0/1 | 2000000 | 2000000
0.0.0.0 | 40000000 | 40000000
0.0.0.1 | c0000000 | c0000000
255.255.255.255/1 | 4000000003ffffff | 4000000003ffffff
255.255.255.255/16 | 7fff80002000ffff | 7fff80002000ffff
255.255.255.255 | 7fffffffc0000000 | 7fffffffc0000000
::/0 | 8000000000000000 | 8000000000000000
::1/0 | 8000000000000000 | 8000000000000000
::1:ffff:ffff:ffff:ffff | 8000000000000000 | 8000000000000000
::2:ffff:ffff:ffff:ffff | 8000000000000001 | 8000000000000001
ffff:ffff:ffff:fffd:: | fffffffffffffffe | fffffffffffffffe
ffff:ffff:ffff:fffe:: | ffffffffffffffff | ffffffffffffffff
ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff | ffffffffffffffff | ffffffffffffffff
(17 rows)

51 changes: 51 additions & 0 deletions src/test/modules/test_inet/sql/test_inet.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
CREATE EXTENSION test_inet;

--
-- These tests return a bit-level representation of the abbreviated key for the
-- given inet value. Because a lot of fairly tricky bit manipulation is done to
-- assemble these abbreviated keys, they're here to help give us confidence
-- that we got everything right.
--
SELECT *
FROM (VALUES
('0.0.0.0/0'::inet, '0', test_inet_abbrev_convert('0.0.0.0/0')),

-- with 1 in the least signification position, not enough subnet bits in
-- abbreviated key to store it, which is why the result comes out as 0
('0.0.0.1/0'::inet, '0', test_inet_abbrev_convert('0.0.0.1/0')),

('255.0.0.0/0'::inet, '1fe0000', test_inet_abbrev_convert('255.0.0.0/0')),
('255.255.255.255/0'::inet, '1ffffff', test_inet_abbrev_convert('255.255.255.255/0')),
('0.0.0.0/1'::inet, '2000000', test_inet_abbrev_convert('0.0.0.0/1')),
('0.0.0.0/32'::inet, '40000000', test_inet_abbrev_convert('0.0.0.0/32')),
('0.0.0.1/32'::inet, 'c0000000', test_inet_abbrev_convert('0.0.0.1/32')),
('255.255.255.255/1'::inet, '4000000003ffffff', test_inet_abbrev_convert('255.255.255.255/1')),
('255.255.255.255/16'::inet, '7fff80002000ffff', test_inet_abbrev_convert('255.255.255.255/16')),

-- note all netmask bits except the one most significant bit (reserved for
-- IP family) are 1s
('255.255.255.255/32'::inet, '7fffffffc0000000', test_inet_abbrev_convert('255.255.255.255/32')),

-- only the most significant bit is a 1
('::/0'::inet, '8000000000000000', test_inet_abbrev_convert('::/0')),

('::1/0'::inet, '8000000000000000', test_inet_abbrev_convert('::1/0')),

-- the boundary of bits in the netmask, all of which are are too
-- insignificant to fit into the abbreviated key
('::1:ffff:ffff:ffff:ffff/128'::inet, '8000000000000000', test_inet_abbrev_convert('::1:ffff:ffff:ffff:ffff/128')),

-- but add just one and we get a value in the abbreviated key
('::2:ffff:ffff:ffff:ffff/128'::inet, '8000000000000001', test_inet_abbrev_convert('::2:ffff:ffff:ffff:ffff/128')),

('ffff:ffff:ffff:fffd::/128'::inet, 'fffffffffffffffe', test_inet_abbrev_convert('ffff:ffff:ffff:fffd::/128')),

-- abbreviated key representation comes out as the maximum possible value;
-- to disambiguate between this and higher numbers, Postgres will have to
-- fall back to authoritative comparison
('ffff:ffff:ffff:fffe::/128'::inet, 'ffffffffffffffff', test_inet_abbrev_convert('ffff:ffff:ffff:fffe::/128')),

('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128'::inet, 'ffffffffffffffff', test_inet_abbrev_convert('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128'))
)
AS t (original, abbrev_expected, abbrev_actual)
ORDER BY original;
8 changes: 8 additions & 0 deletions src/test/modules/test_inet/test_inet--1.0.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* src/test/modules/test_inet/test_inet--1.0.sql */

-- complain if script is sourced in psql, rather than via CREATE EXTENSION
\echo Use "CREATE EXTENSION test_inet" to load this file. \quit

CREATE FUNCTION test_inet_abbrev_convert(original inet)
RETURNS cstring STRICT
AS 'MODULE_PATHNAME' LANGUAGE C;
28 changes: 28 additions & 0 deletions src/test/modules/test_inet/test_inet.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*--------------------------------------------------------------------------
*
* test_inet.c
* Test correctness of the inet/cidr data types.
*
* Copyright (c) 2009-2019, PostgreSQL Global Development Group
*
* IDENTIFICATION
* src/test/modules/test_inet/test_inet.c
*
* -------------------------------------------------------------------------
*/

#include "postgres.h"

#include "utils/inet.h"

PG_MODULE_MAGIC;

PG_FUNCTION_INFO_V1(test_inet_abbrev_convert);

Datum
test_inet_abbrev_convert(PG_FUNCTION_ARGS)
{
inet *src = PG_GETARG_INET_PP(0);
Datum res = network_abbrev_convert_var(src);
PG_RETURN_CSTRING(psprintf("%lx", res));
}
4 changes: 4 additions & 0 deletions src/test/modules/test_inet/test_inet.control
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
comment = 'Test code for the inet type'
default_version = '1.0'
module_pathname = '$libdir/test_inet'
relocatable = true
104 changes: 104 additions & 0 deletions src/test/regress/expected/inet.out
Original file line number Diff line number Diff line change
Expand Up @@ -790,3 +790,107 @@ SELECT inet_merge(c, i) FROM INET_TBL WHERE inet_same_family(c, i);
::/24
(17 rows)

-- tests to specifically check some of the potentially sharp edges when it
-- comes to SortSupport implementation
SELECT i FROM (VALUES
('0.0.0.0/0'::inet),
('0.0.0.1/0'::inet),
('192.168.1.4/0'::inet),
('192.168.1.5/0'::inet),
('255.0.0.0/0'::inet),
('255.255.255.255/0'::inet),
('0.0.0.0/1'::inet),
('0.0.0.0/32'::inet),
('0.0.0.1/1'::inet),
('255.255.255.255/0'::inet),
('255.255.255.255/1'::inet),
('192.168.1.3/1'::inet),
('192.168.1.1/5'::inet),
('192.168.1.255/5'::inet),
('192.168.1.1/6'::inet),
('192.168.1.255/6'::inet),
('192.168.1.1/23'::inet),
('192.168.1.2/23'::inet),
('192.168.1.3/23'::inet),
('192.168.1.0/24'::inet),
('192.168.1.0/25'::inet),
('255.255.255.255/16'::inet),
('255.255.255.255/31'::inet),
('255.255.255.254/32'::inet),
('255.255.255.255/32'::inet),
('0000:0000:0000:0000:0000:0000:0000:0000/0'::inet),
('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet),
('0000:0000:0000:0000:0000:0000:0000:0000/128'::inet),
('0000:0000:0000:0000:0000:0000:0000:0001/128'::inet),
('::1:ffff:ffff:ffff:ffff/128'::inet),
('::2:ffff:ffff:ffff:ffff/128'::inet),
('127::1'::inet),
('127::2'::inet),
('8000:0000:0000:0000:0000:0000:0000:0000/1'::inet),
('ffff:83e7:f118:57dc:6093:6d92:689d:58cf/70'::inet),
('ffff:84b0:4775:536e:c3ed:7116:a6d6:34f0/44'::inet),
('ffff:8566:f84:5867:47f1:7867:d2ba:8a1a/69'::inet),
('ffff:8883:f028:7d2:4d68:d510:7d6b:ac43/73'::inet),
('ffff:8ae8:7c14:65b3:196:8e4a:89ae:fb30/89'::inet),
('ffff:8dd0:646:694c:7c16:7e35:6a26:171/104'::inet),
('ffff:8eef:cbf:700:eda3:ae32:f4b4:318b/121'::inet),
('ffff:90e7:e744:664:a93:8efe:1f25:7663/122'::inet),
('ffff:9597:c69c:8b24:57a:8639:ec78:6026/111'::inet),
('ffff:9e86:79ea:f16e:df31:8e4d:7783:532e/88'::inet),
('ffff:a0c7:82d3:24de:f762:6e1f:316d:3fb2/23'::inet),
('ffff:ffff:ffff:fffd::/128'::inet),
('ffff:ffff:ffff:fffe::/128'::inet),
('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128'::inet)
) AS i ORDER BY i;
i
----------------------------------------------
(0.0.0.0/0)
(0.0.0.1/0)
(192.168.1.4/0)
(192.168.1.5/0)
(255.0.0.0/0)
(255.255.255.255/0)
(255.255.255.255/0)
(0.0.0.0/1)
(0.0.0.1/1)
(0.0.0.0)
(192.168.1.3/1)
(255.255.255.255/1)
(192.168.1.1/5)
(192.168.1.255/5)
(192.168.1.1/6)
(192.168.1.255/6)
(192.168.1.1/23)
(192.168.1.2/23)
(192.168.1.3/23)
(192.168.1.0/24)
(192.168.1.0/25)
(255.255.255.255/16)
(255.255.255.255/31)
(255.255.255.254)
(255.255.255.255)
(::/0)
(ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/0)
(::)
(::1)
(::1:ffff:ffff:ffff:ffff)
(::2:ffff:ffff:ffff:ffff)
(127::1)
(127::2)
(8000::/1)
(ffff:83e7:f118:57dc:6093:6d92:689d:58cf/70)
(ffff:84b0:4775:536e:c3ed:7116:a6d6:34f0/44)
(ffff:8566:f84:5867:47f1:7867:d2ba:8a1a/69)
(ffff:8883:f028:7d2:4d68:d510:7d6b:ac43/73)
(ffff:8ae8:7c14:65b3:196:8e4a:89ae:fb30/89)
(ffff:8dd0:646:694c:7c16:7e35:6a26:171/104)
(ffff:8eef:cbf:700:eda3:ae32:f4b4:318b/121)
(ffff:90e7:e744:664:a93:8efe:1f25:7663/122)
(ffff:9597:c69c:8b24:57a:8639:ec78:6026/111)
(ffff:9e86:79ea:f16e:df31:8e4d:7783:532e/88)
(ffff:a0c7:82d3:24de:f762:6e1f:316d:3fb2/23)
(ffff:ffff:ffff:fffd::)
(ffff:ffff:ffff:fffe::)
(ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff)
(48 rows)

53 changes: 53 additions & 0 deletions src/test/regress/sql/inet.sql
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,56 @@ INSERT INTO INET_TBL (c, i) VALUES ('10', '10::/8');
SELECT inet_merge(c, i) FROM INET_TBL;
-- fix it by inet_same_family() condition
SELECT inet_merge(c, i) FROM INET_TBL WHERE inet_same_family(c, i);

-- tests to specifically check some of the potentially sharp edges when it
-- comes to SortSupport implementation
SELECT i FROM (VALUES
('0.0.0.0/0'::inet),
('0.0.0.1/0'::inet),
('192.168.1.4/0'::inet),
('192.168.1.5/0'::inet),
('255.0.0.0/0'::inet),
('255.255.255.255/0'::inet),
('0.0.0.0/1'::inet),
('0.0.0.0/32'::inet),
('0.0.0.1/1'::inet),
('255.255.255.255/0'::inet),
('255.255.255.255/1'::inet),
('192.168.1.3/1'::inet),
('192.168.1.1/5'::inet),
('192.168.1.255/5'::inet),
('192.168.1.1/6'::inet),
('192.168.1.255/6'::inet),
('192.168.1.1/23'::inet),
('192.168.1.2/23'::inet),
('192.168.1.3/23'::inet),
('192.168.1.0/24'::inet),
('192.168.1.0/25'::inet),
('255.255.255.255/16'::inet),
('255.255.255.255/31'::inet),
('255.255.255.254/32'::inet),
('255.255.255.255/32'::inet),
('0000:0000:0000:0000:0000:0000:0000:0000/0'::inet),
('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/0'::inet),
('0000:0000:0000:0000:0000:0000:0000:0000/128'::inet),
('0000:0000:0000:0000:0000:0000:0000:0001/128'::inet),
('::1:ffff:ffff:ffff:ffff/128'::inet),
('::2:ffff:ffff:ffff:ffff/128'::inet),
('127::1'::inet),
('127::2'::inet),
('8000:0000:0000:0000:0000:0000:0000:0000/1'::inet),
('ffff:83e7:f118:57dc:6093:6d92:689d:58cf/70'::inet),
('ffff:84b0:4775:536e:c3ed:7116:a6d6:34f0/44'::inet),
('ffff:8566:f84:5867:47f1:7867:d2ba:8a1a/69'::inet),
('ffff:8883:f028:7d2:4d68:d510:7d6b:ac43/73'::inet),
('ffff:8ae8:7c14:65b3:196:8e4a:89ae:fb30/89'::inet),
('ffff:8dd0:646:694c:7c16:7e35:6a26:171/104'::inet),
('ffff:8eef:cbf:700:eda3:ae32:f4b4:318b/121'::inet),
('ffff:90e7:e744:664:a93:8efe:1f25:7663/122'::inet),
('ffff:9597:c69c:8b24:57a:8639:ec78:6026/111'::inet),
('ffff:9e86:79ea:f16e:df31:8e4d:7783:532e/88'::inet),
('ffff:a0c7:82d3:24de:f762:6e1f:316d:3fb2/23'::inet),
('ffff:ffff:ffff:fffd::/128'::inet),
('ffff:ffff:ffff:fffe::/128'::inet),
('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128'::inet)
) AS i ORDER BY i;