diff -Nru ip4r-2.4.1/debian/changelog ip4r-2.4.2/debian/changelog --- ip4r-2.4.1/debian/changelog 2022-10-20 13:44:36.000000000 +0000 +++ ip4r-2.4.2/debian/changelog 2023-07-29 17:57:36.000000000 +0000 @@ -1,3 +1,9 @@ +ip4r (2.4.2-1) unstable; urgency=medium + + * New upstream version 2.4.2. + + -- Christoph Berg Sat, 29 Jul 2023 19:57:36 +0200 + ip4r (2.4.1-8) unstable; urgency=medium * Upload for PostgreSQL 15. diff -Nru ip4r-2.4.1/expected/ip4r-softerr.out ip4r-2.4.2/expected/ip4r-softerr.out --- ip4r-2.4.1/expected/ip4r-softerr.out 1970-01-01 00:00:00.000000000 +0000 +++ ip4r-2.4.2/expected/ip4r-softerr.out 2023-07-29 17:52:21.000000000 +0000 @@ -0,0 +1,325 @@ +-- Tests for pg16+ +--valid and invalid ip4 +select v.i, v.t, pg_input_is_valid(v.t,'ip4') as valid, ierr.* + from (values (1, '1.2.3.4'), + (2, '0.0.0.0'), + (3, '255.255.255.255'), + -- invalid + (4, '1.2.3'), + (5, '0'), + (6, ' 1.2.3.4'), + (7, '1.2.3.4 '), + (8, '0.0.0.256'), + (9 , '0.0.256'), + (10, '0..255.0'), + (11, '+0.255.0.0'), + (12, '1.2.3.4-1.2.3.4')) v(i,t) + left join lateral (select * from pg_input_error_info(v.t,'ip4')) ierr + on true; + i | t | valid | message | detail | hint | sql_error_code +----+-----------------+-------+--------------------------------------+--------+------+---------------- + 1 | 1.2.3.4 | t | | | | + 2 | 0.0.0.0 | t | | | | + 3 | 255.255.255.255 | t | | | | + 4 | 1.2.3 | f | invalid IP4 value: '1.2.3' | | | 22023 + 5 | 0 | f | invalid IP4 value: '0' | | | 22023 + 6 | 1.2.3.4 | f | invalid IP4 value: ' 1.2.3.4' | | | 22023 + 7 | 1.2.3.4 | f | invalid IP4 value: '1.2.3.4 ' | | | 22023 + 8 | 0.0.0.256 | f | invalid IP4 value: '0.0.0.256' | | | 22023 + 9 | 0.0.256 | f | invalid IP4 value: '0.0.256' | | | 22023 + 10 | 0..255.0 | f | invalid IP4 value: '0..255.0' | | | 22023 + 11 | +0.255.0.0 | f | invalid IP4 value: '+0.255.0.0' | | | 22023 + 12 | 1.2.3.4-1.2.3.4 | f | invalid IP4 value: '1.2.3.4-1.2.3.4' | | | 22023 +(12 rows) + +--valid and invalid ip4r +select v.i, v.t, pg_input_is_valid(v.t,'ip4r') as valid, ierr.* + from (values (1, '1.2.3.4'), + (2, '255.255.255.255/32'), + (3, '128.0.0.0/1'), + (4, '0.0.0.0/0'), + (5, '1.2.3.4-5.6.7.8'), + (6, '5.6.7.8-1.2.3.4'), + -- invalid + (7, '1.2.3'), + (8, '255.255.255.255.255.255.255.255.255'), + (9, '255.255.255.255.255-255.255.255.255.255'), + (10, '255.255.255.255-1.2.3.4.5'), + (11, '0.0.0.1/31'), + (12, '128.0.0.0/0'), + (13, '0.0.0.0/33'), + (14, '0.0.0.0/3.0'), + (15, '0.0.0.0/+33') + ) v(i,t) + left join lateral (select * from pg_input_error_info(v.t,'ip4r')) ierr + on true; + i | t | valid | message | detail | hint | sql_error_code +----+-----------------------------------------+-------+---------------------------------------------------------------+--------+------+---------------- + 1 | 1.2.3.4 | t | | | | + 2 | 255.255.255.255/32 | t | | | | + 3 | 128.0.0.0/1 | t | | | | + 4 | 0.0.0.0/0 | t | | | | + 5 | 1.2.3.4-5.6.7.8 | t | | | | + 6 | 5.6.7.8-1.2.3.4 | t | | | | + 7 | 1.2.3 | f | invalid IP4R value: "1.2.3" | | | 22023 + 8 | 255.255.255.255.255.255.255.255.255 | f | invalid IP4R value: "255.255.255.255.255.255.255.255.255" | | | 22023 + 9 | 255.255.255.255.255-255.255.255.255.255 | f | invalid IP4R value: "255.255.255.255.255-255.255.255.255.255" | | | 22023 + 10 | 255.255.255.255-1.2.3.4.5 | f | invalid IP4R value: "255.255.255.255-1.2.3.4.5" | | | 22023 + 11 | 0.0.0.1/31 | f | invalid IP4R value: "0.0.0.1/31" | | | 22023 + 12 | 128.0.0.0/0 | f | invalid IP4R value: "128.0.0.0/0" | | | 22023 + 13 | 0.0.0.0/33 | f | invalid IP4R value: "0.0.0.0/33" | | | 22023 + 14 | 0.0.0.0/3.0 | f | invalid IP4R value: "0.0.0.0/3.0" | | | 22023 + 15 | 0.0.0.0/+33 | f | invalid IP4R value: "0.0.0.0/+33" | | | 22023 +(15 rows) + +--valid and invalid ip6 +select v.i, v.t, pg_input_is_valid(v.t,'ip6') as valid, ierr.* + from (values (1, '0000:0000:0000:0000:0000:0000:0000:0000'), + (2, '0000:0000:0000:0000:0000:0000:0000:0001'), + (3, '0:0:0:0:0:0:0:0'), + (4, '0:0:0:0:0:0:0:1'), + (5, '0:0:0:0:0:0:13.1.68.3'), + (6, '0:0:0:0:0:FFFF:129.144.52.38'), + (7, '0::0'), + (8, '1:2:3:4:5:6:1.2.3.4'), + -- invalid + (9, ''), + (10, '02001:0000:1234:0000:0000:C1C0:ABCD:0876'), + (11, '1.2.3.4:1111:2222:3333:4444::5555'), + (12, '123'), + (13, '12345::6:7:8'), + (14, '::1.2.256.4'), + (15, 'FF01::101::2'), + (16, 'FF02:0000:0000:0000:0000:0000:0000:0000:0001'), + (17, 'ldkfj') + ) v(i,t) + left join lateral (select * from pg_input_error_info(v.t,'ip6')) ierr + on true; + i | t | valid | message | detail | hint | sql_error_code +----+----------------------------------------------+-------+-------------------------------------------------------------------+--------+------+---------------- + 1 | 0000:0000:0000:0000:0000:0000:0000:0000 | t | | | | + 2 | 0000:0000:0000:0000:0000:0000:0000:0001 | t | | | | + 3 | 0:0:0:0:0:0:0:0 | t | | | | + 4 | 0:0:0:0:0:0:0:1 | t | | | | + 5 | 0:0:0:0:0:0:13.1.68.3 | t | | | | + 6 | 0:0:0:0:0:FFFF:129.144.52.38 | t | | | | + 7 | 0::0 | t | | | | + 8 | 1:2:3:4:5:6:1.2.3.4 | t | | | | + 9 | | f | invalid IP6 value: '' | | | 22023 + 10 | 02001:0000:1234:0000:0000:C1C0:ABCD:0876 | f | invalid IP6 value: '02001:0000:1234:0000:0000:C1C0:ABCD:0876' | | | 22023 + 11 | 1.2.3.4:1111:2222:3333:4444::5555 | f | invalid IP6 value: '1.2.3.4:1111:2222:3333:4444::5555' | | | 22023 + 12 | 123 | f | invalid IP6 value: '123' | | | 22023 + 13 | 12345::6:7:8 | f | invalid IP6 value: '12345::6:7:8' | | | 22023 + 14 | ::1.2.256.4 | f | invalid IP6 value: '::1.2.256.4' | | | 22023 + 15 | FF01::101::2 | f | invalid IP6 value: 'FF01::101::2' | | | 22023 + 16 | FF02:0000:0000:0000:0000:0000:0000:0000:0001 | f | invalid IP6 value: 'FF02:0000:0000:0000:0000:0000:0000:0000:0001' | | | 22023 + 17 | ldkfj | f | invalid IP6 value: 'ldkfj' | | | 22023 +(17 rows) + +--valid and invalid ip6r +select v.i, v.t, pg_input_is_valid(v.t,'ip6r') as valid, ierr.* + from (values (1, '::'), + (2, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), + (3, '1::2'), + (4, '::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), + (5, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff-::'), + (6, '1::2-3::4'), + (7, '3::4-3::4'), + (8, '3::4-1::2'), + -- invalid + (9, '::-::-::'), + (10, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff-ffff'), + (11, '::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), + (12, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff-::'), + (13, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128'), + (14, '0000:0000:0000:0000:0000:0000:0000:0001/127'), + (15, '0800:0000:0000:0000:0000:0000:0000:0000/4'), + (16, '8000:0000:0000:0000:0000:0000:0000:0000/0'), + (17, '::/129'), + (18, '::/255'), + (19, '::/256'), + (20, '::/+0'), + (21, '::/0-0'), + (22, '::-::/0') + ) v(i,t) + left join lateral (select * from pg_input_error_info(v.t,'ip6r')) ierr + on true; + i | t | valid | message | detail | hint | sql_error_code +----+--------------------------------------------------+-------+------------------------------------------------------------------------+--------+------+---------------- + 1 | :: | t | | | | + 2 | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff | t | | | | + 3 | 1::2 | t | | | | + 4 | ::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff | t | | | | + 5 | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff-:: | t | | | | + 6 | 1::2-3::4 | t | | | | + 7 | 3::4-3::4 | t | | | | + 8 | 3::4-1::2 | t | | | | + 9 | ::-::-:: | f | invalid IP6R value: "::-::-::" | | | 22023 + 10 | ffff:ffff:ffff:ffff:ffff:ffff:ffff-ffff | f | invalid IP6R value: "ffff:ffff:ffff:ffff:ffff:ffff:ffff-ffff" | | | 22023 + 11 | ::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff | f | invalid IP6R value: "::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" | | | 22023 + 12 | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff-:: | f | invalid IP6R value: "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff-::" | | | 22023 + 13 | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128 | f | invalid IP6R value: "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128" | | | 22023 + 14 | 0000:0000:0000:0000:0000:0000:0000:0001/127 | f | invalid IP6R value: "0000:0000:0000:0000:0000:0000:0000:0001/127" | | | 22023 + 15 | 0800:0000:0000:0000:0000:0000:0000:0000/4 | f | invalid IP6R value: "0800:0000:0000:0000:0000:0000:0000:0000/4" | | | 22023 + 16 | 8000:0000:0000:0000:0000:0000:0000:0000/0 | f | invalid IP6R value: "8000:0000:0000:0000:0000:0000:0000:0000/0" | | | 22023 + 17 | ::/129 | f | invalid IP6R value: "::/129" | | | 22023 + 18 | ::/255 | f | invalid IP6R value: "::/255" | | | 22023 + 19 | ::/256 | f | invalid IP6R value: "::/256" | | | 22023 + 20 | ::/+0 | f | invalid IP6R value: "::/+0" | | | 22023 + 21 | ::/0-0 | f | invalid IP6R value: "::/0-0" | | | 22023 + 22 | ::-::/0 | f | invalid IP6R value: "::-::/0" | | | 22023 +(22 rows) + +--valid and invalid ipaddress +select v.i, v.t, pg_input_is_valid(v.t,'ipaddress') as valid, ierr.* + from (values (1, '1.2.3.4'), + (2, '0.0.0.0'), + (3, '255.255.255.255'), + (4, '1::8'), + (5, '2001:0000:1234:0000:0000:C1C0:ABCD:0876'), + (6, '2001:0db8:0000:0000:0000:0000:1428:57ab'), + -- invalid + (7, '1.2.3'), + (8, '0'), + (9, ' 1.2.3.4'), + (10, '1.2.3.4 '), + (11, '0.0.0.256'), + (12, ''), + (13, '02001:0000:1234:0000:0000:C1C0:ABCD:0876'), + (14, '1.2.3.4:1111:2222:3333:4444::5555'), + (15, '::ffff:2.3.4'), + (16, '::ffff:257.1.2.3'), + (17, 'FF01::101::2'), + (18, 'FF02:0000:0000:0000:0000:0000:0000:0000:0001'), + (19, 'ldkfj') + ) v(i,t) + left join lateral (select * from pg_input_error_info(v.t,'ipaddress')) ierr + on true; + i | t | valid | message | detail | hint | sql_error_code +----+----------------------------------------------+-------+------------------------------------------------------------------+--------+------+---------------- + 1 | 1.2.3.4 | t | | | | + 2 | 0.0.0.0 | t | | | | + 3 | 255.255.255.255 | t | | | | + 4 | 1::8 | t | | | | + 5 | 2001:0000:1234:0000:0000:C1C0:ABCD:0876 | t | | | | + 6 | 2001:0db8:0000:0000:0000:0000:1428:57ab | t | | | | + 7 | 1.2.3 | f | invalid IP value: '1.2.3' | | | 22023 + 8 | 0 | f | invalid IP value: '0' | | | 22023 + 9 | 1.2.3.4 | f | invalid IP value: ' 1.2.3.4' | | | 22023 + 10 | 1.2.3.4 | f | invalid IP value: '1.2.3.4 ' | | | 22023 + 11 | 0.0.0.256 | f | invalid IP value: '0.0.0.256' | | | 22023 + 12 | | f | invalid IP value: '' | | | 22023 + 13 | 02001:0000:1234:0000:0000:C1C0:ABCD:0876 | f | invalid IP value: '02001:0000:1234:0000:0000:C1C0:ABCD:0876' | | | 22023 + 14 | 1.2.3.4:1111:2222:3333:4444::5555 | f | invalid IP value: '1.2.3.4:1111:2222:3333:4444::5555' | | | 22023 + 15 | ::ffff:2.3.4 | f | invalid IP value: '::ffff:2.3.4' | | | 22023 + 16 | ::ffff:257.1.2.3 | f | invalid IP value: '::ffff:257.1.2.3' | | | 22023 + 17 | FF01::101::2 | f | invalid IP value: 'FF01::101::2' | | | 22023 + 18 | FF02:0000:0000:0000:0000:0000:0000:0000:0001 | f | invalid IP value: 'FF02:0000:0000:0000:0000:0000:0000:0000:0001' | | | 22023 + 19 | ldkfj | f | invalid IP value: 'ldkfj' | | | 22023 +(19 rows) + +--valid and invalid iprange +select v.i, v.t, pg_input_is_valid(v.t,'iprange') as valid, ierr.* + from (values (1, '-'), + (2, '1.2.3.4'), + (3, '255.255.255.255/32'), + (4, '128.0.0.0/1'), + (5, '0.0.0.0/0'), + (6, '1.2.3.4-5.6.7.8'), + (7, '5.6.7.8-1.2.3.4'), + (8, '1.2.3.4-1.2.3.4'), + (9, '::'), + (10, '1::2'), + (11, '::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), + (12, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff-::'), + (13, '1::2-3::4'), + (14, '3::4-3::4'), + (15, '3::4-1::2'), + (16, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128'), + (17, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe/127'), + (18, '8000:0000:0000:0000:0000:0000:0000:0000/1'), + (19, '0000:0000:0000:0000:0000:0000:0000:0000/0'), + -- invalid + (20, '1.2.3'), + (21, '255.255.255.255.255.255.255.255.255'), + (22, '255.255.255.255.255-255.255.255.255.255'), + (23, '255.255.255.255-1.2.3.4.5'), + (24, '255.255.255.255-1.2.3'), + (25, '0.0.0.1/31'), + (26, '64.0.0.0/1'), + (27, '128.0.0.0/0'), + (28, '0.0.0.0/33'), + (29, '0.0.0.0/3.0'), + (30, '0.0.0.0/+33'), + (31, '::-::-::'), + (32, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff-ffff'), + (33, '::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), + (34, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff-::'), + (35, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128'), + (36, '0000:0000:0000:0000:0000:0000:0000:0001/127'), + (37, '0800:0000:0000:0000:0000:0000:0000:0000/4'), + (38, '8000:0000:0000:0000:0000:0000:0000:0000/0'), + (39, '::/129'), + (40, '::/255'), + (41, '::/256'), + (42, '::/+0'), + (43, '::/0-0'), + (44, '::-::/0'), + (45, '-::'), + (46, '-1.2.3.4'), + (47, '1.2.3.4-') + ) v(i,t) + left join lateral (select * from pg_input_error_info(v.t,'iprange')) ierr + on true; + i | t | valid | message | detail | hint | sql_error_code +----+--------------------------------------------------+-------+------------------------------------------------------------------------+--------+------+---------------- + 1 | - | t | | | | + 2 | 1.2.3.4 | t | | | | + 3 | 255.255.255.255/32 | t | | | | + 4 | 128.0.0.0/1 | t | | | | + 5 | 0.0.0.0/0 | t | | | | + 6 | 1.2.3.4-5.6.7.8 | t | | | | + 7 | 5.6.7.8-1.2.3.4 | t | | | | + 8 | 1.2.3.4-1.2.3.4 | t | | | | + 9 | :: | t | | | | + 10 | 1::2 | t | | | | + 11 | ::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff | t | | | | + 12 | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff-:: | t | | | | + 13 | 1::2-3::4 | t | | | | + 14 | 3::4-3::4 | t | | | | + 15 | 3::4-1::2 | t | | | | + 16 | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128 | t | | | | + 17 | ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe/127 | t | | | | + 18 | 8000:0000:0000:0000:0000:0000:0000:0000/1 | t | | | | + 19 | 0000:0000:0000:0000:0000:0000:0000:0000/0 | t | | | | + 20 | 1.2.3 | f | invalid IP4R value: "1.2.3" | | | 22023 + 21 | 255.255.255.255.255.255.255.255.255 | f | invalid IP4R value: "255.255.255.255.255.255.255.255.255" | | | 22023 + 22 | 255.255.255.255.255-255.255.255.255.255 | f | invalid IP4R value: "255.255.255.255.255-255.255.255.255.255" | | | 22023 + 23 | 255.255.255.255-1.2.3.4.5 | f | invalid IP4R value: "255.255.255.255-1.2.3.4.5" | | | 22023 + 24 | 255.255.255.255-1.2.3 | f | invalid IP4R value: "255.255.255.255-1.2.3" | | | 22023 + 25 | 0.0.0.1/31 | f | invalid IP4R value: "0.0.0.1/31" | | | 22023 + 26 | 64.0.0.0/1 | f | invalid IP4R value: "64.0.0.0/1" | | | 22023 + 27 | 128.0.0.0/0 | f | invalid IP4R value: "128.0.0.0/0" | | | 22023 + 28 | 0.0.0.0/33 | f | invalid IP4R value: "0.0.0.0/33" | | | 22023 + 29 | 0.0.0.0/3.0 | f | invalid IP4R value: "0.0.0.0/3.0" | | | 22023 + 30 | 0.0.0.0/+33 | f | invalid IP4R value: "0.0.0.0/+33" | | | 22023 + 31 | ::-::-:: | f | invalid IP6R value: "::-::-::" | | | 22023 + 32 | ffff:ffff:ffff:ffff:ffff:ffff:ffff-ffff | f | invalid IP6R value: "ffff:ffff:ffff:ffff:ffff:ffff:ffff-ffff" | | | 22023 + 33 | ::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff | f | invalid IP6R value: "::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" | | | 22023 + 34 | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff-:: | f | invalid IP6R value: "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff-::" | | | 22023 + 35 | ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128 | f | invalid IP6R value: "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128" | | | 22023 + 36 | 0000:0000:0000:0000:0000:0000:0000:0001/127 | f | invalid IP6R value: "0000:0000:0000:0000:0000:0000:0000:0001/127" | | | 22023 + 37 | 0800:0000:0000:0000:0000:0000:0000:0000/4 | f | invalid IP6R value: "0800:0000:0000:0000:0000:0000:0000:0000/4" | | | 22023 + 38 | 8000:0000:0000:0000:0000:0000:0000:0000/0 | f | invalid IP6R value: "8000:0000:0000:0000:0000:0000:0000:0000/0" | | | 22023 + 39 | ::/129 | f | invalid IP6R value: "::/129" | | | 22023 + 40 | ::/255 | f | invalid IP6R value: "::/255" | | | 22023 + 41 | ::/256 | f | invalid IP6R value: "::/256" | | | 22023 + 42 | ::/+0 | f | invalid IP6R value: "::/+0" | | | 22023 + 43 | ::/0-0 | f | invalid IP6R value: "::/0-0" | | | 22023 + 44 | ::-::/0 | f | invalid IP6R value: "::-::/0" | | | 22023 + 45 | -:: | f | invalid IP6R value: "-::" | | | 22023 + 46 | -1.2.3.4 | f | invalid IP4R value: "-1.2.3.4" | | | 22023 + 47 | 1.2.3.4- | f | invalid IP4R value: "1.2.3.4-" | | | 22023 +(47 rows) + +-- end diff -Nru ip4r-2.4.1/.github/workflows/regression.yml ip4r-2.4.2/.github/workflows/regression.yml --- ip4r-2.4.1/.github/workflows/regression.yml 1970-01-01 00:00:00.000000000 +0000 +++ ip4r-2.4.2/.github/workflows/regression.yml 2023-07-29 17:52:21.000000000 +0000 @@ -0,0 +1,59 @@ +name: Build + +on: + push: + branches: [ master ] + tags: [ REL_* ] + pull_request: + branches: [ master ] + +jobs: + build: + runs-on: ubuntu-latest + + defaults: + run: + shell: sh + + strategy: + matrix: + pgver: [ 9.5, 9.6, 10, 11, 12, 13, 14, 15 ] + include: + - pgrepo: "" + - pgver: 16 + pgrepo: "-pgdg-snapshot" + + env: + PG: ${{ matrix.pgver }} + PGREPO: ${{ matrix.pgrepo }} + + steps: + - name: checkout + uses: actions/checkout@v3 + + - name: cleanup pg + run: | + sudo apt-get -y --purge --no-upgrade remove postgresql libpq-dev libpq5 postgresql-client-common postgresql-common + curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - + sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" >/etc/apt/sources.list.d/pgdg.list' + sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg-snapshot main 16" >/etc/apt/sources.list.d/pgdg-snap.list' + sudo apt-get update -qq + sudo rm -rf /var/lib/postgresql + + - name: install pg + run: | + sudo apt-get -y \ + -o Dpkg::Options::=--force-confdef \ + -o Dpkg::Options::=--force-confnew \ + ${PGREPO:+-t "$(lsb_release -cs)$PGREPO"} \ + install postgresql-${PG:?} postgresql-server-dev-${PG:?} + sudo -u postgres createuser -s "$USER" + + - name: build and test + run: | + make && sudo -E make install && time make installcheck + + - name: show output + if: always() + run: | + cat regression.diffs || true diff -Nru ip4r-2.4.1/.github/workflows/regr_macos.yml ip4r-2.4.2/.github/workflows/regr_macos.yml --- ip4r-2.4.1/.github/workflows/regr_macos.yml 1970-01-01 00:00:00.000000000 +0000 +++ ip4r-2.4.2/.github/workflows/regr_macos.yml 2023-07-29 17:52:21.000000000 +0000 @@ -0,0 +1,42 @@ +name: Build on MacOS + +on: + push: + branches: [ master ] + tags: [ REL_* ] + pull_request: + branches: [ master ] + +jobs: + build: + runs-on: macos-latest + + defaults: + run: + shell: sh + + steps: + - name: checkout + uses: actions/checkout@v3 + + - name: start pg + run: | + brew services start postgresql + + - name: build + run: | + make && sudo -E make install + + - name: wait for pg + run: | + n=0 + while ! pg_isready; do [ $(( n += 1 )) -gt 10 ] && exit 1; sleep $n; done + + - name: test + run: | + time make installcheck + + - name: show output + if: always() + run: | + cat regression.diffs || true diff -Nru ip4r-2.4.1/.gitignore ip4r-2.4.2/.gitignore --- ip4r-2.4.1/.gitignore 2019-05-22 02:04:18.000000000 +0000 +++ ip4r-2.4.2/.gitignore 2023-07-29 17:52:21.000000000 +0000 @@ -9,6 +9,7 @@ *.dll *.a *.mo +*.bc objfiles.txt .deps/ *.gcno diff -Nru ip4r-2.4.1/LICENSE ip4r-2.4.2/LICENSE --- ip4r-2.4.1/LICENSE 1970-01-01 00:00:00.000000000 +0000 +++ ip4r-2.4.2/LICENSE 2023-07-29 17:52:21.000000000 +0000 @@ -0,0 +1,22 @@ +PostgreSQL License + +Copyright (c) 2004-2019, Andrew Gierth +Copyright (c) 2003, Steve Atkins +Copyright (c) 2000-2003, PostgreSQL Global Development Group + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose, without fee, and without a written agreement is +hereby granted, provided that the above copyright notice and this paragraph +and the following two paragraphs appear in all copies. + +IN NO EVENT SHALL THE AUTHORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, +SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING +OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHORS +HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +THE AUTHORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, +AND THE AUTHORS HAVE NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, +ENHANCEMENTS, OR MODIFICATIONS. + diff -Nru ip4r-2.4.1/Makefile ip4r-2.4.2/Makefile --- ip4r-2.4.1/Makefile 2019-05-22 02:04:18.000000000 +0000 +++ ip4r-2.4.2/Makefile 2023-07-29 17:52:21.000000000 +0000 @@ -1,24 +1,18 @@ +EXTENSION= ip4r + MODULE_big = ip4r -ifndef NO_EXTENSION -EXTENSION= ip4r SRC_SQL = ip4r--2.4.sql \ ip4r--2.2--2.4.sql \ ip4r--2.1--2.2.sql \ ip4r--2.0--2.1.sql \ - ip4r--unpackaged2.1--2.1.sql \ + $(if $(call version_ge,$(MAJORVERSION),13),,$(SRC_OLD)) +# "FROM unpackaged" was removed in pg13 +SRC_OLD = ip4r--unpackaged2.1--2.1.sql \ ip4r--unpackaged2.0--2.0.sql \ ip4r--unpackaged1--2.0.sql DATA = $(addprefix scripts/, $(SRC_SQL)) -REGRESS = ip4r $(REGRESS_$(MAJORVERSION)) -REGRESS_11 := ip4r-v11 -REGRESS_12 := $(REGRESS_11) -else -DATA_built = ip4r.sql -EXTRA_CLEAN += ip4r.sql.in sql/ip4r-legacy.sql expected/ip4r-legacy.out -REGRESS = ip4r-legacy -endif objdir = src @@ -29,6 +23,18 @@ HEADERS = src/ipr.h +REGRESS = ip4r \ + $(REGRESS_BY_VERSION) +REGRESS_V11 := ip4r-v11 +REGRESS_V16 := ip4r-softerr + +define REGRESS_BY_VERSION +$(strip + $(foreach v,$(filter REGRESS_V%,$(.VARIABLES)), + $(if $(call version_ge,$(MAJORVERSION),$(subst REGRESS_V,,$(v))), + $($(v))))) +endef + # if VPATH is not already set, but the makefile is not in the current # dir, then assume a vpath build using the makefile's directory as # source. PGXS will set $(srcdir) accordingly. @@ -38,18 +44,14 @@ endif endif -ifndef NO_PGXS +mklibdir := $(if $(VPATH),$(VPATH)/tools,tools) +include $(mklibdir)/numeric.mk + PG_CONFIG ?= pg_config PGXS = $(shell $(PG_CONFIG) --pgxs) include $(PGXS) -else -subdir = contrib/ip4r -top_builddir = ../.. -include $(top_builddir)/src/Makefile.global -include $(top_srcdir)/contrib/contrib-global.mk -endif -ifeq ($(filter-out 7.% 8.0 8.1 8.2 8.3, $(MAJORVERSION)),) +ifeq ($(call version_ge,$(MAJORVERSION),9.1),) $(error unsupported PostgreSQL version) endif @@ -66,39 +68,5 @@ $(MKDIR_P) $(objdir) endif # VPATH -ifndef EXTENSION - -ifeq ($(filter-out 8.4, $(MAJORVERSION)),) - -ip4r.sql.in: $(srcdir)/scripts/ip4r--2.4.sql $(srcdir)/tools/legacy.sed - sed -f $(srcdir)/tools/legacy.sed $< | sed -e '/^DO /,/^[$$]/d' >$@ - -else - -ip4r.sql.in: $(srcdir)/scripts/ip4r--2.4.sql $(srcdir)/tools/legacy.sed - sed -f $(srcdir)/tools/legacy.sed $< >$@ - -endif - -# regression test doesn't like the idea of having to build files in -# the sql/ subdir, and looks for that only in $(srcdir). So disable -# legacy regression tests in vpath build. -ifndef VPATH -sql/ip4r-legacy.sql: sql/ip4r.sql tools/legacy-r.sed - sed -f tools/legacy-r.sed $< >$@ - -expected/ip4r-legacy.out: expected/ip4r.out tools/legacy-r.sed - sed -f tools/legacy-r.sed $< | sed -e '/^\\i /,+1d' >$@ - -installcheck: sql/ip4r-legacy.sql expected/ip4r-legacy.out -else -installcheck: - @echo regression tests are disabled in legacy vpath build -endif # VPATH - -else -ifeq ($(filter-out 8.% 9.0, $(MAJORVERSION)),) -$(error extension build not supported in versions before 9.1, use NO_EXTENSION=1) -endif -endif +# end diff -Nru ip4r-2.4.1/README.ip4r ip4r-2.4.2/README.ip4r --- ip4r-2.4.1/README.ip4r 2019-05-22 02:04:18.000000000 +0000 +++ ip4r-2.4.2/README.ip4r 2023-07-29 17:52:21.000000000 +0000 @@ -2,6 +2,18 @@ IP4R - IPv4/v6 and IPv4/v6 range index type for PostgreSQL =========================================================== +CHANGES in version 2.4.2: +========================= + + * Support pg 16, including soft-error handling for input. + + * Check for lower < upper in binary format input and correct + if necessary. + + * Remove support for some long-obsolete PG versions + + * Remove support for old-style (pre-extension) building. + CHANGES in version 2.4.1: ========================= @@ -523,6 +535,24 @@ ORDER BY ips.ip, @ ranges.range +Choosing an index method +------------------------ + +As with any data type, the choice of what index method to use (in this +case, btree vs. GiST) is generally dictated by what comparison +operators you want to use on the data. So a condition of the form +WHERE clientip = $1 or WHERE clientip BETWEEN lower($1) AND upper($1) +would make use of a btree index, whereas a for a condition like +WHERE range >>= $1 then a GiST index would be indicated. + +GiST indexes are defined by this module only for ranges of addresses +(ip4r, ip6r, iprange), so you would almost always use btree indexes +for columns storing a single address. The sole exception to this would +be if you need a multicolumn GiST index that combines an ip address +with columns of other GiST-indexable types (such as PostGIS geometry), +in which case it may make sense to cast the address to a range +containing only the single address. + AUTHORS ======= diff -Nru ip4r-2.4.1/sql/ip4r-softerr.sql ip4r-2.4.2/sql/ip4r-softerr.sql --- ip4r-2.4.1/sql/ip4r-softerr.sql 1970-01-01 00:00:00.000000000 +0000 +++ ip4r-2.4.2/sql/ip4r-softerr.sql 2023-07-29 17:52:21.000000000 +0000 @@ -0,0 +1,180 @@ +-- Tests for pg16+ + +--valid and invalid ip4 +select v.i, v.t, pg_input_is_valid(v.t,'ip4') as valid, ierr.* + from (values (1, '1.2.3.4'), + (2, '0.0.0.0'), + (3, '255.255.255.255'), + -- invalid + (4, '1.2.3'), + (5, '0'), + (6, ' 1.2.3.4'), + (7, '1.2.3.4 '), + (8, '0.0.0.256'), + (9 , '0.0.256'), + (10, '0..255.0'), + (11, '+0.255.0.0'), + (12, '1.2.3.4-1.2.3.4')) v(i,t) + left join lateral (select * from pg_input_error_info(v.t,'ip4')) ierr + on true; + +--valid and invalid ip4r +select v.i, v.t, pg_input_is_valid(v.t,'ip4r') as valid, ierr.* + from (values (1, '1.2.3.4'), + (2, '255.255.255.255/32'), + (3, '128.0.0.0/1'), + (4, '0.0.0.0/0'), + (5, '1.2.3.4-5.6.7.8'), + (6, '5.6.7.8-1.2.3.4'), + -- invalid + (7, '1.2.3'), + (8, '255.255.255.255.255.255.255.255.255'), + (9, '255.255.255.255.255-255.255.255.255.255'), + (10, '255.255.255.255-1.2.3.4.5'), + (11, '0.0.0.1/31'), + (12, '128.0.0.0/0'), + (13, '0.0.0.0/33'), + (14, '0.0.0.0/3.0'), + (15, '0.0.0.0/+33') + ) v(i,t) + left join lateral (select * from pg_input_error_info(v.t,'ip4r')) ierr + on true; + +--valid and invalid ip6 + +select v.i, v.t, pg_input_is_valid(v.t,'ip6') as valid, ierr.* + from (values (1, '0000:0000:0000:0000:0000:0000:0000:0000'), + (2, '0000:0000:0000:0000:0000:0000:0000:0001'), + (3, '0:0:0:0:0:0:0:0'), + (4, '0:0:0:0:0:0:0:1'), + (5, '0:0:0:0:0:0:13.1.68.3'), + (6, '0:0:0:0:0:FFFF:129.144.52.38'), + (7, '0::0'), + (8, '1:2:3:4:5:6:1.2.3.4'), + -- invalid + (9, ''), + (10, '02001:0000:1234:0000:0000:C1C0:ABCD:0876'), + (11, '1.2.3.4:1111:2222:3333:4444::5555'), + (12, '123'), + (13, '12345::6:7:8'), + (14, '::1.2.256.4'), + (15, 'FF01::101::2'), + (16, 'FF02:0000:0000:0000:0000:0000:0000:0000:0001'), + (17, 'ldkfj') + ) v(i,t) + left join lateral (select * from pg_input_error_info(v.t,'ip6')) ierr + on true; + +--valid and invalid ip6r + +select v.i, v.t, pg_input_is_valid(v.t,'ip6r') as valid, ierr.* + from (values (1, '::'), + (2, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), + (3, '1::2'), + (4, '::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), + (5, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff-::'), + (6, '1::2-3::4'), + (7, '3::4-3::4'), + (8, '3::4-1::2'), + -- invalid + (9, '::-::-::'), + (10, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff-ffff'), + (11, '::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), + (12, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff-::'), + (13, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128'), + (14, '0000:0000:0000:0000:0000:0000:0000:0001/127'), + (15, '0800:0000:0000:0000:0000:0000:0000:0000/4'), + (16, '8000:0000:0000:0000:0000:0000:0000:0000/0'), + (17, '::/129'), + (18, '::/255'), + (19, '::/256'), + (20, '::/+0'), + (21, '::/0-0'), + (22, '::-::/0') + ) v(i,t) + left join lateral (select * from pg_input_error_info(v.t,'ip6r')) ierr + on true; + +--valid and invalid ipaddress + +select v.i, v.t, pg_input_is_valid(v.t,'ipaddress') as valid, ierr.* + from (values (1, '1.2.3.4'), + (2, '0.0.0.0'), + (3, '255.255.255.255'), + (4, '1::8'), + (5, '2001:0000:1234:0000:0000:C1C0:ABCD:0876'), + (6, '2001:0db8:0000:0000:0000:0000:1428:57ab'), + -- invalid + (7, '1.2.3'), + (8, '0'), + (9, ' 1.2.3.4'), + (10, '1.2.3.4 '), + (11, '0.0.0.256'), + (12, ''), + (13, '02001:0000:1234:0000:0000:C1C0:ABCD:0876'), + (14, '1.2.3.4:1111:2222:3333:4444::5555'), + (15, '::ffff:2.3.4'), + (16, '::ffff:257.1.2.3'), + (17, 'FF01::101::2'), + (18, 'FF02:0000:0000:0000:0000:0000:0000:0000:0001'), + (19, 'ldkfj') + ) v(i,t) + left join lateral (select * from pg_input_error_info(v.t,'ipaddress')) ierr + on true; + +--valid and invalid iprange + +select v.i, v.t, pg_input_is_valid(v.t,'iprange') as valid, ierr.* + from (values (1, '-'), + (2, '1.2.3.4'), + (3, '255.255.255.255/32'), + (4, '128.0.0.0/1'), + (5, '0.0.0.0/0'), + (6, '1.2.3.4-5.6.7.8'), + (7, '5.6.7.8-1.2.3.4'), + (8, '1.2.3.4-1.2.3.4'), + (9, '::'), + (10, '1::2'), + (11, '::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), + (12, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff-::'), + (13, '1::2-3::4'), + (14, '3::4-3::4'), + (15, '3::4-1::2'), + (16, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128'), + (17, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe/127'), + (18, '8000:0000:0000:0000:0000:0000:0000:0000/1'), + (19, '0000:0000:0000:0000:0000:0000:0000:0000/0'), + -- invalid + (20, '1.2.3'), + (21, '255.255.255.255.255.255.255.255.255'), + (22, '255.255.255.255.255-255.255.255.255.255'), + (23, '255.255.255.255-1.2.3.4.5'), + (24, '255.255.255.255-1.2.3'), + (25, '0.0.0.1/31'), + (26, '64.0.0.0/1'), + (27, '128.0.0.0/0'), + (28, '0.0.0.0/33'), + (29, '0.0.0.0/3.0'), + (30, '0.0.0.0/+33'), + (31, '::-::-::'), + (32, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff-ffff'), + (33, '::-ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), + (34, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff-::'), + (35, 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128'), + (36, '0000:0000:0000:0000:0000:0000:0000:0001/127'), + (37, '0800:0000:0000:0000:0000:0000:0000:0000/4'), + (38, '8000:0000:0000:0000:0000:0000:0000:0000/0'), + (39, '::/129'), + (40, '::/255'), + (41, '::/256'), + (42, '::/+0'), + (43, '::/0-0'), + (44, '::-::/0'), + (45, '-::'), + (46, '-1.2.3.4'), + (47, '1.2.3.4-') + ) v(i,t) + left join lateral (select * from pg_input_error_info(v.t,'iprange')) ierr + on true; + +-- end diff -Nru ip4r-2.4.1/src/ip4r.c ip4r-2.4.2/src/ip4r.c --- ip4r-2.4.1/src/ip4r.c 2019-05-22 02:04:18.000000000 +0000 +++ ip4r-2.4.2/src/ip4r.c 2023-07-29 17:52:21.000000000 +0000 @@ -27,66 +27,66 @@ static bool ip4r_from_str(char *str, IP4R *ipr) { - char buf[IP4_STRING_MAX]; - int pos = strcspn(str, "-/"); - IP4 ip; - - switch (str[pos]) - { - case 0: /* no separator, must be single ip4 addr */ - { - if (!ip4_raw_input(str, &ip)) - return false; - ipr->lower = ip; - ipr->upper = ip; - return true; - } - - case '-': /* lower-upper */ - { - char *rest = str + pos + 1; - - if (pos >= sizeof(buf)) - return false; - memcpy(buf, str, pos); - buf[pos] = 0; - if (!ip4_raw_input(buf, &ip)) - return false; - ipr->lower = ip; - if (!ip4_raw_input(rest, &ip)) - return false; - if (!ip4_lessthan(ip, ipr->lower)) - ipr->upper = ip; - else - { - ipr->upper = ipr->lower; - ipr->lower = ip; - } - return true; - } - - case '/': /* prefix/len */ - { - char *rest = str + pos + 1; - unsigned pfxlen; - char dummy; - - if (pos >= sizeof(buf)) - return false; - memcpy(buf, str, pos); - buf[pos] = 0; - if (!ip4_raw_input(buf, &ip)) - return false; - if (rest[strspn(rest,"0123456789")]) - return false; - if (sscanf(rest, "%u%c", &pfxlen, &dummy) != 1) - return false; - return ip4r_from_cidr(ip, pfxlen, ipr); - } - - default: - return false; /* can't happen */ - } + char buf[IP4_STRING_MAX]; + int pos = strcspn(str, "-/"); + IP4 ip; + + switch (str[pos]) + { + case 0: /* no separator, must be single ip4 addr */ + { + if (!ip4_raw_input(str, &ip)) + return false; + ipr->lower = ip; + ipr->upper = ip; + return true; + } + + case '-': /* lower-upper */ + { + char *rest = str + pos + 1; + + if (pos >= sizeof(buf)) + return false; + memcpy(buf, str, pos); + buf[pos] = 0; + if (!ip4_raw_input(buf, &ip)) + return false; + ipr->lower = ip; + if (!ip4_raw_input(rest, &ip)) + return false; + if (!ip4_lessthan(ip, ipr->lower)) + ipr->upper = ip; + else + { + ipr->upper = ipr->lower; + ipr->lower = ip; + } + return true; + } + + case '/': /* prefix/len */ + { + char *rest = str + pos + 1; + unsigned pfxlen; + char dummy; + + if (pos >= sizeof(buf)) + return false; + memcpy(buf, str, pos); + buf[pos] = 0; + if (!ip4_raw_input(buf, &ip)) + return false; + if (rest[strspn(rest,"0123456789")]) + return false; + if (sscanf(rest, "%u%c", &pfxlen, &dummy) != 1) + return false; + return ip4r_from_cidr(ip, pfxlen, ipr); + } + + default: + return false; /* can't happen */ + } } @@ -95,23 +95,23 @@ static inline int ip4r_to_str(IP4R *ipr, char *str, int slen) { - char buf1[IP4_STRING_MAX]; - char buf2[IP4_STRING_MAX]; - unsigned msk; - - if (ip4_equal(ipr->lower, ipr->upper)) - return ip4_raw_output(ipr->lower, str, slen); - - if ((msk = masklen(ipr->lower,ipr->upper)) <= 32) - { - ip4_raw_output(ipr->lower, buf1, sizeof(buf1)); - return snprintf(str, slen, "%s/%u", buf1, msk); - } + char buf1[IP4_STRING_MAX]; + char buf2[IP4_STRING_MAX]; + unsigned msk; + + if (ip4_equal(ipr->lower, ipr->upper)) + return ip4_raw_output(ipr->lower, str, slen); + + if ((msk = masklen(ipr->lower,ipr->upper)) <= 32) + { + ip4_raw_output(ipr->lower, buf1, sizeof(buf1)); + return snprintf(str, slen, "%s/%u", buf1, msk); + } - ip4_raw_output(ipr->lower, buf1, sizeof(buf1)); - ip4_raw_output(ipr->upper, buf2, sizeof(buf2)); + ip4_raw_output(ipr->lower, buf1, sizeof(buf1)); + ip4_raw_output(ipr->upper, buf2, sizeof(buf2)); - return snprintf(str, slen, "%s-%s", buf1, buf2); + return snprintf(str, slen, "%s-%s", buf1, buf2); } @@ -123,9 +123,9 @@ text * make_text(int len) { - text *ret = (text *) palloc0(len + VARHDRSZ); - SET_VARSIZE(ret, len + VARHDRSZ); - return ret; + text *ret = (text *) palloc0(len + VARHDRSZ); + SET_VARSIZE(ret, len + VARHDRSZ); + return ret; } static inline @@ -145,157 +145,154 @@ Datum ip4_in(PG_FUNCTION_ARGS) { - char *str = PG_GETARG_CSTRING(0); - IP4 ip; - if (ip4_raw_input(str, &ip)) - PG_RETURN_IP4(ip); - - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid IP4 value: '%s'", str))); - PG_RETURN_NULL(); + char *str = PG_GETARG_CSTRING(0); + IP4 ip; + if (ip4_raw_input(str, &ip)) + PG_RETURN_IP4(ip); + + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid IP4 value: '%s'", str))); } PG_FUNCTION_INFO_V1(ip4_out); Datum ip4_out(PG_FUNCTION_ARGS) { - IP4 ip = PG_GETARG_IP4(0); - char *out = palloc(IP4_STRING_MAX); - ip4_raw_output(ip, out, IP4_STRING_MAX); - PG_RETURN_CSTRING(out); + IP4 ip = PG_GETARG_IP4(0); + char *out = palloc(IP4_STRING_MAX); + ip4_raw_output(ip, out, IP4_STRING_MAX); + PG_RETURN_CSTRING(out); } PG_FUNCTION_INFO_V1(ip4_recv); Datum ip4_recv(PG_FUNCTION_ARGS) { - StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); - PG_RETURN_IP4((IP4) pq_getmsgint(buf, sizeof(IP4))); + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); + PG_RETURN_IP4((IP4) pq_getmsgint(buf, sizeof(IP4))); } PG_FUNCTION_INFO_V1(ip4_send); Datum ip4_send(PG_FUNCTION_ARGS) { - IP4 arg1 = PG_GETARG_IP4(0); - StringInfoData buf; + IP4 arg1 = PG_GETARG_IP4(0); + StringInfoData buf; - pq_begintypsend(&buf); - pq_sendint(&buf, arg1, sizeof(IP4)); - PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); + pq_begintypsend(&buf); + pq_sendint(&buf, arg1, sizeof(IP4)); + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); } PG_FUNCTION_INFO_V1(ip4hash); Datum ip4hash(PG_FUNCTION_ARGS) { - IP4 arg1 = PG_GETARG_IP4(0); + IP4 arg1 = PG_GETARG_IP4(0); - return hash_any((unsigned char *)&arg1, sizeof(IP4)); + return hash_any((unsigned char *)&arg1, sizeof(IP4)); } PG_FUNCTION_INFO_V1(ip4_hash_extended); Datum ip4_hash_extended(PG_FUNCTION_ARGS) { - IP4 arg1 = PG_GETARG_IP4(0); + IP4 arg1 = PG_GETARG_IP4(0); uint64 seed = DatumGetUInt64(PG_GETARG_DATUM(1)); - return hash_any_extended((unsigned char *)&arg1, sizeof(IP4), seed); + return hash_any_extended((unsigned char *)&arg1, sizeof(IP4), seed); } PG_FUNCTION_INFO_V1(ip4_cast_to_text); Datum ip4_cast_to_text(PG_FUNCTION_ARGS) { - IP4 ip = PG_GETARG_IP4(0); - text *out = make_text(IP4_STRING_MAX); - set_text_len(out, ip4_raw_output(ip, VARDATA(out), IP4_STRING_MAX)); - PG_RETURN_TEXT_P(out); + IP4 ip = PG_GETARG_IP4(0); + text *out = make_text(IP4_STRING_MAX); + set_text_len(out, ip4_raw_output(ip, VARDATA(out), IP4_STRING_MAX)); + PG_RETURN_TEXT_P(out); } PG_FUNCTION_INFO_V1(ip4_cast_from_text); Datum ip4_cast_from_text(PG_FUNCTION_ARGS) { - text *txt = PG_GETARG_TEXT_PP(0); - int tlen = VARSIZE_ANY_EXHDR(txt); - char buf[IP4_STRING_MAX]; - - if (tlen < sizeof(buf)) - { - IP4 ip; - - memcpy(buf, VARDATA_ANY(txt), tlen); - buf[tlen] = 0; - if (ip4_raw_input(buf, &ip)) - PG_RETURN_IP4(ip); - } - - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid IP4 value in text"))); - PG_RETURN_NULL(); + text *txt = PG_GETARG_TEXT_PP(0); + int tlen = VARSIZE_ANY_EXHDR(txt); + char buf[IP4_STRING_MAX]; + + if (tlen < sizeof(buf)) + { + IP4 ip; + + memcpy(buf, VARDATA_ANY(txt), tlen); + buf[tlen] = 0; + if (ip4_raw_input(buf, &ip)) + PG_RETURN_IP4(ip); + } + + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid IP4 value in text"))); } PG_FUNCTION_INFO_V1(ip4_cast_from_inet); Datum ip4_cast_from_inet(PG_FUNCTION_ARGS) { - inet *inetptr = PG_GETARG_INET_P(0); - inet_struct *in = INET_STRUCT_DATA(inetptr); + inet *inetptr = PG_GETARG_INET_P(0); + inet_struct *in = INET_STRUCT_DATA(inetptr); - if (in->family == PGSQL_AF_INET) - { - unsigned char *p = in->ipaddr; - IP4 ip = (p[0] << 24)|(p[1] << 16)|(p[2] << 8)|p[3]; - PG_RETURN_IP4(ip); - } - - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid INET value for conversion to IP4"))); - PG_RETURN_NULL(); + if (in->family == PGSQL_AF_INET) + { + unsigned char *p = in->ipaddr; + IP4 ip = (p[0] << 24)|(p[1] << 16)|(p[2] << 8)|p[3]; + PG_RETURN_IP4(ip); + } + + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid INET value for conversion to IP4"))); } PG_FUNCTION_INFO_V1(ip4_cast_to_cidr); Datum ip4_cast_to_cidr(PG_FUNCTION_ARGS) { - IP4 ip = PG_GETARG_IP4(0); - inet *res = palloc0(VARHDRSZ + sizeof(inet_struct)); - inet_struct *in; - - SET_VARSIZE(res, VARHDRSZ + offsetof(inet_struct, ipaddr) + 4); - - in = ((inet_struct *)VARDATA(res)); - in->bits = 32; - in->family = PGSQL_AF_INET; - { - unsigned char *p = in->ipaddr; - p[0] = (ip >> 24) & 0xff; - p[1] = (ip >> 16) & 0xff; - p[2] = (ip >> 8) & 0xff; - p[3] = (ip ) & 0xff; - } + IP4 ip = PG_GETARG_IP4(0); + inet *res = palloc0(VARHDRSZ + sizeof(inet_struct)); + inet_struct *in; + + SET_VARSIZE(res, VARHDRSZ + offsetof(inet_struct, ipaddr) + 4); - PG_RETURN_INET_P(res); + in = ((inet_struct *)VARDATA(res)); + in->bits = 32; + in->family = PGSQL_AF_INET; + { + unsigned char *p = in->ipaddr; + p[0] = (ip >> 24) & 0xff; + p[1] = (ip >> 16) & 0xff; + p[2] = (ip >> 8) & 0xff; + p[3] = (ip ) & 0xff; + } + + PG_RETURN_INET_P(res); } PG_FUNCTION_INFO_V1(ip4_cast_to_bigint); Datum ip4_cast_to_bigint(PG_FUNCTION_ARGS) { - IP4 ip = PG_GETARG_IP4(0); - PG_RETURN_INT64(ip); + IP4 ip = PG_GETARG_IP4(0); + PG_RETURN_INT64(ip); } PG_FUNCTION_INFO_V1(ip4_cast_to_numeric); Datum ip4_cast_to_numeric(PG_FUNCTION_ARGS) { - IP4 ip = PG_GETARG_IP4(0); + IP4 ip = PG_GETARG_IP4(0); int64 v = ip; PG_RETURN_DATUM(DirectFunctionCall1(int8_numeric, Int64GetDatumFast(v))); } @@ -304,67 +301,67 @@ Datum ip4_cast_from_bigint(PG_FUNCTION_ARGS) { - int64 val = PG_GETARG_INT64(0); + int64 val = PG_GETARG_INT64(0); - if (val < -(int64)0x80000000UL || val > (int64)0xFFFFFFFFUL) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("ip address out of range"))); + if (val >= -(int64)0x80000000UL && val <= (int64)0xFFFFFFFFUL) + PG_RETURN_IP4(val); - PG_RETURN_IP4(val); + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("ip address out of range"))); } PG_FUNCTION_INFO_V1(ip4_cast_to_double); Datum ip4_cast_to_double(PG_FUNCTION_ARGS) { - IP4 ip = PG_GETARG_IP4(0); - PG_RETURN_FLOAT8(ip); + IP4 ip = PG_GETARG_IP4(0); + PG_RETURN_FLOAT8(ip); } PG_FUNCTION_INFO_V1(ip4_cast_from_double); Datum ip4_cast_from_double(PG_FUNCTION_ARGS) { - float8 val = PG_GETARG_FLOAT8(0); - float8 ival = 0; + float8 val = PG_GETARG_FLOAT8(0); + float8 ival = 0; - if (modf(val,&ival) != 0.0) - { - ereport(WARNING, - (errcode(ERRCODE_WARNING), - errmsg("double converted to IP4 is not integral"))); - } - - if (ival < -(float8)0x80000000UL || ival > (float8)0xFFFFFFFFUL) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("ip address out of range"))); + if (modf(val,&ival) != 0.0) + { + ereport(WARNING, + (errcode(ERRCODE_WARNING), + errmsg("double converted to IP4 is not integral"))); + } /* * casting directly to ulong evokes the nasal demons for negative values, * casting to long first evokes them for large positive values if long is * 32bit. */ - if (ival < 0) + + if (ival >= -(float8)0x80000000UL && ival < 0) PG_RETURN_IP4((unsigned long) (long) ival); - else + else if (ival >= 0 && ival <= (float8)0xFFFFFFFFUL) PG_RETURN_IP4((unsigned long) ival); + + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("ip address out of range"))); } PG_FUNCTION_INFO_V1(ip4_cast_from_numeric); Datum ip4_cast_from_numeric(PG_FUNCTION_ARGS) { - Datum val_num = PG_GETARG_DATUM(0); + Datum val_num = PG_GETARG_DATUM(0); int64 val = DatumGetInt64(DirectFunctionCall1(numeric_int8,val_num)); - if (val < -(int64)0x80000000UL || val > (int64)0xFFFFFFFFUL) - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("ip address out of range"))); + if (val >= -(int64)0x80000000UL && val <= (int64)0xFFFFFFFFUL) + PG_RETURN_IP4((unsigned long) val); - PG_RETURN_IP4((unsigned long) val); + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("ip address out of range"))); } PG_FUNCTION_INFO_V1(ip4_cast_from_bit); @@ -375,15 +372,14 @@ if (val->bit_len == 32) { - bits8 *p = VARBITS(val); - IP4 ip = (p[0] << 24)|(p[1] << 16)|(p[2] << 8)|p[3]; - PG_RETURN_IP4(ip); + bits8 *p = VARBITS(val); + IP4 ip = (p[0] << 24)|(p[1] << 16)|(p[2] << 8)|p[3]; + PG_RETURN_IP4(ip); } - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid BIT value for conversion to IP4"))); - PG_RETURN_NULL(); + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid BIT value for conversion to IP4"))); } PG_FUNCTION_INFO_V1(ip4_cast_to_bit); @@ -401,7 +397,7 @@ p[0] = (ip >> 24) & 0xff; p[1] = (ip >> 16) & 0xff; p[2] = (ip >> 8) & 0xff; - p[3] = (ip ) & 0xff; + p[3] = (ip ) & 0xff; PG_RETURN_VARBIT_P(res); } @@ -414,15 +410,14 @@ if (VARSIZE_ANY_EXHDR(val) == 4) { - unsigned char *p = (unsigned char *) VARDATA_ANY(val); - IP4 ip = (p[0] << 24)|(p[1] << 16)|(p[2] << 8)|p[3]; - PG_RETURN_IP4(ip); + unsigned char *p = (unsigned char *) VARDATA_ANY(val); + IP4 ip = (p[0] << 24)|(p[1] << 16)|(p[2] << 8)|p[3]; + PG_RETURN_IP4(ip); } - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid BYTEA value for conversion to IP4"))); - PG_RETURN_NULL(); + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid BYTEA value for conversion to IP4"))); } PG_FUNCTION_INFO_V1(ip4_cast_to_bytea); @@ -438,7 +433,7 @@ p[0] = (ip >> 24) & 0xff; p[1] = (ip >> 16) & 0xff; p[2] = (ip >> 8) & 0xff; - p[3] = (ip ) & 0xff; + p[3] = (ip ) & 0xff; PG_RETURN_BYTEA_P(res); } @@ -447,214 +442,214 @@ Datum ip4_netmask(PG_FUNCTION_ARGS) { - int pfxlen = PG_GETARG_INT32(0); + int pfxlen = PG_GETARG_INT32(0); - if (pfxlen < 0 || pfxlen > 32) - { - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("prefix length out of range"))); - } + if (pfxlen < 0 || pfxlen > 32) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("prefix length out of range"))); + } - PG_RETURN_IP4( netmask(pfxlen) ); + PG_RETURN_IP4( netmask(pfxlen) ); } PG_FUNCTION_INFO_V1(ip4_net_lower); Datum ip4_net_lower(PG_FUNCTION_ARGS) { - IP4 ip = PG_GETARG_IP4(0); - int pfxlen = PG_GETARG_INT32(1); + IP4 ip = PG_GETARG_IP4(0); + int pfxlen = PG_GETARG_INT32(1); - if (pfxlen < 0 || pfxlen > 32) - { - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("prefix length out of range"))); - } + if (pfxlen < 0 || pfxlen > 32) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("prefix length out of range"))); + } - PG_RETURN_IP4( ip & netmask(pfxlen) ); + PG_RETURN_IP4( ip & netmask(pfxlen) ); } PG_FUNCTION_INFO_V1(ip4_net_upper); Datum ip4_net_upper(PG_FUNCTION_ARGS) { - IP4 ip = PG_GETARG_IP4(0); - int pfxlen = PG_GETARG_INT32(1); + IP4 ip = PG_GETARG_IP4(0); + int pfxlen = PG_GETARG_INT32(1); - if (pfxlen < 0 || pfxlen > 32) - { - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("prefix length out of range"))); - } + if (pfxlen < 0 || pfxlen > 32) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("prefix length out of range"))); + } - PG_RETURN_IP4( ip | hostmask(pfxlen) ); + PG_RETURN_IP4( ip | hostmask(pfxlen) ); } PG_FUNCTION_INFO_V1(ip4_plus_int); Datum ip4_plus_int(PG_FUNCTION_ARGS) { - IP4 ip = PG_GETARG_IP4(0); - int addend = PG_GETARG_INT32(1); - IP4 result = ip + (IP4) addend; - - if ((addend < 0) != (result < ip)) - { - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("ip address out of range"))); - } + IP4 ip = PG_GETARG_IP4(0); + int addend = PG_GETARG_INT32(1); + IP4 result = ip + (IP4) addend; - PG_RETURN_IP4(result); + if ((addend < 0) != (result < ip)) + { + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("ip address out of range"))); + } + + PG_RETURN_IP4(result); } PG_FUNCTION_INFO_V1(ip4_plus_bigint); Datum ip4_plus_bigint(PG_FUNCTION_ARGS) { - IP4 ip = PG_GETARG_IP4(0); - int64 addend = PG_GETARG_INT64(1); - int64 result = (int64) ip + addend; - - if (((addend < 0) != (result < ip)) - || result != (int64)(IP4)result) - { - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("ip address out of range"))); - } + IP4 ip = PG_GETARG_IP4(0); + int64 addend = PG_GETARG_INT64(1); + uint64 result = (uint64) ip + addend; - PG_RETURN_IP4( (IP4)(result) ); + if (((addend < 0) != (result < ip)) + || result != (uint64)(IP4)result) + { + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("ip address out of range"))); + } + + PG_RETURN_IP4( (IP4)(result) ); } PG_FUNCTION_INFO_V1(ip4_plus_numeric); Datum ip4_plus_numeric(PG_FUNCTION_ARGS) { - IP4 ip = PG_GETARG_IP4(0); - Datum addend_num = PG_GETARG_DATUM(1); + IP4 ip = PG_GETARG_IP4(0); + Datum addend_num = PG_GETARG_DATUM(1); int64 addend = DatumGetInt64(DirectFunctionCall1(numeric_int8,addend_num)); - int64 result = (int64) ip + addend; + uint64 result = (uint64) ip + addend; - if (((addend < 0) != (result < ip)) - || result != (int64)(IP4)result) - { - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("ip address out of range"))); - } + if (((addend < 0) != (result < ip)) + || result != (uint64)(IP4)result) + { + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("ip address out of range"))); + } - PG_RETURN_IP4( (IP4)(result) ); + PG_RETURN_IP4( (IP4)(result) ); } PG_FUNCTION_INFO_V1(ip4_minus_int); Datum ip4_minus_int(PG_FUNCTION_ARGS) { - IP4 ip = PG_GETARG_IP4(0); - int subtrahend = PG_GETARG_INT32(1); - IP4 result = ip - (IP4) subtrahend; - - if ((subtrahend > 0) != (result < ip)) - { - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("ip address out of range"))); - } + IP4 ip = PG_GETARG_IP4(0); + int subtrahend = PG_GETARG_INT32(1); + IP4 result = ip - (IP4) subtrahend; - PG_RETURN_IP4(result); + if ((subtrahend > 0) != (result < ip)) + { + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("ip address out of range"))); + } + + PG_RETURN_IP4(result); } PG_FUNCTION_INFO_V1(ip4_minus_bigint); Datum ip4_minus_bigint(PG_FUNCTION_ARGS) { - IP4 ip = PG_GETARG_IP4(0); - int64 subtrahend = PG_GETARG_INT64(1); - int64 result = (int64) ip - subtrahend; - - if (((subtrahend > 0) != (result < ip)) - || result != (int64)(IP4)result) - { - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("ip address out of range"))); - } + IP4 ip = PG_GETARG_IP4(0); + int64 subtrahend = PG_GETARG_INT64(1); + uint64 result = (uint64) ip - subtrahend; - PG_RETURN_IP4( (IP4)(result) ); + if (((subtrahend > 0) != (result < ip)) + || result != (uint64)(IP4)result) + { + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("ip address out of range"))); + } + + PG_RETURN_IP4( (IP4)(result) ); } PG_FUNCTION_INFO_V1(ip4_minus_numeric); Datum ip4_minus_numeric(PG_FUNCTION_ARGS) { - IP4 ip = PG_GETARG_IP4(0); + IP4 ip = PG_GETARG_IP4(0); Datum subtrahend_num = PG_GETARG_DATUM(1); int64 subtrahend = DatumGetInt64(DirectFunctionCall1(numeric_int8,subtrahend_num)); - int64 result = (int64) ip - subtrahend; + uint64 result = (uint64) ip - subtrahend; - if (((subtrahend > 0) != (result < ip)) - || result != (int64)(IP4)result) - { - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("ip address out of range"))); - } + if (((subtrahend > 0) != (result < ip)) + || result != (uint64)(IP4)result) + { + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("ip address out of range"))); + } - PG_RETURN_IP4( (IP4)(result) ); + PG_RETURN_IP4( (IP4)(result) ); } PG_FUNCTION_INFO_V1(ip4_minus_ip4); Datum ip4_minus_ip4(PG_FUNCTION_ARGS) { - IP4 minuend = PG_GETARG_IP4(0); - IP4 subtrahend = PG_GETARG_IP4(1); - int64 result = (int64) minuend - (int64) subtrahend; + IP4 minuend = PG_GETARG_IP4(0); + IP4 subtrahend = PG_GETARG_IP4(1); + int64 result = (int64) minuend - (int64) subtrahend; - PG_RETURN_INT64(result); + PG_RETURN_INT64(result); } PG_FUNCTION_INFO_V1(ip4_and); Datum ip4_and(PG_FUNCTION_ARGS) { - IP4 a = PG_GETARG_IP4(0); - IP4 b = PG_GETARG_IP4(1); + IP4 a = PG_GETARG_IP4(0); + IP4 b = PG_GETARG_IP4(1); - PG_RETURN_IP4(a & b); + PG_RETURN_IP4(a & b); } PG_FUNCTION_INFO_V1(ip4_or); Datum ip4_or(PG_FUNCTION_ARGS) { - IP4 a = PG_GETARG_IP4(0); - IP4 b = PG_GETARG_IP4(1); + IP4 a = PG_GETARG_IP4(0); + IP4 b = PG_GETARG_IP4(1); - PG_RETURN_IP4(a | b); + PG_RETURN_IP4(a | b); } PG_FUNCTION_INFO_V1(ip4_xor); Datum ip4_xor(PG_FUNCTION_ARGS) { - IP4 a = PG_GETARG_IP4(0); - IP4 b = PG_GETARG_IP4(1); + IP4 a = PG_GETARG_IP4(0); + IP4 b = PG_GETARG_IP4(1); - PG_RETURN_IP4(a ^ b); + PG_RETURN_IP4(a ^ b); } PG_FUNCTION_INFO_V1(ip4_not); Datum ip4_not(PG_FUNCTION_ARGS) { - IP4 a = PG_GETARG_IP4(0); + IP4 a = PG_GETARG_IP4(0); - PG_RETURN_IP4(~a); + PG_RETURN_IP4(~a); } @@ -664,200 +659,205 @@ Datum ip4r_in(PG_FUNCTION_ARGS) { - char *str = PG_GETARG_CSTRING(0); - IP4R ipr; - if (ip4r_from_str(str, &ipr)) - { - IP4R *res = palloc(sizeof(IP4R)); - *res = ipr; - PG_RETURN_IP4R_P(res); - } - - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid IP4R value: \"%s\"", str))); - PG_RETURN_NULL(); + char *str = PG_GETARG_CSTRING(0); + IP4R ipr; + if (ip4r_from_str(str, &ipr)) + { + IP4R *res = palloc(sizeof(IP4R)); + *res = ipr; + PG_RETURN_IP4R_P(res); + } + + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid IP4R value: \"%s\"", str))); } PG_FUNCTION_INFO_V1(ip4r_out); Datum ip4r_out(PG_FUNCTION_ARGS) { - IP4R *ipr = PG_GETARG_IP4R_P(0); - char *out = palloc(IP4R_STRING_MAX); - ip4r_to_str(ipr, out, IP4R_STRING_MAX); - PG_RETURN_CSTRING(out); + IP4R *ipr = PG_GETARG_IP4R_P(0); + char *out = palloc(IP4R_STRING_MAX); + ip4r_to_str(ipr, out, IP4R_STRING_MAX); + PG_RETURN_CSTRING(out); } PG_FUNCTION_INFO_V1(ip4r_recv); Datum ip4r_recv(PG_FUNCTION_ARGS) { - StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); - IP4R *ipr = palloc(sizeof(IP4R)); + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); + IP4R *ipr = palloc(sizeof(IP4R)); - ipr->lower = (IP4) pq_getmsgint(buf, sizeof(IP4)); - ipr->upper = (IP4) pq_getmsgint(buf, sizeof(IP4)); + ipr->lower = (IP4) pq_getmsgint(buf, sizeof(IP4)); + ipr->upper = (IP4) pq_getmsgint(buf, sizeof(IP4)); - PG_RETURN_IP4R_P(ipr); + if (ipr->lower > ipr->upper) + { + IP4 t = ipr->upper; + ipr->upper = ipr->lower; + ipr->lower = t; + } + + PG_RETURN_IP4R_P(ipr); } PG_FUNCTION_INFO_V1(ip4r_send); Datum ip4r_send(PG_FUNCTION_ARGS) { - IP4R *ipr = PG_GETARG_IP4R_P(0); - StringInfoData buf; + IP4R *ipr = PG_GETARG_IP4R_P(0); + StringInfoData buf; - pq_begintypsend(&buf); - pq_sendint(&buf, ipr->lower, sizeof(IP4)); - pq_sendint(&buf, ipr->upper, sizeof(IP4)); - PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); + pq_begintypsend(&buf); + pq_sendint(&buf, ipr->lower, sizeof(IP4)); + pq_sendint(&buf, ipr->upper, sizeof(IP4)); + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); } PG_FUNCTION_INFO_V1(ip4rhash); Datum ip4rhash(PG_FUNCTION_ARGS) { - IP4R *arg1 = PG_GETARG_IP4R_P(0); + IP4R *arg1 = PG_GETARG_IP4R_P(0); - return hash_any((unsigned char *)arg1, sizeof(IP4R)); + return hash_any((unsigned char *)arg1, sizeof(IP4R)); } PG_FUNCTION_INFO_V1(ip4r_hash_extended); Datum ip4r_hash_extended(PG_FUNCTION_ARGS) { - IP4R *arg1 = PG_GETARG_IP4R_P(0); + IP4R *arg1 = PG_GETARG_IP4R_P(0); uint64 seed = DatumGetUInt64(PG_GETARG_DATUM(1)); - return hash_any_extended((unsigned char *)arg1, sizeof(IP4R), seed); + return hash_any_extended((unsigned char *)arg1, sizeof(IP4R), seed); } PG_FUNCTION_INFO_V1(ip4r_cast_to_text); Datum ip4r_cast_to_text(PG_FUNCTION_ARGS) { - IP4R *ipr = PG_GETARG_IP4R_P(0); - text *out = make_text(IP4R_STRING_MAX); - set_text_len(out, ip4r_to_str(ipr, VARDATA(out), IP4R_STRING_MAX)); - PG_RETURN_TEXT_P(out); + IP4R *ipr = PG_GETARG_IP4R_P(0); + text *out = make_text(IP4R_STRING_MAX); + set_text_len(out, ip4r_to_str(ipr, VARDATA(out), IP4R_STRING_MAX)); + PG_RETURN_TEXT_P(out); } PG_FUNCTION_INFO_V1(ip4r_cast_from_text); Datum ip4r_cast_from_text(PG_FUNCTION_ARGS) { - text *txt = PG_GETARG_TEXT_PP(0); - int tlen = VARSIZE_ANY_EXHDR(txt); - char buf[IP4R_STRING_MAX]; - - if (tlen < sizeof(buf)) - { - IP4R ipr; - - memcpy(buf, VARDATA_ANY(txt), tlen); - buf[tlen] = 0; - if (ip4r_from_str(buf, &ipr)) - { - IP4R *res = palloc(sizeof(IP4R)); - *res = ipr; - PG_RETURN_IP4R_P(res); - } - } - - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid IP4R value in text"))); - PG_RETURN_NULL(); + text *txt = PG_GETARG_TEXT_PP(0); + int tlen = VARSIZE_ANY_EXHDR(txt); + char buf[IP4R_STRING_MAX]; + + if (tlen < sizeof(buf)) + { + IP4R ipr; + + memcpy(buf, VARDATA_ANY(txt), tlen); + buf[tlen] = 0; + if (ip4r_from_str(buf, &ipr)) + { + IP4R *res = palloc(sizeof(IP4R)); + *res = ipr; + PG_RETURN_IP4R_P(res); + } + } + + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid IP4R value in text"))); + PG_RETURN_NULL(); } PG_FUNCTION_INFO_V1(ip4r_cast_from_cidr); Datum ip4r_cast_from_cidr(PG_FUNCTION_ARGS) { - inet *inetptr = PG_GETARG_INET_P(0); - inet_struct *in = INET_STRUCT_DATA(inetptr); + inet *inetptr = PG_GETARG_INET_P(0); + inet_struct *in = INET_STRUCT_DATA(inetptr); + + if (in->family == PGSQL_AF_INET) + { + unsigned char *p = in->ipaddr; + IP4 ip = (p[0] << 24)|(p[1] << 16)|(p[2] << 8)|p[3]; + IP4R ipr; + if (ip4r_from_cidr(ip, in->bits, &ipr)) + { + IP4R *res = palloc(sizeof(IP4R)); + *res = ipr; + PG_RETURN_IP4R_P(res); + } + } - if (in->family == PGSQL_AF_INET) - { - unsigned char *p = in->ipaddr; - IP4 ip = (p[0] << 24)|(p[1] << 16)|(p[2] << 8)|p[3]; - IP4R ipr; - if (ip4r_from_cidr(ip, in->bits, &ipr)) - { - IP4R *res = palloc(sizeof(IP4R)); - *res = ipr; - PG_RETURN_IP4R_P(res); - } - } - - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid CIDR value for conversion to IP4R"))); - PG_RETURN_NULL(); + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid CIDR value for conversion to IP4R"))); } PG_FUNCTION_INFO_V1(ip4r_cast_to_cidr); Datum ip4r_cast_to_cidr(PG_FUNCTION_ARGS) { - IP4R *ipr = PG_GETARG_IP4R_P(0); - IP4 ip = ipr->lower; - inet *res; - inet_struct *in; - unsigned bits = masklen(ip, ipr->upper); - - if (bits > 32) - PG_RETURN_NULL(); - - res = palloc0(VARHDRSZ + sizeof(inet_struct)); - SET_VARSIZE(res, VARHDRSZ + offsetof(inet_struct, ipaddr) + 4); - - in = ((inet_struct *)VARDATA(res)); - in->bits = bits; - in->family = PGSQL_AF_INET; - { - unsigned char *p = in->ipaddr; - p[0] = (ip >> 24) & 0xff; - p[1] = (ip >> 16) & 0xff; - p[2] = (ip >> 8) & 0xff; - p[3] = (ip ) & 0xff; - } + IP4R *ipr = PG_GETARG_IP4R_P(0); + IP4 ip = ipr->lower; + inet *res; + inet_struct *in; + unsigned bits = masklen(ip, ipr->upper); + + if (bits > 32) + PG_RETURN_NULL(); + + res = palloc0(VARHDRSZ + sizeof(inet_struct)); + SET_VARSIZE(res, VARHDRSZ + offsetof(inet_struct, ipaddr) + 4); + + in = ((inet_struct *)VARDATA(res)); + in->bits = bits; + in->family = PGSQL_AF_INET; + { + unsigned char *p = in->ipaddr; + p[0] = (ip >> 24) & 0xff; + p[1] = (ip >> 16) & 0xff; + p[2] = (ip >> 8) & 0xff; + p[3] = (ip ) & 0xff; + } - PG_RETURN_INET_P(res); + PG_RETURN_INET_P(res); } PG_FUNCTION_INFO_V1(ip4r_cast_from_ip4); Datum ip4r_cast_from_ip4(PG_FUNCTION_ARGS) { - IP4 ip = PG_GETARG_IP4(0); - IP4R *res = palloc(sizeof(IP4R)); - if (ip4r_from_inet(ip, 32, res)) - { - PG_RETURN_IP4R_P(res); - } - - pfree(res); - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid IP4 value for conversion to IP4R (shouldn't be possible)"))); - PG_RETURN_NULL(); + IP4 ip = PG_GETARG_IP4(0); + IP4R *res = palloc(sizeof(IP4R)); + if (ip4r_from_inet(ip, 32, res)) + { + PG_RETURN_IP4R_P(res); + } + + pfree(res); + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid IP4 value for conversion to IP4R (shouldn't be possible)"))); + PG_RETURN_NULL(); } PG_FUNCTION_INFO_V1(ip4r_from_ip4s); Datum ip4r_from_ip4s(PG_FUNCTION_ARGS) { - IP4 a = PG_GETARG_IP4(0); - IP4 b = PG_GETARG_IP4(1); - IP4R *res = palloc(sizeof(IP4R)); - if (a < b) - res->lower = a, res->upper = b; - else - res->lower = b, res->upper = a; - PG_RETURN_IP4R_P( res ); + IP4 a = PG_GETARG_IP4(0); + IP4 b = PG_GETARG_IP4(1); + IP4R *res = palloc(sizeof(IP4R)); + if (a < b) + res->lower = a, res->upper = b; + else + res->lower = b, res->upper = a; + PG_RETURN_IP4R_P( res ); } PG_FUNCTION_INFO_V1(ip4r_cast_from_bit); @@ -870,7 +870,7 @@ if (bitlen <= 32) { bits8 buf[4]; - bits8 *p = VARBITS(val); + bits8 *p = VARBITS(val); IP4 ip; IP4R *res = palloc(sizeof(IP4R)); @@ -881,41 +881,40 @@ p = buf; } - ip = (p[0] << 24)|(p[1] << 16)|(p[2] << 8)|p[3]; + ip = (p[0] << 24)|(p[1] << 16)|(p[2] << 8)|p[3]; if (ip4r_from_cidr(ip, bitlen, res)) PG_RETURN_IP4R_P(res); } - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid BIT value for conversion to IP4R"))); - PG_RETURN_NULL(); + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid BIT value for conversion to IP4R"))); } PG_FUNCTION_INFO_V1(ip4r_cast_to_bit); Datum ip4r_cast_to_bit(PG_FUNCTION_ARGS) { - IP4R *ipr = PG_GETARG_IP4R_P(0); - IP4 ip = ipr->lower; - unsigned bits = masklen(ip, ipr->upper); + IP4R *ipr = PG_GETARG_IP4R_P(0); + IP4 ip = ipr->lower; + unsigned bits = masklen(ip, ipr->upper); VarBit *res; unsigned char buf[4]; int len; - if (bits > 32) - PG_RETURN_NULL(); + if (bits > 32) + PG_RETURN_NULL(); len = VARBITTOTALLEN(bits); - res = palloc0(len); - SET_VARSIZE(res, len); + res = palloc0(len); + SET_VARSIZE(res, len); VARBITLEN(res) = bits; buf[0] = (ip >> 24) & 0xff; buf[1] = (ip >> 16) & 0xff; - buf[2] = (ip >> 8) & 0xff; - buf[3] = (ip ) & 0xff; + buf[2] = (ip >> 8) & 0xff; + buf[3] = (ip ) & 0xff; memcpy(VARBITS(res), buf, VARBITBYTES(res)); PG_RETURN_VARBIT_P(res); @@ -925,73 +924,73 @@ Datum ip4r_net_prefix(PG_FUNCTION_ARGS) { - IP4 ip = PG_GETARG_IP4(0); - int pfxlen = PG_GETARG_INT32(1); + IP4 ip = PG_GETARG_IP4(0); + int pfxlen = PG_GETARG_INT32(1); - if (pfxlen < 0 || pfxlen > 32) - { - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("prefix length out of range"))); - } - - { - IP4 mask = netmask(pfxlen); - IP4R *res = palloc(sizeof(IP4R)); + if (pfxlen < 0 || pfxlen > 32) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("prefix length out of range"))); + } - res->lower = ip & mask; - res->upper = ip | ~mask; + { + IP4 mask = netmask(pfxlen); + IP4R *res = palloc(sizeof(IP4R)); + + res->lower = ip & mask; + res->upper = ip | ~mask; - PG_RETURN_IP4R_P(res); - } + PG_RETURN_IP4R_P(res); + } } PG_FUNCTION_INFO_V1(ip4r_net_mask); Datum ip4r_net_mask(PG_FUNCTION_ARGS) { - IP4 ip = PG_GETARG_IP4(0); - IP4 mask = PG_GETARG_IP4(1); + IP4 ip = PG_GETARG_IP4(0); + IP4 mask = PG_GETARG_IP4(1); - if (!ip4_valid_netmask(mask)) - { - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid netmask"))); - } + if (!ip4_valid_netmask(mask)) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid netmask"))); + } - { - IP4R *res = palloc(sizeof(IP4R)); + { + IP4R *res = palloc(sizeof(IP4R)); - res->lower = ip & mask; - res->upper = ip | ~mask; + res->lower = ip & mask; + res->upper = ip | ~mask; - PG_RETURN_IP4R_P(res); - } + PG_RETURN_IP4R_P(res); + } } PG_FUNCTION_INFO_V1(ip4r_lower); Datum ip4r_lower(PG_FUNCTION_ARGS) { - IP4R *ipr = PG_GETARG_IP4R_P(0); - PG_RETURN_IP4( ipr->lower ); + IP4R *ipr = PG_GETARG_IP4R_P(0); + PG_RETURN_IP4( ipr->lower ); } PG_FUNCTION_INFO_V1(ip4r_upper); Datum ip4r_upper(PG_FUNCTION_ARGS) { - IP4R *ipr = PG_GETARG_IP4R_P(0); - PG_RETURN_IP4( ipr->upper ); + IP4R *ipr = PG_GETARG_IP4R_P(0); + PG_RETURN_IP4( ipr->upper ); } PG_FUNCTION_INFO_V1(ip4r_is_cidr); Datum ip4r_is_cidr(PG_FUNCTION_ARGS) { - IP4R *ipr = PG_GETARG_IP4R_P(0); - PG_RETURN_BOOL( (masklen(ipr->lower,ipr->upper) <= 32U) ); + IP4R *ipr = PG_GETARG_IP4R_P(0); + PG_RETURN_BOOL( (masklen(ipr->lower,ipr->upper) <= 32U) ); } /* @@ -1036,156 +1035,156 @@ Datum ip4_lt(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip4_lessthan(PG_GETARG_IP4(0), PG_GETARG_IP4(1)) ); + PG_RETURN_BOOL( ip4_lessthan(PG_GETARG_IP4(0), PG_GETARG_IP4(1)) ); } PG_FUNCTION_INFO_V1(ip4_le); Datum ip4_le(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip4_less_eq(PG_GETARG_IP4(0), PG_GETARG_IP4(1)) ); + PG_RETURN_BOOL( ip4_less_eq(PG_GETARG_IP4(0), PG_GETARG_IP4(1)) ); } PG_FUNCTION_INFO_V1(ip4_gt); Datum ip4_gt(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip4_lessthan(PG_GETARG_IP4(1), PG_GETARG_IP4(0)) ); + PG_RETURN_BOOL( ip4_lessthan(PG_GETARG_IP4(1), PG_GETARG_IP4(0)) ); } PG_FUNCTION_INFO_V1(ip4_ge); Datum ip4_ge(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip4_less_eq(PG_GETARG_IP4(1), PG_GETARG_IP4(0)) ); + PG_RETURN_BOOL( ip4_less_eq(PG_GETARG_IP4(1), PG_GETARG_IP4(0)) ); } PG_FUNCTION_INFO_V1(ip4_eq); Datum ip4_eq(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip4_equal(PG_GETARG_IP4(0), PG_GETARG_IP4(1)) ); + PG_RETURN_BOOL( ip4_equal(PG_GETARG_IP4(0), PG_GETARG_IP4(1)) ); } PG_FUNCTION_INFO_V1(ip4_neq); Datum ip4_neq(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( !ip4_equal(PG_GETARG_IP4(0), PG_GETARG_IP4(1)) ); + PG_RETURN_BOOL( !ip4_equal(PG_GETARG_IP4(0), PG_GETARG_IP4(1)) ); } PG_FUNCTION_INFO_V1(ip4r_lt); Datum ip4r_lt(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip4r_lessthan(PG_GETARG_IP4R_P(0), PG_GETARG_IP4R_P(1)) ); + PG_RETURN_BOOL( ip4r_lessthan(PG_GETARG_IP4R_P(0), PG_GETARG_IP4R_P(1)) ); } PG_FUNCTION_INFO_V1(ip4r_le); Datum ip4r_le(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip4r_less_eq(PG_GETARG_IP4R_P(0), PG_GETARG_IP4R_P(1)) ); + PG_RETURN_BOOL( ip4r_less_eq(PG_GETARG_IP4R_P(0), PG_GETARG_IP4R_P(1)) ); } PG_FUNCTION_INFO_V1(ip4r_gt); Datum ip4r_gt(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip4r_lessthan(PG_GETARG_IP4R_P(1), PG_GETARG_IP4R_P(0)) ); + PG_RETURN_BOOL( ip4r_lessthan(PG_GETARG_IP4R_P(1), PG_GETARG_IP4R_P(0)) ); } PG_FUNCTION_INFO_V1(ip4r_ge); Datum ip4r_ge(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip4r_less_eq(PG_GETARG_IP4R_P(1), PG_GETARG_IP4R_P(0)) ); + PG_RETURN_BOOL( ip4r_less_eq(PG_GETARG_IP4R_P(1), PG_GETARG_IP4R_P(0)) ); } PG_FUNCTION_INFO_V1(ip4r_eq); Datum ip4r_eq(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip4r_equal(PG_GETARG_IP4R_P(0), PG_GETARG_IP4R_P(1)) ); + PG_RETURN_BOOL( ip4r_equal(PG_GETARG_IP4R_P(0), PG_GETARG_IP4R_P(1)) ); } PG_FUNCTION_INFO_V1(ip4r_neq); Datum ip4r_neq(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( !ip4r_equal(PG_GETARG_IP4R_P(0), PG_GETARG_IP4R_P(1)) ); + PG_RETURN_BOOL( !ip4r_equal(PG_GETARG_IP4R_P(0), PG_GETARG_IP4R_P(1)) ); } PG_FUNCTION_INFO_V1(ip4r_overlaps); Datum ip4r_overlaps(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip4r_overlaps_internal(PG_GETARG_IP4R_P(0), - PG_GETARG_IP4R_P(1)) ); + PG_RETURN_BOOL( ip4r_overlaps_internal(PG_GETARG_IP4R_P(0), + PG_GETARG_IP4R_P(1)) ); } PG_FUNCTION_INFO_V1(ip4r_contains); Datum ip4r_contains(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip4r_contains_internal(PG_GETARG_IP4R_P(0), - PG_GETARG_IP4R_P(1), - true) ); + PG_RETURN_BOOL( ip4r_contains_internal(PG_GETARG_IP4R_P(0), + PG_GETARG_IP4R_P(1), + true) ); } PG_FUNCTION_INFO_V1(ip4r_contains_strict); Datum ip4r_contains_strict(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip4r_contains_internal(PG_GETARG_IP4R_P(0), - PG_GETARG_IP4R_P(1), - false) ); + PG_RETURN_BOOL( ip4r_contains_internal(PG_GETARG_IP4R_P(0), + PG_GETARG_IP4R_P(1), + false) ); } PG_FUNCTION_INFO_V1(ip4r_contained_by); Datum ip4r_contained_by(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip4r_contains_internal(PG_GETARG_IP4R_P(1), - PG_GETARG_IP4R_P(0), - true) ); + PG_RETURN_BOOL( ip4r_contains_internal(PG_GETARG_IP4R_P(1), + PG_GETARG_IP4R_P(0), + true) ); } PG_FUNCTION_INFO_V1(ip4r_contained_by_strict); Datum ip4r_contained_by_strict(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip4r_contains_internal(PG_GETARG_IP4R_P(1), - PG_GETARG_IP4R_P(0), - false) ); + PG_RETURN_BOOL( ip4r_contains_internal(PG_GETARG_IP4R_P(1), + PG_GETARG_IP4R_P(0), + false) ); } PG_FUNCTION_INFO_V1(ip4_contains); Datum ip4_contains(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip4_contains_internal(PG_GETARG_IP4R_P(0), PG_GETARG_IP4(1)) ); + PG_RETURN_BOOL( ip4_contains_internal(PG_GETARG_IP4R_P(0), PG_GETARG_IP4(1)) ); } PG_FUNCTION_INFO_V1(ip4_contained_by); Datum ip4_contained_by(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip4_contains_internal(PG_GETARG_IP4R_P(1), PG_GETARG_IP4(0)) ); + PG_RETURN_BOOL( ip4_contains_internal(PG_GETARG_IP4R_P(1), PG_GETARG_IP4(0)) ); } PG_FUNCTION_INFO_V1(ip4r_left_of); Datum ip4r_left_of(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip4r_left_internal(PG_GETARG_IP4R_P(0), PG_GETARG_IP4R_P(1)) ); + PG_RETURN_BOOL( ip4r_left_internal(PG_GETARG_IP4R_P(0), PG_GETARG_IP4R_P(1)) ); } PG_FUNCTION_INFO_V1(ip4r_right_of); Datum ip4r_right_of(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip4r_left_internal(PG_GETARG_IP4R_P(1), PG_GETARG_IP4R_P(0)) ); + PG_RETURN_BOOL( ip4r_left_internal(PG_GETARG_IP4R_P(1), PG_GETARG_IP4R_P(0)) ); } @@ -1193,37 +1192,37 @@ Datum ip4r_union(PG_FUNCTION_ARGS) { - IP4R *res = (IP4R *) palloc(sizeof(IP4R)); - ip4r_union_internal(PG_GETARG_IP4R_P(0), PG_GETARG_IP4R_P(1), res); - PG_RETURN_IP4R_P(res); + IP4R *res = (IP4R *) palloc(sizeof(IP4R)); + ip4r_union_internal(PG_GETARG_IP4R_P(0), PG_GETARG_IP4R_P(1), res); + PG_RETURN_IP4R_P(res); } PG_FUNCTION_INFO_V1(ip4r_inter); Datum ip4r_inter(PG_FUNCTION_ARGS) { - IP4R *res = (IP4R *) palloc(sizeof(IP4R)); - if (ip4r_inter_internal(PG_GETARG_IP4R_P(0), PG_GETARG_IP4R_P(1), res)) - { - PG_RETURN_IP4R_P(res); - } - pfree(res); - PG_RETURN_NULL(); + IP4R *res = (IP4R *) palloc(sizeof(IP4R)); + if (ip4r_inter_internal(PG_GETARG_IP4R_P(0), PG_GETARG_IP4R_P(1), res)) + { + PG_RETURN_IP4R_P(res); + } + pfree(res); + PG_RETURN_NULL(); } PG_FUNCTION_INFO_V1(ip4r_size); Datum ip4r_size(PG_FUNCTION_ARGS) { - double size = ip4r_metric(PG_GETARG_IP4R_P(0)); - PG_RETURN_FLOAT8(size); + double size = ip4r_metric(PG_GETARG_IP4R_P(0)); + PG_RETURN_FLOAT8(size); } PG_FUNCTION_INFO_V1(ip4r_size_exact); Datum ip4r_size_exact(PG_FUNCTION_ARGS) { - int64 size = (int64) ip4r_metric(PG_GETARG_IP4R_P(0)); + int64 size = (int64) ip4r_metric(PG_GETARG_IP4R_P(0)); PG_RETURN_DATUM(DirectFunctionCall1(int8_numeric, Int64GetDatumFast(size))); } @@ -1231,7 +1230,7 @@ Datum ip4r_prefixlen(PG_FUNCTION_ARGS) { - IP4R *ipr = PG_GETARG_IP4R_P(0); + IP4R *ipr = PG_GETARG_IP4R_P(0); unsigned len = masklen(ipr->lower, ipr->upper); if (len <= 32) PG_RETURN_INT32((int32) len); @@ -1240,40 +1239,40 @@ /***************************************************************************** - * Btree functions + * Btree functions *****************************************************************************/ PG_FUNCTION_INFO_V1(ip4r_cmp); Datum ip4r_cmp(PG_FUNCTION_ARGS) { - IP4R *a = PG_GETARG_IP4R_P(0); - IP4R *b = PG_GETARG_IP4R_P(1); - if (ip4r_lessthan(a,b)) - PG_RETURN_INT32(-1); - if (ip4r_equal(a,b)) - PG_RETURN_INT32(0); - PG_RETURN_INT32(1); + IP4R *a = PG_GETARG_IP4R_P(0); + IP4R *b = PG_GETARG_IP4R_P(1); + if (ip4r_lessthan(a,b)) + PG_RETURN_INT32(-1); + if (ip4r_equal(a,b)) + PG_RETURN_INT32(0); + PG_RETURN_INT32(1); } PG_FUNCTION_INFO_V1(ip4_cmp); Datum ip4_cmp(PG_FUNCTION_ARGS) { - IP4 a = PG_GETARG_IP4(0); - IP4 b = PG_GETARG_IP4(1); - if (ip4_lessthan(a,b)) - PG_RETURN_INT32(-1); - if (ip4_equal(a,b)) - PG_RETURN_INT32(0); - PG_RETURN_INT32(1); + IP4 a = PG_GETARG_IP4(0); + IP4 b = PG_GETARG_IP4(1); + if (ip4_lessthan(a,b)) + PG_RETURN_INT32(-1); + if (ip4_equal(a,b)) + PG_RETURN_INT32(0); + PG_RETURN_INT32(1); } /* * in_range(val ip4,base ip4,offset bigint,sub bool,less bool) * returns val CMP (base OP offset) * where CMP is <= if less, >= otherwise - * and OP is - if sub, + otherwise + * and OP is - if sub, + otherwise * We treat negative values of offset as special: they indicate * the (negation of) a cidr prefix length */ @@ -1347,7 +1346,7 @@ /***************************************************************************** - * GiST functions + * GiST functions *****************************************************************************/ /* @@ -1376,27 +1375,27 @@ Datum gip4r_consistent(PG_FUNCTION_ARGS) { - GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); - IP4R *query = (IP4R *) PG_GETARG_POINTER(1); - StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); - bool *recheck = (bool *) PG_GETARG_POINTER(4); - IP4R *key = (IP4R *) DatumGetPointer(entry->key); - bool retval; - - /* recheck is never needed with this type */ - if (recheck) - *recheck = false; - - /* - * * if entry is not leaf, use gip4r_internal_consistent, * else use - * gip4r_leaf_consistent - */ - if (GIST_LEAF(entry)) - retval = gip4r_leaf_consistent(key, query, strategy); - else - retval = gip4r_internal_consistent(key, query, strategy); + GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); + IP4R *query = (IP4R *) PG_GETARG_POINTER(1); + StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); + bool *recheck = (bool *) PG_GETARG_POINTER(4); + IP4R *key = (IP4R *) DatumGetPointer(entry->key); + bool retval; + + /* recheck is never needed with this type */ + if (recheck) + *recheck = false; - PG_RETURN_BOOL(retval); + /* + * * if entry is not leaf, use gip4r_internal_consistent, * else use + * gip4r_leaf_consistent + */ + if (GIST_LEAF(entry)) + retval = gip4r_leaf_consistent(key, query, strategy); + else + retval = gip4r_internal_consistent(key, query, strategy); + + PG_RETURN_BOOL(retval); } /* @@ -1407,33 +1406,33 @@ Datum gip4r_union(PG_FUNCTION_ARGS) { - GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); - int *sizep = (int *) PG_GETARG_POINTER(1); - GISTENTRY *ent = GISTENTRYVEC(entryvec); - - int numranges, i; - IP4R *out = (IP4R *) palloc(sizeof(IP4R)); - IP4R *tmp; + GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); + int *sizep = (int *) PG_GETARG_POINTER(1); + GISTENTRY *ent = GISTENTRYVEC(entryvec); + + int numranges, i; + IP4R *out = (IP4R *) palloc(sizeof(IP4R)); + IP4R *tmp; #ifdef GIST_DEBUG - fprintf(stderr, "union\n"); + fprintf(stderr, "union\n"); #endif - numranges = GISTENTRYCOUNT(entryvec); - tmp = (IP4R *) DatumGetPointer(ent[0].key); - *sizep = sizeof(IP4R); - *out = *tmp; - - for (i = 1; i < numranges; i++) - { - tmp = (IP4R *) DatumGetPointer(ent[i].key); - if (tmp->lower < out->lower) - out->lower = tmp->lower; - if (tmp->upper > out->upper) - out->upper = tmp->upper; - } + numranges = GISTENTRYCOUNT(entryvec); + tmp = (IP4R *) DatumGetPointer(ent[0].key); + *sizep = sizeof(IP4R); + *out = *tmp; - PG_RETURN_IP4R_P(out); + for (i = 1; i < numranges; i++) + { + tmp = (IP4R *) DatumGetPointer(ent[i].key); + if (tmp->lower < out->lower) + out->lower = tmp->lower; + if (tmp->upper > out->upper) + out->upper = tmp->upper; + } + + PG_RETURN_IP4R_P(out); } /* @@ -1444,21 +1443,21 @@ Datum gip4r_compress(PG_FUNCTION_ARGS) { - PG_RETURN_POINTER(PG_GETARG_POINTER(0)); + PG_RETURN_POINTER(PG_GETARG_POINTER(0)); } PG_FUNCTION_INFO_V1(gip4r_decompress); Datum gip4r_decompress(PG_FUNCTION_ARGS) { - PG_RETURN_POINTER(PG_GETARG_POINTER(0)); + PG_RETURN_POINTER(PG_GETARG_POINTER(0)); } PG_FUNCTION_INFO_V1(gip4r_fetch); Datum gip4r_fetch(PG_FUNCTION_ARGS) { - PG_RETURN_POINTER(PG_GETARG_POINTER(0)); + PG_RETURN_POINTER(PG_GETARG_POINTER(0)); } /* @@ -1469,32 +1468,32 @@ Datum gip4r_penalty(PG_FUNCTION_ARGS) { - GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); - GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1); - float *result = (float *) PG_GETARG_POINTER(2); - IP4R *key; - IP4R ud; - float tmp1, tmp2; - - key = (IP4R *) DatumGetPointer(origentry->key); - ud = *key; - tmp2 = ip4r_metric(&ud); - - key = (IP4R *) DatumGetPointer(newentry->key); - if (key->lower < ud.lower) - ud.lower = key->lower; - if (key->upper > ud.upper) - ud.upper = key->upper; - tmp1 = ip4r_metric(&ud); + GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); + GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1); + float *result = (float *) PG_GETARG_POINTER(2); + IP4R *key; + IP4R ud; + float tmp1, tmp2; + + key = (IP4R *) DatumGetPointer(origentry->key); + ud = *key; + tmp2 = ip4r_metric(&ud); + + key = (IP4R *) DatumGetPointer(newentry->key); + if (key->lower < ud.lower) + ud.lower = key->lower; + if (key->upper > ud.upper) + ud.upper = key->upper; + tmp1 = ip4r_metric(&ud); - *result = tmp1 - tmp2; + *result = tmp1 - tmp2; #ifdef GIST_DEBUG - fprintf(stderr, "penalty\n"); - fprintf(stderr, "\t%g\n", *result); + fprintf(stderr, "penalty\n"); + fprintf(stderr, "\t%g\n", *result); #endif - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(result); } @@ -1504,16 +1503,16 @@ struct gip4r_sort { - IP4R *key; - OffsetNumber pos; + IP4R *key; + OffsetNumber pos; }; static int gip4r_sort_compare(const void *a, const void *b) { - double sa = ip4r_metric(((struct gip4r_sort *)a)->key); - double sb = ip4r_metric(((struct gip4r_sort *)b)->key); - return (sa > sb) ? 1 : ((sa == sb) ? 0 : -1); + double sa = ip4r_metric(((struct gip4r_sort *)a)->key); + double sb = ip4r_metric(((struct gip4r_sort *)b)->key); + return (sa > sb) ? 1 : ((sa == sb) ? 0 : -1); } /* @@ -1526,130 +1525,130 @@ Datum gip4r_picksplit(PG_FUNCTION_ARGS) { - GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); - GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1); - GISTENTRY *ent = GISTENTRYVEC(entryvec); - OffsetNumber i; - int nbytes; - OffsetNumber maxoff; - OffsetNumber *listL; - OffsetNumber *listR; - bool allisequal = true; - IP4R pageunion; - IP4R *cur; - IP4R *unionL; - IP4R *unionR; - int posL = 0; - int posR = 0; - - posL = posR = 0; - maxoff = GISTENTRYCOUNT(entryvec) - 1; - - cur = (IP4R *) DatumGetPointer(ent[FirstOffsetNumber].key); - pageunion = *cur; - - /* find MBR */ - for (i = OffsetNumberNext(FirstOffsetNumber); i <= maxoff; i = OffsetNumberNext(i)) - { - cur = (IP4R *) DatumGetPointer(ent[i].key); - if (allisequal == true - && (pageunion.lower != cur->lower || pageunion.upper != cur->upper)) - allisequal = false; - - if (cur->lower < pageunion.lower) - pageunion.lower = cur->lower; - if (cur->upper > pageunion.upper) - pageunion.upper = cur->upper; - } - - nbytes = (maxoff + 2) * sizeof(OffsetNumber); - listL = (OffsetNumber *) palloc(nbytes); - listR = (OffsetNumber *) palloc(nbytes); - unionL = (IP4R *) palloc(sizeof(IP4R)); - unionR = (IP4R *) palloc(sizeof(IP4R)); - v->spl_ldatum = PointerGetDatum(unionL); - v->spl_rdatum = PointerGetDatum(unionR); - v->spl_left = listL; - v->spl_right = listR; - - if (allisequal) - { - cur = (IP4R *) DatumGetPointer(ent[OffsetNumberNext(FirstOffsetNumber)].key); - if (ip4r_equal(cur, &pageunion)) - { - OffsetNumber split_at = FirstOffsetNumber + (maxoff - FirstOffsetNumber + 1)/2; - v->spl_nleft = v->spl_nright = 0; - *unionL = pageunion; - *unionR = pageunion; - - for (i = FirstOffsetNumber; i < split_at; i = OffsetNumberNext(i)) - v->spl_left[v->spl_nleft++] = i; - for (; i <= maxoff; i = OffsetNumberNext(i)) - v->spl_right[v->spl_nright++] = i; - - PG_RETURN_POINTER(v); - } - } + GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); + GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1); + GISTENTRY *ent = GISTENTRYVEC(entryvec); + OffsetNumber i; + int nbytes; + OffsetNumber maxoff; + OffsetNumber *listL; + OffsetNumber *listR; + bool allisequal = true; + IP4R pageunion; + IP4R *cur; + IP4R *unionL; + IP4R *unionR; + int posL = 0; + int posR = 0; + + posL = posR = 0; + maxoff = GISTENTRYCOUNT(entryvec) - 1; + + cur = (IP4R *) DatumGetPointer(ent[FirstOffsetNumber].key); + pageunion = *cur; + + /* find MBR */ + for (i = OffsetNumberNext(FirstOffsetNumber); i <= maxoff; i = OffsetNumberNext(i)) + { + cur = (IP4R *) DatumGetPointer(ent[i].key); + if (allisequal == true + && (pageunion.lower != cur->lower || pageunion.upper != cur->upper)) + allisequal = false; + + if (cur->lower < pageunion.lower) + pageunion.lower = cur->lower; + if (cur->upper > pageunion.upper) + pageunion.upper = cur->upper; + } + + nbytes = (maxoff + 2) * sizeof(OffsetNumber); + listL = (OffsetNumber *) palloc(nbytes); + listR = (OffsetNumber *) palloc(nbytes); + unionL = (IP4R *) palloc(sizeof(IP4R)); + unionR = (IP4R *) palloc(sizeof(IP4R)); + v->spl_ldatum = PointerGetDatum(unionL); + v->spl_rdatum = PointerGetDatum(unionR); + v->spl_left = listL; + v->spl_right = listR; + + if (allisequal) + { + cur = (IP4R *) DatumGetPointer(ent[OffsetNumberNext(FirstOffsetNumber)].key); + if (ip4r_equal(cur, &pageunion)) + { + OffsetNumber split_at = FirstOffsetNumber + (maxoff - FirstOffsetNumber + 1)/2; + v->spl_nleft = v->spl_nright = 0; + *unionL = pageunion; + *unionR = pageunion; + + for (i = FirstOffsetNumber; i < split_at; i = OffsetNumberNext(i)) + v->spl_left[v->spl_nleft++] = i; + for (; i <= maxoff; i = OffsetNumberNext(i)) + v->spl_right[v->spl_nright++] = i; + + PG_RETURN_POINTER(v); + } + } #define ADDLIST( list_, u_, pos_, num_ ) do { \ - if ( pos_ ) { \ - if ( (u_)->upper < (cur)->upper ) (u_)->upper = (cur)->upper; \ - if ( (u_)->lower > (cur)->lower ) (u_)->lower = (cur)->lower; \ - } else { \ - *(u_) = *(cur); \ - } \ - (list_)[(pos_)++] = (num_); \ + if ( pos_ ) { \ + if ( (u_)->upper < (cur)->upper ) (u_)->upper = (cur)->upper; \ + if ( (u_)->lower > (cur)->lower ) (u_)->lower = (cur)->lower; \ + } else { \ + *(u_) = *(cur); \ + } \ + (list_)[(pos_)++] = (num_); \ } while(0) - for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) - { - cur = (IP4R *) DatumGetPointer(ent[i].key); - if (cur->lower - pageunion.lower < pageunion.upper - cur->upper) - ADDLIST(listL, unionL, posL, i); - else - ADDLIST(listR, unionR, posR, i); - } - - /* bad disposition, sort by ascending size and resplit */ - if (posR == 0 || posL == 0) - { - struct gip4r_sort *arr = (struct gip4r_sort *) - palloc(sizeof(struct gip4r_sort) * (maxoff + FirstOffsetNumber)); - - for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) - { - arr[i].key = (IP4R *) DatumGetPointer(ent[i].key); - arr[i].pos = i; - } - - qsort(arr + FirstOffsetNumber, - maxoff - FirstOffsetNumber + 1, - sizeof(struct gip4r_sort), - gip4r_sort_compare); - - posL = posR = 0; - for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) - { - cur = arr[i].key; - if (cur->lower - pageunion.lower < pageunion.upper - cur->upper) - ADDLIST(listL, unionL, posL, arr[i].pos); - else if (cur->lower - pageunion.lower == pageunion.upper - cur->upper) - { - if (posL > posR) - ADDLIST(listR, unionR, posR, arr[i].pos); - else - ADDLIST(listL, unionL, posL, arr[i].pos); - } - else - ADDLIST(listR, unionR, posR, arr[i].pos); - } - pfree(arr); - } + for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) + { + cur = (IP4R *) DatumGetPointer(ent[i].key); + if (cur->lower - pageunion.lower < pageunion.upper - cur->upper) + ADDLIST(listL, unionL, posL, i); + else + ADDLIST(listR, unionR, posR, i); + } + + /* bad disposition, sort by ascending size and resplit */ + if (posR == 0 || posL == 0) + { + struct gip4r_sort *arr = (struct gip4r_sort *) + palloc(sizeof(struct gip4r_sort) * (maxoff + FirstOffsetNumber)); + + for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) + { + arr[i].key = (IP4R *) DatumGetPointer(ent[i].key); + arr[i].pos = i; + } + + qsort(arr + FirstOffsetNumber, + maxoff - FirstOffsetNumber + 1, + sizeof(struct gip4r_sort), + gip4r_sort_compare); - v->spl_nleft = posL; - v->spl_nright = posR; + posL = posR = 0; + for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) + { + cur = arr[i].key; + if (cur->lower - pageunion.lower < pageunion.upper - cur->upper) + ADDLIST(listL, unionL, posL, arr[i].pos); + else if (cur->lower - pageunion.lower == pageunion.upper - cur->upper) + { + if (posL > posR) + ADDLIST(listR, unionR, posR, arr[i].pos); + else + ADDLIST(listL, unionL, posL, arr[i].pos); + } + else + ADDLIST(listR, unionR, posR, arr[i].pos); + } + pfree(arr); + } - PG_RETURN_POINTER(v); + v->spl_nleft = posL; + v->spl_nright = posR; + + PG_RETURN_POINTER(v); } #undef ADDLIST @@ -1661,31 +1660,31 @@ Datum gip4r_same(PG_FUNCTION_ARGS) { - IP4R *v1 = (IP4R *) PG_GETARG_POINTER(0); - IP4R *v2 = (IP4R *) PG_GETARG_POINTER(1); - bool *result = (bool *) PG_GETARG_POINTER(2); - - if (v1 && v2) - *result = ip4r_equal(v1,v2); - else - *result = (v1 == NULL && v2 == NULL); + IP4R *v1 = (IP4R *) PG_GETARG_POINTER(0); + IP4R *v2 = (IP4R *) PG_GETARG_POINTER(1); + bool *result = (bool *) PG_GETARG_POINTER(2); + + if (v1 && v2) + *result = ip4r_equal(v1,v2); + else + *result = (v1 == NULL && v2 == NULL); #ifdef GIST_DEBUG - fprintf(stderr, "same: %s\n", (*result ? "true" : "false")); + fprintf(stderr, "same: %s\n", (*result ? "true" : "false")); #endif - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(result); } /* * Strategy numbers: - * OPERATOR 1 >>= , - * OPERATOR 2 <<= , - * OPERATOR 3 >> , - * OPERATOR 4 << , - * OPERATOR 5 && , - * OPERATOR 6 = , + * OPERATOR 1 >>= , + * OPERATOR 2 <<= , + * OPERATOR 3 >> , + * OPERATOR 4 << , + * OPERATOR 5 && , + * OPERATOR 6 = , */ /* @@ -1693,30 +1692,30 @@ */ static bool gip4r_leaf_consistent(IP4R * key, - IP4R * query, - StrategyNumber strategy) + IP4R * query, + StrategyNumber strategy) { #ifdef GIST_QUERY_DEBUG - fprintf(stderr, "leaf_consistent, %d\n", strategy); + fprintf(stderr, "leaf_consistent, %d\n", strategy); #endif - switch (strategy) - { - case 1: /* left contains right nonstrict */ - return ip4r_contains_internal(key, query, true); - case 2: /* left contained in right nonstrict */ - return ip4r_contains_internal(query, key, true); - case 3: /* left contains right strict */ - return ip4r_contains_internal(key, query, false); - case 4: /* left contained in right strict */ - return ip4r_contains_internal(query, key, false); - case 5: /* left overlaps right */ - return ip4r_overlaps_internal(key, query); - case 6: /* left equal right */ - return ip4r_equal(key, query); - default: - return false; - } + switch (strategy) + { + case 1: /* left contains right nonstrict */ + return ip4r_contains_internal(key, query, true); + case 2: /* left contained in right nonstrict */ + return ip4r_contains_internal(query, key, true); + case 3: /* left contains right strict */ + return ip4r_contains_internal(key, query, false); + case 4: /* left contained in right strict */ + return ip4r_contains_internal(query, key, false); + case 5: /* left overlaps right */ + return ip4r_overlaps_internal(key, query); + case 6: /* left equal right */ + return ip4r_equal(key, query); + default: + return false; + } } /* logic notes: @@ -1733,27 +1732,27 @@ bool gip4r_internal_consistent(IP4R * key, - IP4R * query, - StrategyNumber strategy) + IP4R * query, + StrategyNumber strategy) { #ifdef GIST_QUERY_DEBUG - fprintf(stderr, "internal_consistent, %d\n", strategy); + fprintf(stderr, "internal_consistent, %d\n", strategy); #endif - switch (strategy) - { - case 2: /* left contained in right nonstrict */ - case 4: /* left contained in right strict */ - case 5: /* left overlaps right */ - return ip4r_overlaps_internal(key, query); - case 3: /* left contains right strict */ - return ip4r_contains_internal(key, query, false); - case 1: /* left contains right nonstrict */ - case 6: /* left equal right */ - return ip4r_contains_internal(key, query, true); - default: - return false; - } + switch (strategy) + { + case 2: /* left contained in right nonstrict */ + case 4: /* left contained in right strict */ + case 5: /* left overlaps right */ + return ip4r_overlaps_internal(key, query); + case 3: /* left contains right strict */ + return ip4r_contains_internal(key, query, false); + case 1: /* left contains right nonstrict */ + case 6: /* left equal right */ + return ip4r_contains_internal(key, query, true); + default: + return false; + } } /* end */ diff -Nru ip4r-2.4.1/src/ip4r_funcs.h ip4r-2.4.2/src/ip4r_funcs.h --- ip4r-2.4.1/src/ip4r_funcs.h 2019-05-22 02:04:18.000000000 +0000 +++ ip4r-2.4.2/src/ip4r_funcs.h 2023-07-29 17:52:21.000000000 +0000 @@ -3,13 +3,13 @@ static inline uint32 hostmask(unsigned masklen) { - return (masklen) ? ( (((uint32)(1U)) << (32-masklen)) - 1U ) : 0xFFFFFFFFU; + return (masklen) ? ( (((uint32)(1U)) << (32-masklen)) - 1U ) : 0xFFFFFFFFU; } static inline uint32 netmask(unsigned masklen) { - return ~hostmask(masklen); + return ~hostmask(masklen); } /* if LO and HI are ends of a CIDR prefix, return the mask length. @@ -19,74 +19,74 @@ static inline unsigned masklen(uint32 lo, uint32 hi) { - uint32 d = (lo ^ hi) + 1; - /* at this point, d can be: - * 0 if A and B have all bits different - * 1 if A and B are equal - * 1 << (32-masklen) - * some other value if A and B are not ends of a CIDR range - * but in any case, after extracting the masklen, we have to - * recheck because some non-CIDR ranges will produce the same - * results. - */ - int fbit = ffs(d); - switch (fbit) - { - case 0: return (lo == 0 && hi == ~0) ? 0 : ~0; - case 1: return (lo == hi) ? 32 : ~0; - default: - if ( ((uint32)(1U) << (fbit-1)) == d ) - { - uint32 mask = hostmask(33-fbit); - if ((lo & mask) == 0 && (hi & mask) == mask) - return 33-fbit; - } - return ~0; - } + uint32 d = (lo ^ hi) + 1; + /* at this point, d can be: + * 0 if A and B have all bits different + * 1 if A and B are equal + * 1 << (32-masklen) + * some other value if A and B are not ends of a CIDR range + * but in any case, after extracting the masklen, we have to + * recheck because some non-CIDR ranges will produce the same + * results. + */ + int fbit = ffs(d); + switch (fbit) + { + case 0: return (lo == 0 && hi == ~0) ? 0 : ~0; + case 1: return (lo == hi) ? 32 : ~0; + default: + if ( ((uint32)(1U) << (fbit-1)) == d ) + { + uint32 mask = hostmask(33-fbit); + if ((lo & mask) == 0 && (hi & mask) == mask) + return 33-fbit; + } + return ~0; + } } static inline bool ip4_valid_netmask(uint32 mask) { - uint32 d = ~mask + 1; - /* at this point, d can be: - * 0 if mask was 0x00000000 (valid) - * 1 << (32-masklen) (valid) - * some other value (invalid) - */ - int fbit = ffs(d); - switch (fbit) - { - case 0: - return true; - default: - return ( ((uint32)(1U) << (fbit-1)) == d ); - } + uint32 d = ~mask + 1; + /* at this point, d can be: + * 0 if mask was 0x00000000 (valid) + * 1 << (32-masklen) (valid) + * some other value (invalid) + */ + int fbit = ffs(d); + switch (fbit) + { + case 0: + return true; + default: + return ( ((uint32)(1U) << (fbit-1)) == d ); + } } static inline bool ip4r_from_cidr(IP4 prefix, unsigned masklen, IP4R *ipr) { - uint32 mask = hostmask(masklen); - if (masklen > 32) - return false; - if (prefix & mask) - return false; - ipr->lower = prefix; - ipr->upper = prefix | mask; - return true; + uint32 mask = hostmask(masklen); + if (masklen > 32) + return false; + if (prefix & mask) + return false; + ipr->lower = prefix; + ipr->upper = prefix | mask; + return true; } static inline bool ip4r_from_inet(IP4 addr, unsigned masklen, IP4R *ipr) { - uint32 mask = hostmask(masklen); - if (masklen > 32) - return false; - ipr->lower = addr & ~mask; - ipr->upper = addr | mask; - return true; + uint32 mask = hostmask(masklen); + if (masklen > 32) + return false; + ipr->lower = addr & ~mask; + ipr->upper = addr | mask; + return true; } static inline @@ -107,9 +107,9 @@ * We know that all these cases are impossible because the CIDR check * would catch them: * - * lo==hi - * lo==0 && hi==~0 - * lo==~0 + * lo==hi + * lo==0 && hi==~0 + * lo==~0 * * Therefore this loop must terminate before the mask overflows */ @@ -128,19 +128,19 @@ static inline bool ip4_equal(IP4 a, IP4 b) { - return (a == b); + return (a == b); } static inline bool ip4_lessthan(IP4 a, IP4 b) { - return (a < b); + return (a < b); } static inline bool ip4_less_eq(IP4 a, IP4 b) { - return (a <= b); + return (a <= b); } /* helpers for union/intersection for indexing */ @@ -148,105 +148,105 @@ static inline IP4R *ip4r_union_internal(IP4R *a, IP4R *b, IP4R *result) { - if (a->lower < b->lower) - result->lower = a->lower; - else - result->lower = b->lower; - - if (a->upper > b->upper) - result->upper = a->upper; - else - result->upper = b->upper; + if (a->lower < b->lower) + result->lower = a->lower; + else + result->lower = b->lower; + + if (a->upper > b->upper) + result->upper = a->upper; + else + result->upper = b->upper; - return result; + return result; } static inline IP4R *ip4r_inter_internal(IP4R *a, IP4R *b, IP4R *result) { - if (a->upper < b->lower || a->lower > b->upper) - { - /* disjoint */ - result->lower = 1; - result->upper = 0; /* INVALID VALUE */ - return NULL; - } - - if (a->upper < b->upper) - result->upper = a->upper; - else - result->upper = b->upper; - - if (a->lower > b->lower) - result->lower = a->lower; - else - result->lower = b->lower; + if (a->upper < b->lower || a->lower > b->upper) + { + /* disjoint */ + result->lower = 1; + result->upper = 0; /* INVALID VALUE */ + return NULL; + } + + if (a->upper < b->upper) + result->upper = a->upper; + else + result->upper = b->upper; + + if (a->lower > b->lower) + result->lower = a->lower; + else + result->lower = b->lower; - return result; + return result; } static inline double ip4r_metric(IP4R *v) { - if (!v) - return 0.0; - return ((v->upper - v->lower) + 1.0); + if (!v) + return 0.0; + return ((v->upper - v->lower) + 1.0); } static inline bool ip4r_equal(IP4R *a, IP4R *b) { - return (a->lower == b->lower && a->upper == b->upper); + return (a->lower == b->lower && a->upper == b->upper); } static inline bool ip4r_lessthan(IP4R *a, IP4R *b) { - return (a->lower == b->lower) ? (a->upper < b->upper) : (a->lower < b->lower); + return (a->lower == b->lower) ? (a->upper < b->upper) : (a->lower < b->lower); } static inline bool ip4r_less_eq(IP4R *a, IP4R *b) { - return (a->lower == b->lower) ? (a->upper <= b->upper) : (a->lower < b->lower); + return (a->lower == b->lower) ? (a->upper <= b->upper) : (a->lower < b->lower); } static inline bool ip4r_contains_internal(IP4R *left, IP4R *right, bool eqval) { - if (ip4r_equal(left,right)) - return eqval; - return ((left->lower <= right->lower) && (left->upper >= right->upper)); + if (ip4r_equal(left,right)) + return eqval; + return ((left->lower <= right->lower) && (left->upper >= right->upper)); } static inline bool ip4r_overlaps_internal(IP4R *left, IP4R *right) { - return (left->upper >= right->lower && left->lower <= right->upper); + return (left->upper >= right->lower && left->lower <= right->upper); } static inline bool ip4_contains_internal(IP4R *left, IP4 right) { - return (left->lower <= right && left->upper >= right); + return (left->lower <= right && left->upper >= right); } static inline bool ip4r_left_internal(IP4R *left, IP4R *right) { - return (left->upper < right->lower); + return (left->upper < right->lower); } static inline bool ip4r_extends_left_of_internal(IP4R *left, IP4R *right) { - return (left->lower < right->lower); + return (left->lower < right->lower); } static inline bool ip4r_extends_right_of_internal(IP4R *left, IP4R *right) { - return (left->upper > right->upper); + return (left->upper > right->upper); } /* end */ diff -Nru ip4r-2.4.1/src/ip6r.c ip4r-2.4.2/src/ip6r.c --- ip4r-2.4.1/src/ip6r.c 2019-05-22 02:04:18.000000000 +0000 +++ ip4r-2.4.2/src/ip6r.c 2023-07-29 17:52:21.000000000 +0000 @@ -26,66 +26,66 @@ static bool ip6r_from_str(char *str, IP6R *ipr) { - char buf[IP6_STRING_MAX]; - int pos = strcspn(str, "-/"); - IP6 ip; - - switch (str[pos]) - { - case 0: /* no separator, must be single ip6 addr */ - { - if (!ip6_raw_input(str, ip.bits)) - return false; - ipr->lower = ip; - ipr->upper = ip; - return true; - } - - case '-': /* lower-upper */ - { - char *rest = str + pos + 1; - - if (pos > sizeof(buf)-2) - return false; - memcpy(buf, str, pos); - buf[pos] = 0; - if (!ip6_raw_input(buf, ip.bits)) - return false; - ipr->lower = ip; - if (!ip6_raw_input(rest, ip.bits)) - return false; - if (!ip6_lessthan(&ip, &ipr->lower)) - ipr->upper = ip; - else - { - ipr->upper = ipr->lower; - ipr->lower = ip; - } - return true; - } - - case '/': /* prefix/len */ - { - char *rest = str + pos + 1; - unsigned pfxlen; - char dummy; - - if (pos > sizeof(buf)-2) - return false; - memcpy(buf, str, pos); - buf[pos] = 0; - if (!ip6_raw_input(buf, ip.bits)) - return false; - if (rest[strspn(rest,"0123456789")]) - return false; - if (sscanf(rest, "%u%c", &pfxlen, &dummy) != 1) - return false; - return ip6r_from_cidr(&ip, pfxlen, ipr); - } - - default: - return false; /* can't happen */ - } + char buf[IP6_STRING_MAX]; + int pos = strcspn(str, "-/"); + IP6 ip; + + switch (str[pos]) + { + case 0: /* no separator, must be single ip6 addr */ + { + if (!ip6_raw_input(str, ip.bits)) + return false; + ipr->lower = ip; + ipr->upper = ip; + return true; + } + + case '-': /* lower-upper */ + { + char *rest = str + pos + 1; + + if (pos > sizeof(buf)-2) + return false; + memcpy(buf, str, pos); + buf[pos] = 0; + if (!ip6_raw_input(buf, ip.bits)) + return false; + ipr->lower = ip; + if (!ip6_raw_input(rest, ip.bits)) + return false; + if (!ip6_lessthan(&ip, &ipr->lower)) + ipr->upper = ip; + else + { + ipr->upper = ipr->lower; + ipr->lower = ip; + } + return true; + } + + case '/': /* prefix/len */ + { + char *rest = str + pos + 1; + unsigned pfxlen; + char dummy; + + if (pos > sizeof(buf)-2) + return false; + memcpy(buf, str, pos); + buf[pos] = 0; + if (!ip6_raw_input(buf, ip.bits)) + return false; + if (rest[strspn(rest,"0123456789")]) + return false; + if (sscanf(rest, "%u%c", &pfxlen, &dummy) != 1) + return false; + return ip6r_from_cidr(&ip, pfxlen, ipr); + } + + default: + return false; /* can't happen */ + } } @@ -94,23 +94,23 @@ static int ip6r_to_str(IP6R *ipr, char *str, int slen) { - char buf1[IP6_STRING_MAX]; - char buf2[IP6_STRING_MAX]; - unsigned msk; - - if (ip6_equal(&ipr->lower, &ipr->upper)) - return ip6_raw_output(ipr->lower.bits, str, slen); - - if ((msk = masklen6(&ipr->lower,&ipr->upper)) <= 128) - { - ip6_raw_output(ipr->lower.bits, buf1, sizeof(buf1)); - return snprintf(str, slen, "%s/%u", buf1, msk); - } + char buf1[IP6_STRING_MAX]; + char buf2[IP6_STRING_MAX]; + unsigned msk; - ip6_raw_output(ipr->lower.bits, buf1, sizeof(buf1)); - ip6_raw_output(ipr->upper.bits, buf2, sizeof(buf2)); + if (ip6_equal(&ipr->lower, &ipr->upper)) + return ip6_raw_output(ipr->lower.bits, str, slen); - return snprintf(str, slen, "%s-%s", buf1, buf2); + if ((msk = masklen6(&ipr->lower,&ipr->upper)) <= 128) + { + ip6_raw_output(ipr->lower.bits, buf1, sizeof(buf1)); + return snprintf(str, slen, "%s/%u", buf1, msk); + } + + ip6_raw_output(ipr->lower.bits, buf1, sizeof(buf1)); + ip6_raw_output(ipr->upper.bits, buf2, sizeof(buf2)); + + return snprintf(str, slen, "%s-%s", buf1, buf2); } @@ -131,16 +131,16 @@ text * make_text(int len) { - text *ret = (text *) palloc0(len + VARHDRSZ); - SET_VARSIZE(ret, len + VARHDRSZ); - return ret; + text *ret = (text *) palloc0(len + VARHDRSZ); + SET_VARSIZE(ret, len + VARHDRSZ); + return ret; } static inline void set_text_len(text *txt, int len) { - Assert(len >= 0 && len + VARHDRSZ <= VARSIZE(txt)); + Assert(len >= 0 && len + VARHDRSZ <= VARSIZE(txt)); if (len + VARHDRSZ <= VARSIZE(txt)) SET_VARSIZE(txt, len + VARHDRSZ); } @@ -153,143 +153,140 @@ Datum ip6_in(PG_FUNCTION_ARGS) { - char *str = PG_GETARG_CSTRING(0); - IP6 *ip = palloc(sizeof(IP6)); - if (ip6_raw_input(str, ip->bits)) - PG_RETURN_IP6_P(ip); - - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid IP6 value: '%s'", str))); - PG_RETURN_NULL(); + char *str = PG_GETARG_CSTRING(0); + IP6 *ip = palloc(sizeof(IP6)); + if (ip6_raw_input(str, ip->bits)) + PG_RETURN_IP6_P(ip); + + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid IP6 value: '%s'", str))); } PG_FUNCTION_INFO_V1(ip6_out); Datum ip6_out(PG_FUNCTION_ARGS) { - IP6 *ip = PG_GETARG_IP6_P(0); - char *out = palloc(IP6_STRING_MAX); - ip6_raw_output(ip->bits, out, IP6_STRING_MAX); - PG_RETURN_CSTRING(out); + IP6 *ip = PG_GETARG_IP6_P(0); + char *out = palloc(IP6_STRING_MAX); + ip6_raw_output(ip->bits, out, IP6_STRING_MAX); + PG_RETURN_CSTRING(out); } PG_FUNCTION_INFO_V1(ip6_recv); Datum ip6_recv(PG_FUNCTION_ARGS) { - StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); - IP6 *ip = palloc(sizeof(IP6)); + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); + IP6 *ip = palloc(sizeof(IP6)); - ip->bits[0] = pq_getmsgint64(buf); - ip->bits[1] = pq_getmsgint64(buf); + ip->bits[0] = pq_getmsgint64(buf); + ip->bits[1] = pq_getmsgint64(buf); - PG_RETURN_IP6_P(ip); + PG_RETURN_IP6_P(ip); } PG_FUNCTION_INFO_V1(ip6_send); Datum ip6_send(PG_FUNCTION_ARGS) { - IP6 *arg1 = PG_GETARG_IP6_P(0); - StringInfoData buf; + IP6 *arg1 = PG_GETARG_IP6_P(0); + StringInfoData buf; - pq_begintypsend(&buf); - pq_sendint64(&buf, arg1->bits[0]); - pq_sendint64(&buf, arg1->bits[1]); - PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); + pq_begintypsend(&buf); + pq_sendint64(&buf, arg1->bits[0]); + pq_sendint64(&buf, arg1->bits[1]); + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); } PG_FUNCTION_INFO_V1(ip6hash); Datum ip6hash(PG_FUNCTION_ARGS) { - IP6 *arg1 = PG_GETARG_IP6_P(0); + IP6 *arg1 = PG_GETARG_IP6_P(0); - return hash_any((unsigned char *)arg1, sizeof(IP6)); + return hash_any((unsigned char *)arg1, sizeof(IP6)); } PG_FUNCTION_INFO_V1(ip6_hash_extended); Datum ip6_hash_extended(PG_FUNCTION_ARGS) { - IP6 *arg1 = PG_GETARG_IP6_P(0); + IP6 *arg1 = PG_GETARG_IP6_P(0); uint64 seed = DatumGetUInt64(PG_GETARG_DATUM(1)); - return hash_any_extended((unsigned char *)arg1, sizeof(IP6), seed); + return hash_any_extended((unsigned char *)arg1, sizeof(IP6), seed); } PG_FUNCTION_INFO_V1(ip6_cast_to_text); Datum ip6_cast_to_text(PG_FUNCTION_ARGS) { - IP6 *ip = PG_GETARG_IP6_P(0); - text *out = make_text(IP6_STRING_MAX); - set_text_len(out, ip6_raw_output(ip->bits, VARDATA(out), IP6_STRING_MAX)); - PG_RETURN_TEXT_P(out); + IP6 *ip = PG_GETARG_IP6_P(0); + text *out = make_text(IP6_STRING_MAX); + set_text_len(out, ip6_raw_output(ip->bits, VARDATA(out), IP6_STRING_MAX)); + PG_RETURN_TEXT_P(out); } PG_FUNCTION_INFO_V1(ip6_cast_from_text); Datum ip6_cast_from_text(PG_FUNCTION_ARGS) { - text *txt = PG_GETARG_TEXT_PP(0); - int tlen = VARSIZE_ANY_EXHDR(txt); - char buf[IP6_STRING_MAX]; - - if (tlen < sizeof(buf)) - { - IP6 *ip = palloc(sizeof(IP6)); - - memcpy(buf, VARDATA_ANY(txt), tlen); - buf[tlen] = 0; - if (ip6_raw_input(buf, ip->bits)) - PG_RETURN_IP6_P(ip); - } - - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid IP6 value in text"))); - PG_RETURN_NULL(); + text *txt = PG_GETARG_TEXT_PP(0); + int tlen = VARSIZE_ANY_EXHDR(txt); + char buf[IP6_STRING_MAX]; + + if (tlen < sizeof(buf)) + { + IP6 *ip = palloc(sizeof(IP6)); + + memcpy(buf, VARDATA_ANY(txt), tlen); + buf[tlen] = 0; + if (ip6_raw_input(buf, ip->bits)) + PG_RETURN_IP6_P(ip); + } + + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid IP6 value in text"))); } PG_FUNCTION_INFO_V1(ip6_cast_from_inet); Datum ip6_cast_from_inet(PG_FUNCTION_ARGS) { - inet *inetptr = PG_GETARG_INET_P(0); - inet_struct *in = INET_STRUCT_DATA(inetptr); + inet *inetptr = PG_GETARG_INET_P(0); + inet_struct *in = INET_STRUCT_DATA(inetptr); - if (in->family == PGSQL_AF_INET6) - { - unsigned char *p = in->ipaddr; - IP6 *ip = palloc(sizeof(IP6)); + if (in->family == PGSQL_AF_INET6) + { + unsigned char *p = in->ipaddr; + IP6 *ip = palloc(sizeof(IP6)); ip6_deserialize(p, ip); - PG_RETURN_IP6_P(ip); - } + PG_RETURN_IP6_P(ip); + } - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid INET value for conversion to IP6"))); - PG_RETURN_NULL(); + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid INET value for conversion to IP6"))); } PG_FUNCTION_INFO_V1(ip6_cast_to_cidr); Datum ip6_cast_to_cidr(PG_FUNCTION_ARGS) { - IP6 *ip = PG_GETARG_IP6_P(0); - inet *res = palloc0(VARHDRSZ + sizeof(inet_struct)); - inet_struct *in; - - SET_VARSIZE(res, VARHDRSZ + offsetof(inet_struct, ipaddr) + 16); - - in = ((inet_struct *)VARDATA(res)); - in->bits = 128; - in->family = PGSQL_AF_INET6; + IP6 *ip = PG_GETARG_IP6_P(0); + inet *res = palloc0(VARHDRSZ + sizeof(inet_struct)); + inet_struct *in; + + SET_VARSIZE(res, VARHDRSZ + offsetof(inet_struct, ipaddr) + 16); + + in = ((inet_struct *)VARDATA(res)); + in->bits = 128; + in->family = PGSQL_AF_INET6; ip6_serialize(ip, in->ipaddr); - PG_RETURN_INET_P(res); + PG_RETURN_INET_P(res); } @@ -297,78 +294,77 @@ Datum ip6_cast_to_numeric(PG_FUNCTION_ARGS) { - IP6 *ip = PG_GETARG_IP6_P(0); - Datum res,tmp,mul; - static int64 mul_val = ((int64)1 << 56); - int64 tmp_val; - - mul = DirectFunctionCall1(int8_numeric,Int64GetDatumFast(mul_val)); - tmp_val = (ip->bits[0] >> 48); - res = DirectFunctionCall1(int8_numeric,Int64GetDatumFast(tmp_val)); - tmp_val = ((ip->bits[0] & (uint64)(0xFFFFFFFFFFFFULL)) << 8) | (ip->bits[1] >> 56); - tmp = DirectFunctionCall1(int8_numeric,Int64GetDatumFast(tmp_val)); - res = DirectFunctionCall2(numeric_mul,res,mul); - res = DirectFunctionCall2(numeric_add,res,tmp); - tmp_val = (ip->bits[1] & (uint64)(0xFFFFFFFFFFFFFFULL)); - tmp = DirectFunctionCall1(int8_numeric,Int64GetDatumFast(tmp_val)); - res = DirectFunctionCall2(numeric_mul,res,mul); - res = DirectFunctionCall2(numeric_add,res,tmp); + IP6 *ip = PG_GETARG_IP6_P(0); + Datum res,tmp,mul; + static int64 mul_val = ((int64)1 << 56); + int64 tmp_val; + + mul = DirectFunctionCall1(int8_numeric,Int64GetDatumFast(mul_val)); + tmp_val = (ip->bits[0] >> 48); + res = DirectFunctionCall1(int8_numeric,Int64GetDatumFast(tmp_val)); + tmp_val = ((ip->bits[0] & (uint64)(0xFFFFFFFFFFFFULL)) << 8) | (ip->bits[1] >> 56); + tmp = DirectFunctionCall1(int8_numeric,Int64GetDatumFast(tmp_val)); + res = DirectFunctionCall2(numeric_mul,res,mul); + res = DirectFunctionCall2(numeric_add,res,tmp); + tmp_val = (ip->bits[1] & (uint64)(0xFFFFFFFFFFFFFFULL)); + tmp = DirectFunctionCall1(int8_numeric,Int64GetDatumFast(tmp_val)); + res = DirectFunctionCall2(numeric_mul,res,mul); + res = DirectFunctionCall2(numeric_add,res,tmp); - PG_RETURN_DATUM(res); + PG_RETURN_DATUM(res); } PG_FUNCTION_INFO_V1(ip6_cast_from_numeric); Datum ip6_cast_from_numeric(PG_FUNCTION_ARGS) { - Datum val = NumericGetDatum(PG_GETARG_NUMERIC(0)); - Datum rem,tmp,div,mul; - static int64 mul_val = ((int64)1 << 56); - uint64 tmp_val; - IP6 *res; - - tmp = DirectFunctionCall1(numeric_floor,DirectFunctionCall1(numeric_abs,val)); - - if (!DatumGetBool(DirectFunctionCall2(numeric_eq,tmp,val))) - { - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid numeric value for conversion to IP6"))); - } - - res = palloc(sizeof(IP6)); - - /* we use div/mul here rather than mod because numeric_mod is implemented as - * a div/mul/subtract in any case, so we save a division step by doing the - * mul/subtract ourselves - */ - - mul = DirectFunctionCall1(int8_numeric,Int64GetDatumFast(mul_val)); - div = DirectFunctionCall2(numeric_div_trunc,val,mul); - tmp = DirectFunctionCall2(numeric_mul,div,mul); - rem = DirectFunctionCall2(numeric_sub,val,tmp); - res->bits[1] = (uint64)DatumGetInt64(DirectFunctionCall1(numeric_int8,rem)); - val = div; - div = DirectFunctionCall2(numeric_div_trunc,val,mul); - tmp = DirectFunctionCall2(numeric_mul,div,mul); - rem = DirectFunctionCall2(numeric_sub,val,tmp); - tmp_val = (uint64)DatumGetInt64(DirectFunctionCall1(numeric_int8,rem)); - res->bits[1] |= ((tmp_val & 0xFF) << 56); - res->bits[0] = (tmp_val >> 8); - if (!DatumGetBool(DirectFunctionCall2(numeric_gt,div,mul))) - { - tmp_val = (uint64)DatumGetInt64(DirectFunctionCall1(numeric_int8,div)); - if (tmp_val <= (uint64)0xFFFFU) - { - res->bits[0] |= (tmp_val << 48); - PG_RETURN_IP6_P(res); - } - } - - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("numeric value too large for conversion to IP6"))); - PG_RETURN_NULL(); + Datum val = NumericGetDatum(PG_GETARG_NUMERIC(0)); + Datum rem,tmp,div,mul; + static int64 mul_val = ((int64)1 << 56); + uint64 tmp_val; + IP6 *res; + + tmp = DirectFunctionCall1(numeric_floor,DirectFunctionCall1(numeric_abs,val)); + + if (!DatumGetBool(DirectFunctionCall2(numeric_eq,tmp,val))) + { + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid numeric value for conversion to IP6"))); + } + + res = palloc(sizeof(IP6)); + + /* we use div/mul here rather than mod because numeric_mod is implemented as + * a div/mul/subtract in any case, so we save a division step by doing the + * mul/subtract ourselves + */ + + mul = DirectFunctionCall1(int8_numeric,Int64GetDatumFast(mul_val)); + div = DirectFunctionCall2(numeric_div_trunc,val,mul); + tmp = DirectFunctionCall2(numeric_mul,div,mul); + rem = DirectFunctionCall2(numeric_sub,val,tmp); + res->bits[1] = (uint64)DatumGetInt64(DirectFunctionCall1(numeric_int8,rem)); + val = div; + div = DirectFunctionCall2(numeric_div_trunc,val,mul); + tmp = DirectFunctionCall2(numeric_mul,div,mul); + rem = DirectFunctionCall2(numeric_sub,val,tmp); + tmp_val = (uint64)DatumGetInt64(DirectFunctionCall1(numeric_int8,rem)); + res->bits[1] |= ((tmp_val & 0xFF) << 56); + res->bits[0] = (tmp_val >> 8); + if (!DatumGetBool(DirectFunctionCall2(numeric_gt,div,mul))) + { + tmp_val = (uint64)DatumGetInt64(DirectFunctionCall1(numeric_int8,div)); + if (tmp_val <= (uint64)0xFFFFU) + { + res->bits[0] |= (tmp_val << 48); + PG_RETURN_IP6_P(res); + } + } + + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("numeric value too large for conversion to IP6"))); } PG_FUNCTION_INFO_V1(ip6_cast_from_bit); @@ -379,16 +375,15 @@ if (VARBITLEN(val) == 128) { - bits8 *p = VARBITS(val); + bits8 *p = VARBITS(val); IP6 *res = palloc(sizeof(IP6)); ip6_deserialize(p, res); - PG_RETURN_IP6_P(res); + PG_RETURN_IP6_P(res); } - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid BIT value for conversion to IP6"))); - PG_RETURN_NULL(); + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid BIT value for conversion to IP6"))); } PG_FUNCTION_INFO_V1(ip6_cast_to_bit); @@ -416,16 +411,15 @@ if (VARSIZE_ANY_EXHDR(val) == 16) { - void *p = VARDATA_ANY(val); + void *p = VARDATA_ANY(val); IP6 *res = palloc(sizeof(IP6)); ip6_deserialize(p, res); - PG_RETURN_IP6_P(res); + PG_RETURN_IP6_P(res); } - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid BYTEA value for conversion to IP4"))); - PG_RETURN_NULL(); + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid BYTEA value for conversion to IP4"))); } PG_FUNCTION_INFO_V1(ip6_cast_to_bytea); @@ -447,289 +441,289 @@ Datum ip6_netmask(PG_FUNCTION_ARGS) { - int pfxlen = PG_GETARG_INT32(0); - IP6 *mask; + int pfxlen = PG_GETARG_INT32(0); + IP6 *mask; + + if (pfxlen < 0 || pfxlen > 128) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("prefix length out of range"))); + } - if (pfxlen < 0 || pfxlen > 128) - { - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("prefix length out of range"))); - } - - mask = palloc(sizeof(IP6)); - mask->bits[0] = netmask6_hi(pfxlen); - mask->bits[1] = netmask6_lo(pfxlen); - PG_RETURN_IP6_P(mask); + mask = palloc(sizeof(IP6)); + mask->bits[0] = netmask6_hi(pfxlen); + mask->bits[1] = netmask6_lo(pfxlen); + PG_RETURN_IP6_P(mask); } PG_FUNCTION_INFO_V1(ip6_net_lower); Datum ip6_net_lower(PG_FUNCTION_ARGS) { - IP6 *ip = PG_GETARG_IP6_P(0); - int pfxlen = PG_GETARG_INT32(1); - IP6 *res; - - if (pfxlen < 0 || pfxlen > 128) - { - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("prefix length out of range"))); - } - - res = palloc(sizeof(IP6)); - res->bits[0] = ip->bits[0] & netmask6_hi(pfxlen); - res->bits[1] = ip->bits[1] & netmask6_lo(pfxlen); + IP6 *ip = PG_GETARG_IP6_P(0); + int pfxlen = PG_GETARG_INT32(1); + IP6 *res; + + if (pfxlen < 0 || pfxlen > 128) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("prefix length out of range"))); + } - PG_RETURN_IP6_P(res); + res = palloc(sizeof(IP6)); + res->bits[0] = ip->bits[0] & netmask6_hi(pfxlen); + res->bits[1] = ip->bits[1] & netmask6_lo(pfxlen); + + PG_RETURN_IP6_P(res); } PG_FUNCTION_INFO_V1(ip6_net_upper); Datum ip6_net_upper(PG_FUNCTION_ARGS) { - IP6 *ip = PG_GETARG_IP6_P(0); - int pfxlen = PG_GETARG_INT32(1); - IP6 *res; - - if (pfxlen < 0 || pfxlen > 128) - { - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("prefix length out of range"))); - } - - res = palloc(sizeof(IP6)); - res->bits[0] = ip->bits[0] | hostmask6_hi(pfxlen); - res->bits[1] = ip->bits[1] | hostmask6_lo(pfxlen); + IP6 *ip = PG_GETARG_IP6_P(0); + int pfxlen = PG_GETARG_INT32(1); + IP6 *res; - PG_RETURN_IP6_P(res); + if (pfxlen < 0 || pfxlen > 128) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("prefix length out of range"))); + } + + res = palloc(sizeof(IP6)); + res->bits[0] = ip->bits[0] | hostmask6_hi(pfxlen); + res->bits[1] = ip->bits[1] | hostmask6_lo(pfxlen); + + PG_RETURN_IP6_P(res); } PG_FUNCTION_INFO_V1(ip6_plus_int); Datum ip6_plus_int(PG_FUNCTION_ARGS) { - IP6 *ip = PG_GETARG_IP6_P(0); - int addend = PG_GETARG_INT32(1); - IP6 *result = palloc(sizeof(IP6)); - - if (addend >= 0) - { - result->bits[1] = ip->bits[1] + addend; - result->bits[0] = ip->bits[0] + (result->bits[1] < ip->bits[1]); - } - else - { - result->bits[1] = ip->bits[1] - (uint64)(-addend); - result->bits[0] = ip->bits[0] - (result->bits[1] > ip->bits[1]); - } - - if ((addend < 0) != ip6_lessthan(result,ip)) - { - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("ip address out of range"))); - } + IP6 *ip = PG_GETARG_IP6_P(0); + int addend = PG_GETARG_INT32(1); + IP6 *result = palloc(sizeof(IP6)); + + if (addend >= 0) + { + result->bits[1] = ip->bits[1] + addend; + result->bits[0] = ip->bits[0] + (result->bits[1] < ip->bits[1]); + } + else + { + result->bits[1] = ip->bits[1] - (uint64)(-addend); + result->bits[0] = ip->bits[0] - (result->bits[1] > ip->bits[1]); + } + + if ((addend < 0) != ip6_lessthan(result,ip)) + { + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("ip address out of range"))); + } - PG_RETURN_IP6_P(result); + PG_RETURN_IP6_P(result); } PG_FUNCTION_INFO_V1(ip6_plus_bigint); Datum ip6_plus_bigint(PG_FUNCTION_ARGS) { - IP6 *ip = PG_GETARG_IP6_P(0); - int64 addend = PG_GETARG_INT64(1); - IP6 *result = palloc(sizeof(IP6)); - - if (addend >= 0) - { - result->bits[1] = ip->bits[1] + addend; - result->bits[0] = ip->bits[0] + (result->bits[1] < ip->bits[1]); - } - else - { - result->bits[1] = ip->bits[1] - (uint64)(-addend); - result->bits[0] = ip->bits[0] - (result->bits[1] > ip->bits[1]); - } - - if ((addend < 0) != ip6_lessthan(result,ip)) - { - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("ip address out of range"))); - } + IP6 *ip = PG_GETARG_IP6_P(0); + int64 addend = PG_GETARG_INT64(1); + IP6 *result = palloc(sizeof(IP6)); - PG_RETURN_IP6_P(result); + if (addend >= 0) + { + result->bits[1] = ip->bits[1] + addend; + result->bits[0] = ip->bits[0] + (result->bits[1] < ip->bits[1]); + } + else + { + result->bits[1] = ip->bits[1] - (uint64)(-addend); + result->bits[0] = ip->bits[0] - (result->bits[1] > ip->bits[1]); + } + + if ((addend < 0) != ip6_lessthan(result,ip)) + { + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("ip address out of range"))); + } + + PG_RETURN_IP6_P(result); } PG_FUNCTION_INFO_V1(ip6_plus_numeric); Datum ip6_plus_numeric(PG_FUNCTION_ARGS) { - IP6 *ip = PG_GETARG_IP6_P(0); - Datum addend_num = NumericGetDatum(PG_GETARG_NUMERIC(1)); - Datum addend_abs; - IP6 *addend; - IP6 *result = palloc(sizeof(IP6)); - bool is_negative; - - addend_abs = DirectFunctionCall1(numeric_abs,addend_num); - addend = DatumGetIP6P(DirectFunctionCall1(ip6_cast_from_numeric,addend_abs)); - - if (DatumGetBool(DirectFunctionCall2(numeric_eq,addend_num,addend_abs))) - { - is_negative = false; - result->bits[1] = ip->bits[1] + addend->bits[1]; - result->bits[0] = ip->bits[0] + addend->bits[0] + (result->bits[1] < ip->bits[1]); - } - else - { - is_negative = true; - result->bits[1] = ip->bits[1] - addend->bits[1]; - result->bits[0] = ip->bits[0] - addend->bits[0] - (result->bits[1] > ip->bits[1]); - } - - if (is_negative != ip6_lessthan(result,ip)) - { - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("ip address out of range"))); - } + IP6 *ip = PG_GETARG_IP6_P(0); + Datum addend_num = NumericGetDatum(PG_GETARG_NUMERIC(1)); + Datum addend_abs; + IP6 *addend; + IP6 *result = palloc(sizeof(IP6)); + bool is_negative; + + addend_abs = DirectFunctionCall1(numeric_abs,addend_num); + addend = DatumGetIP6P(DirectFunctionCall1(ip6_cast_from_numeric,addend_abs)); + + if (DatumGetBool(DirectFunctionCall2(numeric_eq,addend_num,addend_abs))) + { + is_negative = false; + result->bits[1] = ip->bits[1] + addend->bits[1]; + result->bits[0] = ip->bits[0] + addend->bits[0] + (result->bits[1] < ip->bits[1]); + } + else + { + is_negative = true; + result->bits[1] = ip->bits[1] - addend->bits[1]; + result->bits[0] = ip->bits[0] - addend->bits[0] - (result->bits[1] > ip->bits[1]); + } - PG_RETURN_IP6_P(result); + if (is_negative != ip6_lessthan(result,ip)) + { + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("ip address out of range"))); + } + + PG_RETURN_IP6_P(result); } PG_FUNCTION_INFO_V1(ip6_minus_int); Datum ip6_minus_int(PG_FUNCTION_ARGS) { - IP6 *ip = PG_GETARG_IP6_P(0); - int subtrahend = PG_GETARG_INT32(1); - IP6 *result = palloc(sizeof(IP6)); + IP6 *ip = PG_GETARG_IP6_P(0); + int subtrahend = PG_GETARG_INT32(1); + IP6 *result = palloc(sizeof(IP6)); ip6_sub_int(ip, subtrahend, result); - if ((subtrahend > 0) != ip6_lessthan(result,ip)) - { - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("ip address out of range"))); - } + if ((subtrahend > 0) != ip6_lessthan(result,ip)) + { + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("ip address out of range"))); + } - PG_RETURN_IP6_P(result); + PG_RETURN_IP6_P(result); } PG_FUNCTION_INFO_V1(ip6_minus_bigint); Datum ip6_minus_bigint(PG_FUNCTION_ARGS) { - IP6 *ip = PG_GETARG_IP6_P(0); - int64 subtrahend = PG_GETARG_INT64(1); - IP6 *result = palloc(sizeof(IP6)); - - if (subtrahend >= 0) - { - result->bits[1] = ip->bits[1] - (uint64)subtrahend; - result->bits[0] = ip->bits[0] - (result->bits[1] > ip->bits[1]); - } - else - { - result->bits[1] = ip->bits[1] + (uint64)(-subtrahend); - result->bits[0] = ip->bits[0] + (result->bits[1] < ip->bits[1]); - } - - if ((subtrahend > 0) != ip6_lessthan(result,ip)) - { - ereport(ERROR, - (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("ip address out of range"))); - } + IP6 *ip = PG_GETARG_IP6_P(0); + int64 subtrahend = PG_GETARG_INT64(1); + IP6 *result = palloc(sizeof(IP6)); + + if (subtrahend >= 0) + { + result->bits[1] = ip->bits[1] - (uint64)subtrahend; + result->bits[0] = ip->bits[0] - (result->bits[1] > ip->bits[1]); + } + else + { + result->bits[1] = ip->bits[1] + (uint64)(-subtrahend); + result->bits[0] = ip->bits[0] + (result->bits[1] < ip->bits[1]); + } + + if ((subtrahend > 0) != ip6_lessthan(result,ip)) + { + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("ip address out of range"))); + } - PG_RETURN_IP6_P(result); + PG_RETURN_IP6_P(result); } PG_FUNCTION_INFO_V1(ip6_minus_numeric); Datum ip6_minus_numeric(PG_FUNCTION_ARGS) { - Datum ip = PG_GETARG_DATUM(0); - Datum subtrahend = PG_GETARG_DATUM(1); + Datum ip = PG_GETARG_DATUM(0); + Datum subtrahend = PG_GETARG_DATUM(1); - subtrahend = DirectFunctionCall1(numeric_uminus,subtrahend); - return DirectFunctionCall2(ip6_plus_numeric,ip,subtrahend); + subtrahend = DirectFunctionCall1(numeric_uminus,subtrahend); + return DirectFunctionCall2(ip6_plus_numeric,ip,subtrahend); } PG_FUNCTION_INFO_V1(ip6_minus_ip6); Datum ip6_minus_ip6(PG_FUNCTION_ARGS) { - Datum minuend = PG_GETARG_DATUM(0); - Datum subtrahend = PG_GETARG_DATUM(1); - Datum res; - - res = DirectFunctionCall2(numeric_sub, - DirectFunctionCall1(ip6_cast_to_numeric,minuend), - DirectFunctionCall1(ip6_cast_to_numeric,subtrahend)); + Datum minuend = PG_GETARG_DATUM(0); + Datum subtrahend = PG_GETARG_DATUM(1); + Datum res; + + res = DirectFunctionCall2(numeric_sub, + DirectFunctionCall1(ip6_cast_to_numeric,minuend), + DirectFunctionCall1(ip6_cast_to_numeric,subtrahend)); - PG_RETURN_DATUM(res); + PG_RETURN_DATUM(res); } PG_FUNCTION_INFO_V1(ip6_and); Datum ip6_and(PG_FUNCTION_ARGS) { - IP6 *a = PG_GETARG_IP6_P(0); - IP6 *b = PG_GETARG_IP6_P(1); - IP6 *res = palloc(sizeof(IP6)); + IP6 *a = PG_GETARG_IP6_P(0); + IP6 *b = PG_GETARG_IP6_P(1); + IP6 *res = palloc(sizeof(IP6)); - res->bits[0] = a->bits[0] & b->bits[0]; - res->bits[1] = a->bits[1] & b->bits[1]; + res->bits[0] = a->bits[0] & b->bits[0]; + res->bits[1] = a->bits[1] & b->bits[1]; - PG_RETURN_IP6_P(res); + PG_RETURN_IP6_P(res); } PG_FUNCTION_INFO_V1(ip6_or); Datum ip6_or(PG_FUNCTION_ARGS) { - IP6 *a = PG_GETARG_IP6_P(0); - IP6 *b = PG_GETARG_IP6_P(1); - IP6 *res = palloc(sizeof(IP6)); + IP6 *a = PG_GETARG_IP6_P(0); + IP6 *b = PG_GETARG_IP6_P(1); + IP6 *res = palloc(sizeof(IP6)); - res->bits[0] = a->bits[0] | b->bits[0]; - res->bits[1] = a->bits[1] | b->bits[1]; + res->bits[0] = a->bits[0] | b->bits[0]; + res->bits[1] = a->bits[1] | b->bits[1]; - PG_RETURN_IP6_P(res); + PG_RETURN_IP6_P(res); } PG_FUNCTION_INFO_V1(ip6_xor); Datum ip6_xor(PG_FUNCTION_ARGS) { - IP6 *a = PG_GETARG_IP6_P(0); - IP6 *b = PG_GETARG_IP6_P(1); - IP6 *res = palloc(sizeof(IP6)); + IP6 *a = PG_GETARG_IP6_P(0); + IP6 *b = PG_GETARG_IP6_P(1); + IP6 *res = palloc(sizeof(IP6)); - res->bits[0] = a->bits[0] ^ b->bits[0]; - res->bits[1] = a->bits[1] ^ b->bits[1]; + res->bits[0] = a->bits[0] ^ b->bits[0]; + res->bits[1] = a->bits[1] ^ b->bits[1]; - PG_RETURN_IP6_P(res); + PG_RETURN_IP6_P(res); } PG_FUNCTION_INFO_V1(ip6_not); Datum ip6_not(PG_FUNCTION_ARGS) { - IP6 *a = PG_GETARG_IP6_P(0); - IP6 *res = palloc(sizeof(IP6)); + IP6 *a = PG_GETARG_IP6_P(0); + IP6 *res = palloc(sizeof(IP6)); - res->bits[0] = ~a->bits[0]; - res->bits[1] = ~a->bits[1]; + res->bits[0] = ~a->bits[0]; + res->bits[1] = ~a->bits[1]; - PG_RETURN_IP6_P(res); + PG_RETURN_IP6_P(res); } @@ -739,200 +733,204 @@ Datum ip6r_in(PG_FUNCTION_ARGS) { - char *str = PG_GETARG_CSTRING(0); - IP6R ipr; + char *str = PG_GETARG_CSTRING(0); + IP6R ipr; - if (ip6r_from_str(str, &ipr)) - { - IP6R *res = palloc(sizeof(IP6R)); - *res = ipr; - PG_RETURN_IP6R_P(res); - } - - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid IP6R value: \"%s\"", str))); - PG_RETURN_NULL(); + if (ip6r_from_str(str, &ipr)) + { + IP6R *res = palloc(sizeof(IP6R)); + *res = ipr; + PG_RETURN_IP6R_P(res); + } + + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid IP6R value: \"%s\"", str))); } PG_FUNCTION_INFO_V1(ip6r_out); Datum ip6r_out(PG_FUNCTION_ARGS) { - IP6R *ipr = PG_GETARG_IP6R_P(0); - char *out = palloc(IP6R_STRING_MAX); - ip6r_to_str(ipr, out, IP6R_STRING_MAX); - PG_RETURN_CSTRING(out); + IP6R *ipr = PG_GETARG_IP6R_P(0); + char *out = palloc(IP6R_STRING_MAX); + ip6r_to_str(ipr, out, IP6R_STRING_MAX); + PG_RETURN_CSTRING(out); } PG_FUNCTION_INFO_V1(ip6r_recv); Datum ip6r_recv(PG_FUNCTION_ARGS) { - StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); - IP6R *ipr = palloc(sizeof(IP6R)); + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); + IP6R *ipr = palloc(sizeof(IP6R)); + + ipr->lower.bits[0] = pq_getmsgint64(buf); + ipr->lower.bits[1] = pq_getmsgint64(buf); + ipr->upper.bits[0] = pq_getmsgint64(buf); + ipr->upper.bits[1] = pq_getmsgint64(buf); - ipr->lower.bits[0] = pq_getmsgint64(buf); - ipr->lower.bits[1] = pq_getmsgint64(buf); - ipr->upper.bits[0] = pq_getmsgint64(buf); - ipr->upper.bits[1] = pq_getmsgint64(buf); + if (ip6_lessthan(&ipr->upper, &ipr->lower)) + { + IP6 t = ipr->upper; + ipr->upper = ipr->lower; + ipr->lower = t; + } - PG_RETURN_IP6R_P(ipr); + PG_RETURN_IP6R_P(ipr); } PG_FUNCTION_INFO_V1(ip6r_send); Datum ip6r_send(PG_FUNCTION_ARGS) { - IP6R *ipr = PG_GETARG_IP6R_P(0); - StringInfoData buf; + IP6R *ipr = PG_GETARG_IP6R_P(0); + StringInfoData buf; - pq_begintypsend(&buf); - pq_sendint64(&buf, ipr->lower.bits[0]); - pq_sendint64(&buf, ipr->lower.bits[1]); - pq_sendint64(&buf, ipr->upper.bits[0]); - pq_sendint64(&buf, ipr->upper.bits[1]); - PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); + pq_begintypsend(&buf); + pq_sendint64(&buf, ipr->lower.bits[0]); + pq_sendint64(&buf, ipr->lower.bits[1]); + pq_sendint64(&buf, ipr->upper.bits[0]); + pq_sendint64(&buf, ipr->upper.bits[1]); + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); } PG_FUNCTION_INFO_V1(ip6rhash); Datum ip6rhash(PG_FUNCTION_ARGS) { - IP6R *arg1 = PG_GETARG_IP6R_P(0); + IP6R *arg1 = PG_GETARG_IP6R_P(0); - return hash_any((unsigned char *)arg1, sizeof(IP6R)); + return hash_any((unsigned char *)arg1, sizeof(IP6R)); } PG_FUNCTION_INFO_V1(ip6r_hash_extended); Datum ip6r_hash_extended(PG_FUNCTION_ARGS) { - IP6R *arg1 = PG_GETARG_IP6R_P(0); + IP6R *arg1 = PG_GETARG_IP6R_P(0); uint64 seed = DatumGetUInt64(PG_GETARG_DATUM(1)); - return hash_any_extended((unsigned char *)arg1, sizeof(IP6R), seed); + return hash_any_extended((unsigned char *)arg1, sizeof(IP6R), seed); } PG_FUNCTION_INFO_V1(ip6r_cast_to_text); Datum ip6r_cast_to_text(PG_FUNCTION_ARGS) { - IP6R *ipr = PG_GETARG_IP6R_P(0); - text *out = make_text(IP6R_STRING_MAX); - set_text_len(out, ip6r_to_str(ipr, VARDATA(out), IP6R_STRING_MAX)); - PG_RETURN_TEXT_P(out); + IP6R *ipr = PG_GETARG_IP6R_P(0); + text *out = make_text(IP6R_STRING_MAX); + set_text_len(out, ip6r_to_str(ipr, VARDATA(out), IP6R_STRING_MAX)); + PG_RETURN_TEXT_P(out); } PG_FUNCTION_INFO_V1(ip6r_cast_from_text); Datum ip6r_cast_from_text(PG_FUNCTION_ARGS) { - text *txt = PG_GETARG_TEXT_PP(0); - int tlen = VARSIZE_ANY_EXHDR(txt); - char buf[IP6R_STRING_MAX]; - - if (tlen < sizeof(buf)) - { - IP6R ipr; - - memcpy(buf, VARDATA_ANY(txt), tlen); - buf[tlen] = 0; - if (ip6r_from_str(buf, &ipr)) - { - IP6R *res = palloc(sizeof(IP6R)); - *res = ipr; - PG_RETURN_IP6R_P(res); - } - } - - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid IP6R value in text"))); - PG_RETURN_NULL(); + text *txt = PG_GETARG_TEXT_PP(0); + int tlen = VARSIZE_ANY_EXHDR(txt); + char buf[IP6R_STRING_MAX]; + + if (tlen < sizeof(buf)) + { + IP6R ipr; + + memcpy(buf, VARDATA_ANY(txt), tlen); + buf[tlen] = 0; + if (ip6r_from_str(buf, &ipr)) + { + IP6R *res = palloc(sizeof(IP6R)); + *res = ipr; + PG_RETURN_IP6R_P(res); + } + } + + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid IP6R value in text"))); } PG_FUNCTION_INFO_V1(ip6r_cast_from_cidr); Datum ip6r_cast_from_cidr(PG_FUNCTION_ARGS) { - inet *inetptr = PG_GETARG_INET_P(0); - inet_struct *in = INET_STRUCT_DATA(inetptr); + inet *inetptr = PG_GETARG_INET_P(0); + inet_struct *in = INET_STRUCT_DATA(inetptr); - if (in->family == PGSQL_AF_INET6) - { - unsigned char *p = in->ipaddr; - IP6 ip; - IP6R ipr; + if (in->family == PGSQL_AF_INET6) + { + unsigned char *p = in->ipaddr; + IP6 ip; + IP6R ipr; ip6_deserialize(p, &ip); - if (ip6r_from_cidr(&ip, in->bits, &ipr)) - { - IP6R *res = palloc(sizeof(IP6R)); - *res = ipr; - PG_RETURN_IP6R_P(res); - } - } - - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid CIDR value for conversion to IP6R"))); - PG_RETURN_NULL(); + if (ip6r_from_cidr(&ip, in->bits, &ipr)) + { + IP6R *res = palloc(sizeof(IP6R)); + *res = ipr; + PG_RETURN_IP6R_P(res); + } + } + + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid CIDR value for conversion to IP6R"))); } PG_FUNCTION_INFO_V1(ip6r_cast_to_cidr); Datum ip6r_cast_to_cidr(PG_FUNCTION_ARGS) { - IP6R *ipr = PG_GETARG_IP6R_P(0); - IP6 *ip = &ipr->lower; - inet *res; - inet_struct *in; - unsigned bits = masklen6(ip, &ipr->upper); - - if (bits > 128) - PG_RETURN_NULL(); - - res = palloc0(VARHDRSZ + sizeof(inet_struct)); - SET_VARSIZE(res, VARHDRSZ + offsetof(inet_struct, ipaddr) + 16); - - in = ((inet_struct *)VARDATA(res)); - in->bits = bits; - in->family = PGSQL_AF_INET6; + IP6R *ipr = PG_GETARG_IP6R_P(0); + IP6 *ip = &ipr->lower; + inet *res; + inet_struct *in; + unsigned bits = masklen6(ip, &ipr->upper); + + if (bits > 128) + PG_RETURN_NULL(); + + res = palloc0(VARHDRSZ + sizeof(inet_struct)); + SET_VARSIZE(res, VARHDRSZ + offsetof(inet_struct, ipaddr) + 16); + + in = ((inet_struct *)VARDATA(res)); + in->bits = bits; + in->family = PGSQL_AF_INET6; ip6_serialize(ip, in->ipaddr); - PG_RETURN_INET_P(res); + PG_RETURN_INET_P(res); } PG_FUNCTION_INFO_V1(ip6r_cast_from_ip6); Datum ip6r_cast_from_ip6(PG_FUNCTION_ARGS) { - IP6 *ip = PG_GETARG_IP6_P(0); - IP6R *res = palloc(sizeof(IP6R)); - if (ip6r_from_inet(ip, 128, res)) - { - PG_RETURN_IP6R_P(res); - } - - pfree(res); - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid IP6 value for conversion to IP6R (shouldn't be possible)"))); - PG_RETURN_NULL(); + IP6 *ip = PG_GETARG_IP6_P(0); + IP6R *res = palloc(sizeof(IP6R)); + if (ip6r_from_inet(ip, 128, res)) + { + PG_RETURN_IP6R_P(res); + } + + pfree(res); + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid IP6 value for conversion to IP6R (shouldn't be possible)"))); + PG_RETURN_NULL(); } PG_FUNCTION_INFO_V1(ip6r_from_ip6s); Datum ip6r_from_ip6s(PG_FUNCTION_ARGS) { - IP6 *a = PG_GETARG_IP6_P(0); - IP6 *b = PG_GETARG_IP6_P(1); - IP6R *res = palloc(sizeof(IP6R)); - if (ip6_lessthan(a,b)) - res->lower = *a, res->upper = *b; - else - res->lower = *b, res->upper = *a; - PG_RETURN_IP6R_P(res); + IP6 *a = PG_GETARG_IP6_P(0); + IP6 *b = PG_GETARG_IP6_P(1); + IP6R *res = palloc(sizeof(IP6R)); + if (ip6_lessthan(a,b)) + res->lower = *a, res->upper = *b; + else + res->lower = *b, res->upper = *a; + PG_RETURN_IP6R_P(res); } PG_FUNCTION_INFO_V1(ip6r_cast_from_bit); @@ -945,7 +943,7 @@ if (bitlen <= 128) { bits8 buf[16]; - bits8 *p = VARBITS(val); + bits8 *p = VARBITS(val); IP6 ip; IP6R *res = palloc(sizeof(IP6R)); @@ -961,29 +959,28 @@ PG_RETURN_IP6_P(res); } - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid BIT value for conversion to IP6R"))); - PG_RETURN_NULL(); + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid BIT value for conversion to IP6R"))); } PG_FUNCTION_INFO_V1(ip6r_cast_to_bit); Datum ip6r_cast_to_bit(PG_FUNCTION_ARGS) { - IP6R *ipr = PG_GETARG_IP6R_P(0); - IP6 *ip = &ipr->lower; - unsigned bits = masklen6(ip, &ipr->upper); + IP6R *ipr = PG_GETARG_IP6R_P(0); + IP6 *ip = &ipr->lower; + unsigned bits = masklen6(ip, &ipr->upper); VarBit *res; unsigned char buf[16]; int len; - if (bits > 128) - PG_RETURN_NULL(); + if (bits > 128) + PG_RETURN_NULL(); len = VARBITTOTALLEN(bits); - res = palloc0(len); - SET_VARSIZE(res, len); + res = palloc0(len); + SET_VARSIZE(res, len); VARBITLEN(res) = bits; ip6_serialize(ip, buf); @@ -996,47 +993,47 @@ Datum ip6r_net_prefix(PG_FUNCTION_ARGS) { - IP6 *ip = PG_GETARG_IP6_P(0); - int pfxlen = PG_GETARG_INT32(1); + IP6 *ip = PG_GETARG_IP6_P(0); + int pfxlen = PG_GETARG_INT32(1); + + if (pfxlen < 0 || pfxlen > 128) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("prefix length out of range"))); + } - if (pfxlen < 0 || pfxlen > 128) - { - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("prefix length out of range"))); - } - - { - IP6R *res = palloc(sizeof(IP6R)); - ip6r_from_inet(ip, (unsigned)pfxlen, res); - PG_RETURN_IP6R_P(res); - } + { + IP6R *res = palloc(sizeof(IP6R)); + ip6r_from_inet(ip, (unsigned)pfxlen, res); + PG_RETURN_IP6R_P(res); + } } PG_FUNCTION_INFO_V1(ip6r_net_mask); Datum ip6r_net_mask(PG_FUNCTION_ARGS) { - IP6 *ip = PG_GETARG_IP6_P(0); - IP6 *mask = PG_GETARG_IP6_P(1); + IP6 *ip = PG_GETARG_IP6_P(0); + IP6 *mask = PG_GETARG_IP6_P(1); + + if (!ip6_valid_netmask(mask->bits[0], mask->bits[1])) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid netmask"))); + } + + { + IP6R *res = palloc(sizeof(IP6R)); - if (!ip6_valid_netmask(mask->bits[0], mask->bits[1])) - { - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid netmask"))); - } - - { - IP6R *res = palloc(sizeof(IP6R)); - - res->lower.bits[0] = ip->bits[0] & mask->bits[0]; - res->lower.bits[1] = ip->bits[1] & mask->bits[1]; - res->upper.bits[0] = ip->bits[0] | ~(mask->bits[0]); - res->upper.bits[1] = ip->bits[1] | ~(mask->bits[1]); + res->lower.bits[0] = ip->bits[0] & mask->bits[0]; + res->lower.bits[1] = ip->bits[1] & mask->bits[1]; + res->upper.bits[0] = ip->bits[0] | ~(mask->bits[0]); + res->upper.bits[1] = ip->bits[1] | ~(mask->bits[1]); - PG_RETURN_IP6R_P(res); - } + PG_RETURN_IP6R_P(res); + } } @@ -1044,28 +1041,28 @@ Datum ip6r_lower(PG_FUNCTION_ARGS) { - IP6R *ipr = PG_GETARG_IP6R_P(0); - IP6 *res = palloc(sizeof(IP6)); - *res = ipr->lower; - PG_RETURN_IP6_P(res); + IP6R *ipr = PG_GETARG_IP6R_P(0); + IP6 *res = palloc(sizeof(IP6)); + *res = ipr->lower; + PG_RETURN_IP6_P(res); } PG_FUNCTION_INFO_V1(ip6r_upper); Datum ip6r_upper(PG_FUNCTION_ARGS) { - IP6R *ipr = PG_GETARG_IP6R_P(0); - IP6 *res = palloc(sizeof(IP6)); - *res = ipr->upper; - PG_RETURN_IP6_P(res); + IP6R *ipr = PG_GETARG_IP6R_P(0); + IP6 *res = palloc(sizeof(IP6)); + *res = ipr->upper; + PG_RETURN_IP6_P(res); } PG_FUNCTION_INFO_V1(ip6r_is_cidr); Datum ip6r_is_cidr(PG_FUNCTION_ARGS) { - IP6R *ipr = PG_GETARG_IP6R_P(0); - PG_RETURN_BOOL( (masklen6(&ipr->lower,&ipr->upper) <= 128U) ); + IP6R *ipr = PG_GETARG_IP6R_P(0); + PG_RETURN_BOOL( (masklen6(&ipr->lower,&ipr->upper) <= 128U) ); } /* @@ -1110,172 +1107,172 @@ Datum ip6_lt(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip6_lessthan(PG_GETARG_IP6_P(0), PG_GETARG_IP6_P(1)) ); + PG_RETURN_BOOL( ip6_lessthan(PG_GETARG_IP6_P(0), PG_GETARG_IP6_P(1)) ); } PG_FUNCTION_INFO_V1(ip6_le); Datum ip6_le(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip6_less_eq(PG_GETARG_IP6_P(0), PG_GETARG_IP6_P(1)) ); + PG_RETURN_BOOL( ip6_less_eq(PG_GETARG_IP6_P(0), PG_GETARG_IP6_P(1)) ); } PG_FUNCTION_INFO_V1(ip6_gt); Datum ip6_gt(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip6_lessthan(PG_GETARG_IP6_P(1), PG_GETARG_IP6_P(0)) ); + PG_RETURN_BOOL( ip6_lessthan(PG_GETARG_IP6_P(1), PG_GETARG_IP6_P(0)) ); } PG_FUNCTION_INFO_V1(ip6_ge); Datum ip6_ge(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip6_less_eq(PG_GETARG_IP6_P(1), PG_GETARG_IP6_P(0)) ); + PG_RETURN_BOOL( ip6_less_eq(PG_GETARG_IP6_P(1), PG_GETARG_IP6_P(0)) ); } PG_FUNCTION_INFO_V1(ip6_eq); Datum ip6_eq(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip6_equal(PG_GETARG_IP6_P(0), PG_GETARG_IP6_P(1)) ); + PG_RETURN_BOOL( ip6_equal(PG_GETARG_IP6_P(0), PG_GETARG_IP6_P(1)) ); } PG_FUNCTION_INFO_V1(ip6_neq); Datum ip6_neq(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( !ip6_equal(PG_GETARG_IP6_P(0), PG_GETARG_IP6_P(1)) ); + PG_RETURN_BOOL( !ip6_equal(PG_GETARG_IP6_P(0), PG_GETARG_IP6_P(1)) ); } PG_FUNCTION_INFO_V1(ip6r_lt); Datum ip6r_lt(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip6r_lessthan(PG_GETARG_IP6R_P(0), PG_GETARG_IP6R_P(1)) ); + PG_RETURN_BOOL( ip6r_lessthan(PG_GETARG_IP6R_P(0), PG_GETARG_IP6R_P(1)) ); } PG_FUNCTION_INFO_V1(ip6r_le); Datum ip6r_le(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip6r_less_eq(PG_GETARG_IP6R_P(0), PG_GETARG_IP6R_P(1)) ); + PG_RETURN_BOOL( ip6r_less_eq(PG_GETARG_IP6R_P(0), PG_GETARG_IP6R_P(1)) ); } PG_FUNCTION_INFO_V1(ip6r_gt); Datum ip6r_gt(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip6r_lessthan(PG_GETARG_IP6R_P(1), PG_GETARG_IP6R_P(0)) ); + PG_RETURN_BOOL( ip6r_lessthan(PG_GETARG_IP6R_P(1), PG_GETARG_IP6R_P(0)) ); } PG_FUNCTION_INFO_V1(ip6r_ge); Datum ip6r_ge(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip6r_less_eq(PG_GETARG_IP6R_P(1), PG_GETARG_IP6R_P(0)) ); + PG_RETURN_BOOL( ip6r_less_eq(PG_GETARG_IP6R_P(1), PG_GETARG_IP6R_P(0)) ); } PG_FUNCTION_INFO_V1(ip6r_eq); Datum ip6r_eq(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip6r_equal(PG_GETARG_IP6R_P(0), PG_GETARG_IP6R_P(1)) ); + PG_RETURN_BOOL( ip6r_equal(PG_GETARG_IP6R_P(0), PG_GETARG_IP6R_P(1)) ); } PG_FUNCTION_INFO_V1(ip6r_neq); Datum ip6r_neq(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( !ip6r_equal(PG_GETARG_IP6R_P(0), PG_GETARG_IP6R_P(1)) ); + PG_RETURN_BOOL( !ip6r_equal(PG_GETARG_IP6R_P(0), PG_GETARG_IP6R_P(1)) ); } PG_FUNCTION_INFO_V1(ip6r_overlaps); Datum ip6r_overlaps(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip6r_overlaps_internal(PG_GETARG_IP6R_P(0), - PG_GETARG_IP6R_P(1)) ); + PG_RETURN_BOOL( ip6r_overlaps_internal(PG_GETARG_IP6R_P(0), + PG_GETARG_IP6R_P(1)) ); } PG_FUNCTION_INFO_V1(ip6r_contains); Datum ip6r_contains(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip6r_contains_internal(PG_GETARG_IP6R_P(0), - PG_GETARG_IP6R_P(1), - true) ); + PG_RETURN_BOOL( ip6r_contains_internal(PG_GETARG_IP6R_P(0), + PG_GETARG_IP6R_P(1), + true) ); } PG_FUNCTION_INFO_V1(ip6r_contains_strict); Datum ip6r_contains_strict(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip6r_contains_internal(PG_GETARG_IP6R_P(0), - PG_GETARG_IP6R_P(1), - false) ); + PG_RETURN_BOOL( ip6r_contains_internal(PG_GETARG_IP6R_P(0), + PG_GETARG_IP6R_P(1), + false) ); } PG_FUNCTION_INFO_V1(ip6r_contained_by); Datum ip6r_contained_by(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip6r_contains_internal(PG_GETARG_IP6R_P(1), - PG_GETARG_IP6R_P(0), - true) ); + PG_RETURN_BOOL( ip6r_contains_internal(PG_GETARG_IP6R_P(1), + PG_GETARG_IP6R_P(0), + true) ); } PG_FUNCTION_INFO_V1(ip6r_contained_by_strict); Datum ip6r_contained_by_strict(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip6r_contains_internal(PG_GETARG_IP6R_P(1), - PG_GETARG_IP6R_P(0), - false) ); + PG_RETURN_BOOL( ip6r_contains_internal(PG_GETARG_IP6R_P(1), + PG_GETARG_IP6R_P(0), + false) ); } PG_FUNCTION_INFO_V1(ip6_contains); Datum ip6_contains(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip6_contains_internal(PG_GETARG_IP6R_P(0), PG_GETARG_IP6_P(1)) ); + PG_RETURN_BOOL( ip6_contains_internal(PG_GETARG_IP6R_P(0), PG_GETARG_IP6_P(1)) ); } PG_FUNCTION_INFO_V1(ip6_contained_by); Datum ip6_contained_by(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( ip6_contains_internal(PG_GETARG_IP6R_P(1), PG_GETARG_IP6_P(0)) ); + PG_RETURN_BOOL( ip6_contains_internal(PG_GETARG_IP6R_P(1), PG_GETARG_IP6_P(0)) ); } PG_FUNCTION_INFO_V1(ip6r_union); Datum ip6r_union(PG_FUNCTION_ARGS) { - IP6R *res = palloc(sizeof(IP6R)); - ip6r_union_internal(PG_GETARG_IP6R_P(0), PG_GETARG_IP6R_P(1), res); - PG_RETURN_IP6R_P(res); + IP6R *res = palloc(sizeof(IP6R)); + ip6r_union_internal(PG_GETARG_IP6R_P(0), PG_GETARG_IP6R_P(1), res); + PG_RETURN_IP6R_P(res); } PG_FUNCTION_INFO_V1(ip6r_inter); Datum ip6r_inter(PG_FUNCTION_ARGS) { - IP6R *res = palloc(sizeof(IP6R)); - if (ip6r_inter_internal(PG_GETARG_IP6R_P(0), PG_GETARG_IP6R_P(1), res)) - { - PG_RETURN_IP6R_P(res); - } - pfree(res); - PG_RETURN_NULL(); + IP6R *res = palloc(sizeof(IP6R)); + if (ip6r_inter_internal(PG_GETARG_IP6R_P(0), PG_GETARG_IP6R_P(1), res)) + { + PG_RETURN_IP6R_P(res); + } + pfree(res); + PG_RETURN_NULL(); } PG_FUNCTION_INFO_V1(ip6r_size); Datum ip6r_size(PG_FUNCTION_ARGS) { - double size = ip6r_metric(PG_GETARG_IP6R_P(0)); - PG_RETURN_FLOAT8(size); + double size = ip6r_metric(PG_GETARG_IP6R_P(0)); + PG_RETURN_FLOAT8(size); } PG_FUNCTION_INFO_V1(ip6r_size_exact); @@ -1294,7 +1291,7 @@ Datum ip6r_prefixlen(PG_FUNCTION_ARGS) { - IP6R *ipr = PG_GETARG_IP6R_P(0); + IP6R *ipr = PG_GETARG_IP6R_P(0); unsigned len = masklen6(&ipr->lower, &ipr->upper); if (len <= 128) PG_RETURN_INT32((int32) len); @@ -1303,36 +1300,36 @@ /***************************************************************************** - * Btree functions + * Btree functions *****************************************************************************/ PG_FUNCTION_INFO_V1(ip6r_cmp); Datum ip6r_cmp(PG_FUNCTION_ARGS) { - IP6R *a = PG_GETARG_IP6R_P(0); - IP6R *b = PG_GETARG_IP6R_P(1); - if (ip6r_lessthan(a,b)) - PG_RETURN_INT32(-1); - if (ip6r_equal(a,b)) - PG_RETURN_INT32(0); - PG_RETURN_INT32(1); + IP6R *a = PG_GETARG_IP6R_P(0); + IP6R *b = PG_GETARG_IP6R_P(1); + if (ip6r_lessthan(a,b)) + PG_RETURN_INT32(-1); + if (ip6r_equal(a,b)) + PG_RETURN_INT32(0); + PG_RETURN_INT32(1); } PG_FUNCTION_INFO_V1(ip6_cmp); Datum ip6_cmp(PG_FUNCTION_ARGS) { - IP6 *a = PG_GETARG_IP6_P(0); - IP6 *b = PG_GETARG_IP6_P(1); - PG_RETURN_INT32(ip6_compare(a,b)); + IP6 *a = PG_GETARG_IP6_P(0); + IP6 *b = PG_GETARG_IP6_P(1); + PG_RETURN_INT32(ip6_compare(a,b)); } /* * in_range(val ip6,base ip6,offset bigint,sub bool,less bool) * returns val CMP (base OP offset) * where CMP is <= if less, >= otherwise - * and OP is - if sub, + otherwise + * and OP is - if sub, + otherwise * We treat negative values of offset as special: they indicate * the (negation of) a cidr prefix length */ @@ -1450,7 +1447,7 @@ #endif /***************************************************************************** - * GiST functions + * GiST functions *****************************************************************************/ /* @@ -1479,27 +1476,27 @@ Datum gip6r_consistent(PG_FUNCTION_ARGS) { - GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); - IP6R *query = (IP6R *) PG_GETARG_POINTER(1); - StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); - bool *recheck = (bool *) PG_GETARG_POINTER(4); - IP6R *key = (IP6R *) DatumGetPointer(entry->key); - bool retval; - - /* recheck is never needed with this type */ - if (recheck) - *recheck = false; - - /* - * * if entry is not leaf, use gip6r_internal_consistent, * else use - * gip6r_leaf_consistent - */ - if (GIST_LEAF(entry)) - retval = gip6r_leaf_consistent(key, query, strategy); - else - retval = gip6r_internal_consistent(key, query, strategy); + GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); + IP6R *query = (IP6R *) PG_GETARG_POINTER(1); + StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); + bool *recheck = (bool *) PG_GETARG_POINTER(4); + IP6R *key = (IP6R *) DatumGetPointer(entry->key); + bool retval; + + /* recheck is never needed with this type */ + if (recheck) + *recheck = false; + + /* + * * if entry is not leaf, use gip6r_internal_consistent, * else use + * gip6r_leaf_consistent + */ + if (GIST_LEAF(entry)) + retval = gip6r_leaf_consistent(key, query, strategy); + else + retval = gip6r_internal_consistent(key, query, strategy); - PG_RETURN_BOOL(retval); + PG_RETURN_BOOL(retval); } /* @@ -1510,33 +1507,33 @@ Datum gip6r_union(PG_FUNCTION_ARGS) { - GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); - int *sizep = (int *) PG_GETARG_POINTER(1); - GISTENTRY *ent = GISTENTRYVEC(entryvec); - - int numranges, i; - IP6R *out = palloc(sizeof(IP6R)); - IP6R *tmp; + GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); + int *sizep = (int *) PG_GETARG_POINTER(1); + GISTENTRY *ent = GISTENTRYVEC(entryvec); + + int numranges, i; + IP6R *out = palloc(sizeof(IP6R)); + IP6R *tmp; #ifdef GIST_DEBUG - fprintf(stderr, "union\n"); + fprintf(stderr, "union\n"); #endif - numranges = GISTENTRYCOUNT(entryvec); - tmp = (IP6R *) DatumGetPointer(ent[0].key); - *sizep = sizeof(IP6R); - *out = *tmp; - - for (i = 1; i < numranges; i++) - { - tmp = (IP6R *) DatumGetPointer(ent[i].key); - if (ip6_lessthan(&tmp->lower,&out->lower)) - out->lower = tmp->lower; - if (ip6_lessthan(&out->upper,&tmp->upper)) - out->upper = tmp->upper; - } + numranges = GISTENTRYCOUNT(entryvec); + tmp = (IP6R *) DatumGetPointer(ent[0].key); + *sizep = sizeof(IP6R); + *out = *tmp; - PG_RETURN_IP6R_P(out); + for (i = 1; i < numranges; i++) + { + tmp = (IP6R *) DatumGetPointer(ent[i].key); + if (ip6_lessthan(&tmp->lower,&out->lower)) + out->lower = tmp->lower; + if (ip6_lessthan(&out->upper,&tmp->upper)) + out->upper = tmp->upper; + } + + PG_RETURN_IP6R_P(out); } /* @@ -1547,21 +1544,21 @@ Datum gip6r_compress(PG_FUNCTION_ARGS) { - PG_RETURN_POINTER(PG_GETARG_POINTER(0)); + PG_RETURN_POINTER(PG_GETARG_POINTER(0)); } PG_FUNCTION_INFO_V1(gip6r_decompress); Datum gip6r_decompress(PG_FUNCTION_ARGS) { - PG_RETURN_POINTER(PG_GETARG_POINTER(0)); + PG_RETURN_POINTER(PG_GETARG_POINTER(0)); } PG_FUNCTION_INFO_V1(gip6r_fetch); Datum gip6r_fetch(PG_FUNCTION_ARGS) { - PG_RETURN_POINTER(PG_GETARG_POINTER(0)); + PG_RETURN_POINTER(PG_GETARG_POINTER(0)); } /* @@ -1572,29 +1569,29 @@ Datum gip6r_penalty(PG_FUNCTION_ARGS) { - GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); - GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1); - float *result = (float *) PG_GETARG_POINTER(2); - IP6R *key = (IP6R *) DatumGetPointer(origentry->key); - IP6R *newkey = (IP6R *) DatumGetPointer(newentry->key); - IP6R ud; + GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); + GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1); + float *result = (float *) PG_GETARG_POINTER(2); + IP6R *key = (IP6R *) DatumGetPointer(origentry->key); + IP6R *newkey = (IP6R *) DatumGetPointer(newentry->key); + IP6R ud; double tmp = 0.0; /* rather than subtract the sizes, which might lose due to rounding errors, * we calculate the actual number of addresses added to the range. */ - if (ip6_lessthan(&newkey->lower,&key->lower)) + if (ip6_lessthan(&newkey->lower,&key->lower)) { - ud.lower = newkey->lower; + ud.lower = newkey->lower; ud.upper = key->lower; ip6_sub_int(&ud.upper,1,&ud.upper); tmp = ip6r_metric(&ud); } - if (ip6_lessthan(&key->upper,&newkey->upper)) + if (ip6_lessthan(&key->upper,&newkey->upper)) { ud.lower = key->upper; - ud.upper = newkey->upper; + ud.upper = newkey->upper; ip6_sub_int(&ud.upper,1,&ud.upper); tmp += ip6r_metric(&ud); } @@ -1610,14 +1607,14 @@ * gives us a range 0 - 268435456. */ - *result = (float) pow(log(tmp+1) / log(2), 4); + *result = (float) pow(log(tmp+1) / log(2), 4); #ifdef GIST_DEBUG - fprintf(stderr, "penalty\n"); - fprintf(stderr, "\t%g\n", *result); + fprintf(stderr, "penalty\n"); + fprintf(stderr, "\t%g\n", *result); #endif - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(result); } @@ -1627,16 +1624,16 @@ struct gip6r_sort { - IP6R *key; - OffsetNumber pos; + IP6R *key; + OffsetNumber pos; }; static int gip6r_sort_compare(const void *a, const void *b) { - double sa = ip6r_metric(((struct gip6r_sort *)a)->key); - double sb = ip6r_metric(((struct gip6r_sort *)b)->key); - return (sa > sb) ? 1 : ((sa == sb) ? 0 : -1); + double sa = ip6r_metric(((struct gip6r_sort *)a)->key); + double sb = ip6r_metric(((struct gip6r_sort *)b)->key); + return (sa > sb) ? 1 : ((sa == sb) ? 0 : -1); } /* @@ -1649,140 +1646,140 @@ Datum gip6r_picksplit(PG_FUNCTION_ARGS) { - GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); - GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1); - GISTENTRY *ent = GISTENTRYVEC(entryvec); - OffsetNumber i; - int nbytes; - OffsetNumber maxoff; - OffsetNumber *listL; - OffsetNumber *listR; - bool allisequal = true; - IP6R pageunion; - IP6R *cur; - IP6R *unionL; - IP6R *unionR; - int posL = 0; - int posR = 0; - - posL = posR = 0; - maxoff = GISTENTRYCOUNT(entryvec) - 1; - - cur = (IP6R *) DatumGetPointer(ent[FirstOffsetNumber].key); - pageunion = *cur; - - /* find MBR */ - for (i = OffsetNumberNext(FirstOffsetNumber); i <= maxoff; i = OffsetNumberNext(i)) - { - cur = (IP6R *) DatumGetPointer(ent[i].key); - if (allisequal == true && !ip6r_equal(&pageunion,cur)) - allisequal = false; - - if (ip6_lessthan(&cur->lower,&pageunion.lower)) - pageunion.lower = cur->lower; - if (ip6_lessthan(&pageunion.upper,&cur->upper)) - pageunion.upper = cur->upper; - } - - nbytes = (maxoff + 2) * sizeof(OffsetNumber); - listL = (OffsetNumber *) palloc(nbytes); - listR = (OffsetNumber *) palloc(nbytes); - unionL = palloc(sizeof(IP6R)); - unionR = palloc(sizeof(IP6R)); - v->spl_ldatum = PointerGetDatum(unionL); - v->spl_rdatum = PointerGetDatum(unionR); - v->spl_left = listL; - v->spl_right = listR; - - if (allisequal) - { - cur = (IP6R *) DatumGetPointer(ent[OffsetNumberNext(FirstOffsetNumber)].key); - if (ip6r_equal(cur, &pageunion)) - { - OffsetNumber split_at = FirstOffsetNumber + (maxoff - FirstOffsetNumber + 1)/2; - v->spl_nleft = v->spl_nright = 0; - *unionL = pageunion; - *unionR = pageunion; - - for (i = FirstOffsetNumber; i < split_at; i = OffsetNumberNext(i)) - v->spl_left[v->spl_nleft++] = i; - for (; i <= maxoff; i = OffsetNumberNext(i)) - v->spl_right[v->spl_nright++] = i; - - PG_RETURN_POINTER(v); - } - } + GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); + GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1); + GISTENTRY *ent = GISTENTRYVEC(entryvec); + OffsetNumber i; + int nbytes; + OffsetNumber maxoff; + OffsetNumber *listL; + OffsetNumber *listR; + bool allisequal = true; + IP6R pageunion; + IP6R *cur; + IP6R *unionL; + IP6R *unionR; + int posL = 0; + int posR = 0; + + posL = posR = 0; + maxoff = GISTENTRYCOUNT(entryvec) - 1; + + cur = (IP6R *) DatumGetPointer(ent[FirstOffsetNumber].key); + pageunion = *cur; + + /* find MBR */ + for (i = OffsetNumberNext(FirstOffsetNumber); i <= maxoff; i = OffsetNumberNext(i)) + { + cur = (IP6R *) DatumGetPointer(ent[i].key); + if (allisequal == true && !ip6r_equal(&pageunion,cur)) + allisequal = false; + + if (ip6_lessthan(&cur->lower,&pageunion.lower)) + pageunion.lower = cur->lower; + if (ip6_lessthan(&pageunion.upper,&cur->upper)) + pageunion.upper = cur->upper; + } + + nbytes = (maxoff + 2) * sizeof(OffsetNumber); + listL = (OffsetNumber *) palloc(nbytes); + listR = (OffsetNumber *) palloc(nbytes); + unionL = palloc(sizeof(IP6R)); + unionR = palloc(sizeof(IP6R)); + v->spl_ldatum = PointerGetDatum(unionL); + v->spl_rdatum = PointerGetDatum(unionR); + v->spl_left = listL; + v->spl_right = listR; + + if (allisequal) + { + cur = (IP6R *) DatumGetPointer(ent[OffsetNumberNext(FirstOffsetNumber)].key); + if (ip6r_equal(cur, &pageunion)) + { + OffsetNumber split_at = FirstOffsetNumber + (maxoff - FirstOffsetNumber + 1)/2; + v->spl_nleft = v->spl_nright = 0; + *unionL = pageunion; + *unionR = pageunion; + + for (i = FirstOffsetNumber; i < split_at; i = OffsetNumberNext(i)) + v->spl_left[v->spl_nleft++] = i; + for (; i <= maxoff; i = OffsetNumberNext(i)) + v->spl_right[v->spl_nright++] = i; + + PG_RETURN_POINTER(v); + } + } #define ADDLIST( list_, u_, pos_, num_ ) do { \ - if ( pos_ ) { \ - if ( ip6_lessthan(&(u_)->upper, &(cur)->upper) ) (u_)->upper = (cur)->upper; \ - if ( ip6_lessthan(&(cur)->lower, &(u_)->lower) ) (u_)->lower = (cur)->lower; \ - } else { \ - *(u_) = *(cur); \ - } \ - (list_)[(pos_)++] = (num_); \ + if ( pos_ ) { \ + if ( ip6_lessthan(&(u_)->upper, &(cur)->upper) ) (u_)->upper = (cur)->upper; \ + if ( ip6_lessthan(&(cur)->lower, &(u_)->lower) ) (u_)->lower = (cur)->lower; \ + } else { \ + *(u_) = *(cur); \ + } \ + (list_)[(pos_)++] = (num_); \ } while(0) - for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) - { - IP6 diff1; - IP6 diff2; - - cur = (IP6R *) DatumGetPointer(ent[i].key); - ip6_sub(&cur->lower, &pageunion.lower, &diff1); - ip6_sub(&pageunion.upper, &cur->upper, &diff2); - if (ip6_lessthan(&diff1,&diff2)) - ADDLIST(listL, unionL, posL, i); - else - ADDLIST(listR, unionR, posR, i); - } - - /* bad disposition, sort by ascending size and resplit */ - if (posR == 0 || posL == 0) - { - struct gip6r_sort *arr = (struct gip6r_sort *) - palloc(sizeof(struct gip6r_sort) * (maxoff + FirstOffsetNumber)); - - for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) - { - arr[i].key = (IP6R *) DatumGetPointer(ent[i].key); - arr[i].pos = i; - } - - qsort(arr + FirstOffsetNumber, - maxoff - FirstOffsetNumber + 1, - sizeof(struct gip6r_sort), - gip6r_sort_compare); - - posL = posR = 0; - for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) - { - IP6 diff1; - IP6 diff2; - - cur = arr[i].key; - ip6_sub(&cur->lower, &pageunion.lower, &diff1); - ip6_sub(&pageunion.upper, &cur->upper, &diff2); - - if (ip6_lessthan(&diff1,&diff2)) - ADDLIST(listL, unionL, posL, arr[i].pos); - else if (ip6_equal(&diff1,&diff2)) - { - if (posL > posR) - ADDLIST(listR, unionR, posR, arr[i].pos); - else - ADDLIST(listL, unionL, posL, arr[i].pos); - } - else - ADDLIST(listR, unionR, posR, arr[i].pos); - } - pfree(arr); - } + for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) + { + IP6 diff1; + IP6 diff2; + + cur = (IP6R *) DatumGetPointer(ent[i].key); + ip6_sub(&cur->lower, &pageunion.lower, &diff1); + ip6_sub(&pageunion.upper, &cur->upper, &diff2); + if (ip6_lessthan(&diff1,&diff2)) + ADDLIST(listL, unionL, posL, i); + else + ADDLIST(listR, unionR, posR, i); + } + + /* bad disposition, sort by ascending size and resplit */ + if (posR == 0 || posL == 0) + { + struct gip6r_sort *arr = (struct gip6r_sort *) + palloc(sizeof(struct gip6r_sort) * (maxoff + FirstOffsetNumber)); + + for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) + { + arr[i].key = (IP6R *) DatumGetPointer(ent[i].key); + arr[i].pos = i; + } - v->spl_nleft = posL; - v->spl_nright = posR; + qsort(arr + FirstOffsetNumber, + maxoff - FirstOffsetNumber + 1, + sizeof(struct gip6r_sort), + gip6r_sort_compare); - PG_RETURN_POINTER(v); + posL = posR = 0; + for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) + { + IP6 diff1; + IP6 diff2; + + cur = arr[i].key; + ip6_sub(&cur->lower, &pageunion.lower, &diff1); + ip6_sub(&pageunion.upper, &cur->upper, &diff2); + + if (ip6_lessthan(&diff1,&diff2)) + ADDLIST(listL, unionL, posL, arr[i].pos); + else if (ip6_equal(&diff1,&diff2)) + { + if (posL > posR) + ADDLIST(listR, unionR, posR, arr[i].pos); + else + ADDLIST(listL, unionL, posL, arr[i].pos); + } + else + ADDLIST(listR, unionR, posR, arr[i].pos); + } + pfree(arr); + } + + v->spl_nleft = posL; + v->spl_nright = posR; + + PG_RETURN_POINTER(v); } #undef ADDLIST @@ -1794,31 +1791,31 @@ Datum gip6r_same(PG_FUNCTION_ARGS) { - IP6R *v1 = (IP6R *) PG_GETARG_POINTER(0); - IP6R *v2 = (IP6R *) PG_GETARG_POINTER(1); - bool *result = (bool *) PG_GETARG_POINTER(2); - - if (v1 && v2) - *result = ip6r_equal(v1,v2); - else - *result = (v1 == NULL && v2 == NULL); + IP6R *v1 = (IP6R *) PG_GETARG_POINTER(0); + IP6R *v2 = (IP6R *) PG_GETARG_POINTER(1); + bool *result = (bool *) PG_GETARG_POINTER(2); + + if (v1 && v2) + *result = ip6r_equal(v1,v2); + else + *result = (v1 == NULL && v2 == NULL); #ifdef GIST_DEBUG - fprintf(stderr, "same: %s\n", (*result ? "true" : "false")); + fprintf(stderr, "same: %s\n", (*result ? "true" : "false")); #endif - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(result); } /* * Strategy numbers: - * OPERATOR 1 >>= , - * OPERATOR 2 <<= , - * OPERATOR 3 >> , - * OPERATOR 4 << , - * OPERATOR 5 && , - * OPERATOR 6 = , + * OPERATOR 1 >>= , + * OPERATOR 2 <<= , + * OPERATOR 3 >> , + * OPERATOR 4 << , + * OPERATOR 5 && , + * OPERATOR 6 = , */ /* @@ -1826,30 +1823,30 @@ */ static bool gip6r_leaf_consistent(IP6R * key, - IP6R * query, - StrategyNumber strategy) + IP6R * query, + StrategyNumber strategy) { #ifdef GIST_QUERY_DEBUG - fprintf(stderr, "leaf_consistent, %d\n", strategy); + fprintf(stderr, "leaf_consistent, %d\n", strategy); #endif - switch (strategy) - { - case 1: /* left contains right nonstrict */ - return ip6r_contains_internal(key, query, true); - case 2: /* left contained in right nonstrict */ - return ip6r_contains_internal(query, key, true); - case 3: /* left contains right strict */ - return ip6r_contains_internal(key, query, false); - case 4: /* left contained in right strict */ - return ip6r_contains_internal(query, key, false); - case 5: /* left overlaps right */ - return ip6r_overlaps_internal(key, query); - case 6: /* left equal right */ - return ip6r_equal(key, query); - default: - return false; - } + switch (strategy) + { + case 1: /* left contains right nonstrict */ + return ip6r_contains_internal(key, query, true); + case 2: /* left contained in right nonstrict */ + return ip6r_contains_internal(query, key, true); + case 3: /* left contains right strict */ + return ip6r_contains_internal(key, query, false); + case 4: /* left contained in right strict */ + return ip6r_contains_internal(query, key, false); + case 5: /* left overlaps right */ + return ip6r_overlaps_internal(key, query); + case 6: /* left equal right */ + return ip6r_equal(key, query); + default: + return false; + } } /* logic notes: @@ -1866,27 +1863,27 @@ bool gip6r_internal_consistent(IP6R * key, - IP6R * query, - StrategyNumber strategy) + IP6R * query, + StrategyNumber strategy) { #ifdef GIST_QUERY_DEBUG - fprintf(stderr, "internal_consistent, %d\n", strategy); + fprintf(stderr, "internal_consistent, %d\n", strategy); #endif - switch (strategy) - { - case 2: /* left contained in right nonstrict */ - case 4: /* left contained in right strict */ - case 5: /* left overlaps right */ - return ip6r_overlaps_internal(key, query); - case 3: /* left contains right strict */ - return ip6r_contains_internal(key, query, false); - case 1: /* left contains right nonstrict */ - case 6: /* left equal right */ - return ip6r_contains_internal(key, query, true); - default: - return false; - } + switch (strategy) + { + case 2: /* left contained in right nonstrict */ + case 4: /* left contained in right strict */ + case 5: /* left overlaps right */ + return ip6r_overlaps_internal(key, query); + case 3: /* left contains right strict */ + return ip6r_contains_internal(key, query, false); + case 1: /* left contains right nonstrict */ + case 6: /* left equal right */ + return ip6r_contains_internal(key, query, true); + default: + return false; + } } /* end */ diff -Nru ip4r-2.4.1/src/ip6r_funcs.h ip4r-2.4.2/src/ip6r_funcs.h --- ip4r-2.4.1/src/ip6r_funcs.h 2019-05-22 02:04:18.000000000 +0000 +++ ip4r-2.4.2/src/ip6r_funcs.h 2023-07-29 17:52:21.000000000 +0000 @@ -9,31 +9,31 @@ static inline uint64 hostmask6_hi(unsigned masklen) { - if (masklen >= 64) - return 0; - if (masklen == 0) - return ~((uint64)0); - return (((uint64)(1U)) << (64-masklen)) - 1U; + if (masklen >= 64) + return 0; + if (masklen == 0) + return ~((uint64)0); + return (((uint64)(1U)) << (64-masklen)) - 1U; } static inline uint64 hostmask6_lo(unsigned masklen) { - if (masklen <= 64) - return ~((uint64)0); - return (((uint64)(1U)) << (128-masklen)) - 1U; + if (masklen <= 64) + return ~((uint64)0); + return (((uint64)(1U)) << (128-masklen)) - 1U; } static inline uint64 netmask6_hi(unsigned masklen) { - return ~hostmask6_hi(masklen); + return ~hostmask6_hi(masklen); } static inline uint64 netmask6_lo(unsigned masklen) { - return ~hostmask6_lo(masklen); + return ~hostmask6_lo(masklen); } /* if LO and HI are ends of a CIDR prefix, return the mask length. @@ -43,84 +43,84 @@ static inline unsigned masklen64(uint64 lo, uint64 hi, int offset) { - uint64 d = (lo ^ hi) + 1; - int t = 0; - int b; - - /* at this point, d can be: - * 0 if A and B have all bits different - * 1 if A and B are equal - * 1 << (64-masklen) - * some other value if A and B are not ends of a CIDR range - * but in any case, after extracting the masklen, we have to - * recheck because some non-CIDR ranges will produce the same - * results. - */ - if (d == 0) - return (lo == 0 && hi == ~((uint64)0)) ? offset : ~0; - if (d == 1) - return (lo == hi) ? 64+offset : ~0; - - if (!(d & 0xFFFFFFFFUL)) - { - t = 32; - d >>= 32; - } - - b = ffs((uint32) d); - if ((((uint32)1U) << (b-1)) != d) - return ~0; - - { - uint64 mask = ((uint64)(1U) << (t+b-1)) - 1U; - if ((lo & mask) == 0 && (hi & mask) == mask) - return 65-t-b + offset; - } + uint64 d = (lo ^ hi) + 1; + int t = 0; + int b; + + /* at this point, d can be: + * 0 if A and B have all bits different + * 1 if A and B are equal + * 1 << (64-masklen) + * some other value if A and B are not ends of a CIDR range + * but in any case, after extracting the masklen, we have to + * recheck because some non-CIDR ranges will produce the same + * results. + */ + if (d == 0) + return (lo == 0 && hi == ~((uint64)0)) ? offset : ~0; + if (d == 1) + return (lo == hi) ? 64+offset : ~0; + + if (!(d & 0xFFFFFFFFUL)) + { + t = 32; + d >>= 32; + } + + b = ffs((uint32) d); + if ((((uint32)1U) << (b-1)) != d) + return ~0; - return ~0; + { + uint64 mask = ((uint64)(1U) << (t+b-1)) - 1U; + if ((lo & mask) == 0 && (hi & mask) == mask) + return 65-t-b + offset; + } + + return ~0; } static inline unsigned masklen6(IP6 *lo, IP6 *hi) { - if (lo->bits[0] == hi->bits[0]) /* masklen >= 64 */ - { - return masklen64(lo->bits[1], hi->bits[1], 64); - } - else /* masklen < 64 */ - { - if (lo->bits[1] != 0 || hi->bits[1] != ~((uint64)0)) - return ~0U; - return masklen64(lo->bits[0], hi->bits[0], 0); - } + if (lo->bits[0] == hi->bits[0]) /* masklen >= 64 */ + { + return masklen64(lo->bits[1], hi->bits[1], 64); + } + else /* masklen < 64 */ + { + if (lo->bits[1] != 0 || hi->bits[1] != ~((uint64)0)) + return ~0U; + return masklen64(lo->bits[0], hi->bits[0], 0); + } } static inline bool ip6_valid_netmask(uint64 maskhi, uint64 masklo) { - uint64 d; - int fbit; + uint64 d; + int fbit; + + if (maskhi == ~((uint64)0)) + d = ~masklo + 1; + else if (masklo == 0) + d = ~maskhi + 1; + else + return false; + + /* at this point, d can be: + * 0 if mask was 0x00000000 (valid) + * 1 << (32-masklen) (valid) + * some other value (invalid) + */ - if (maskhi == ~((uint64)0)) - d = ~masklo + 1; - else if (masklo == 0) - d = ~maskhi + 1; - else - return false; - - /* at this point, d can be: - * 0 if mask was 0x00000000 (valid) - * 1 << (32-masklen) (valid) - * some other value (invalid) - */ - - if (!(d & 0xFFFFFFFFUL)) - d >>= 32; - if (!d) - return true; + if (!(d & 0xFFFFFFFFUL)) + d >>= 32; + if (!d) + return true; - fbit = ffs((uint32)d); - return ((uint32)(1U) << (fbit-1)) == d; + fbit = ffs((uint32)d); + return ((uint32)(1U) << (fbit-1)) == d; } static inline @@ -170,31 +170,31 @@ static inline bool ip6_equal(IP6 *a, IP6 *b) { - return (a->bits[0] == b->bits[0]) && (a->bits[1] == b->bits[1]); + return (a->bits[0] == b->bits[0]) && (a->bits[1] == b->bits[1]); } static inline int ip6_compare(IP6 *a, IP6 *b) { - if (a->bits[0] != b->bits[0]) - return (a->bits[0] > b->bits[0]) ? 1 : -1; - if (a->bits[1] != b->bits[1]) - return (a->bits[1] > b->bits[1]) ? 1 : -1; - return 0; + if (a->bits[0] != b->bits[0]) + return (a->bits[0] > b->bits[0]) ? 1 : -1; + if (a->bits[1] != b->bits[1]) + return (a->bits[1] > b->bits[1]) ? 1 : -1; + return 0; } static inline bool ip6_lessthan(IP6 *a, IP6 *b) { - return ( (a->bits[0] < b->bits[0]) - || ((a->bits[0] == b->bits[0]) && (a->bits[1] < b->bits[1])) ); + return ( (a->bits[0] < b->bits[0]) + || ((a->bits[0] == b->bits[0]) && (a->bits[1] < b->bits[1])) ); } static inline void ip6_sub(IP6 *minuend, IP6 *subtrahend, IP6 *result) { - result->bits[1] = minuend->bits[1] - subtrahend->bits[1]; - result->bits[0] = minuend->bits[0] - subtrahend->bits[0] - (minuend->bits[1] < subtrahend->bits[1]); + result->bits[1] = minuend->bits[1] - subtrahend->bits[1]; + result->bits[0] = minuend->bits[0] - subtrahend->bits[0] - (minuend->bits[1] < subtrahend->bits[1]); } static inline @@ -202,16 +202,16 @@ { uint64 res_lo; - if (subtrahend >= 0) - { - res_lo = minuend->bits[1] - (uint64)(subtrahend); - result->bits[0] = minuend->bits[0] - (res_lo > minuend->bits[1]); - } - else - { - res_lo = minuend->bits[1] + (uint64)(-subtrahend); - result->bits[0] = minuend->bits[0] + (res_lo < minuend->bits[1]); - } + if (subtrahend >= 0) + { + res_lo = minuend->bits[1] - (uint64)(subtrahend); + result->bits[0] = minuend->bits[0] - (res_lo > minuend->bits[1]); + } + else + { + res_lo = minuend->bits[1] + (uint64)(-subtrahend); + result->bits[0] = minuend->bits[0] + (res_lo < minuend->bits[1]); + } result->bits[1] = res_lo; } @@ -226,13 +226,13 @@ * * val CMP (base OP offset) is equivalent to: * (val - base) CMP (offset) when OP=+, - * note that if (base > val) then - * (val - base) <= offset is known true, - * (val - base) >= offset is known false, + * note that if (base > val) then + * (val - base) <= offset is known true, + * (val - base) >= offset is known false, * (offset) CMP (base - val) when OP=-, - * note that if (val > base) then - * offset >= (base - val) is known true, - * offset <= (base - val) is known false, + * note that if (val > base) then + * offset >= (base - val) is known true, + * offset <= (base - val) is known false, * so we can choose to do all of these tests in a way that * avoids underflow of val - base. */ @@ -279,30 +279,30 @@ static inline bool ip6r_from_cidr(IP6 *prefix, unsigned masklen, IP6R *ipr) { - uint64 mask_lo = hostmask6_lo(masklen); - uint64 mask_hi = hostmask6_hi(masklen); - if (masklen > 128) - return false; - if ((prefix->bits[0] & mask_hi) || (prefix->bits[1] & mask_lo)) - return false; - ipr->upper.bits[0] = (prefix->bits[0] | mask_hi); - ipr->upper.bits[1] = (prefix->bits[1] | mask_lo); - ipr->lower = *prefix; - return true; + uint64 mask_lo = hostmask6_lo(masklen); + uint64 mask_hi = hostmask6_hi(masklen); + if (masklen > 128) + return false; + if ((prefix->bits[0] & mask_hi) || (prefix->bits[1] & mask_lo)) + return false; + ipr->upper.bits[0] = (prefix->bits[0] | mask_hi); + ipr->upper.bits[1] = (prefix->bits[1] | mask_lo); + ipr->lower = *prefix; + return true; } static inline bool ip6r_from_inet(IP6 *addr, unsigned masklen, IP6R *ipr) { - uint64 mask_lo = hostmask6_lo(masklen); - uint64 mask_hi = hostmask6_hi(masklen); - if (masklen > 128) - return false; - ipr->lower.bits[0] = (addr->bits[0] & ~mask_hi); - ipr->lower.bits[1] = (addr->bits[1] & ~mask_lo); - ipr->upper.bits[0] = (addr->bits[0] | mask_hi); - ipr->upper.bits[1] = (addr->bits[1] | mask_lo); - return true; + uint64 mask_lo = hostmask6_lo(masklen); + uint64 mask_hi = hostmask6_hi(masklen); + if (masklen > 128) + return false; + ipr->lower.bits[0] = (addr->bits[0] & ~mask_hi); + ipr->lower.bits[1] = (addr->bits[1] & ~mask_lo); + ipr->upper.bits[0] = (addr->bits[0] | mask_hi); + ipr->upper.bits[1] = (addr->bits[1] | mask_lo); + return true; } static inline @@ -324,9 +324,9 @@ * We know that all these cases are impossible because the CIDR check * would catch them: * - * lo==hi - * lo==0 && hi==~0 - * lo==~0 + * lo==hi + * lo==0 && hi==~0 + * lo==~0 * * Therefore this loop must terminate before the mask overflows */ @@ -365,57 +365,57 @@ static inline IP6R *ip6r_union_internal(IP6R *a, IP6R *b, IP6R *result) { - if (ip6_lessthan(&a->lower,&b->lower)) - result->lower = a->lower; - else - result->lower = b->lower; - - if (ip6_lessthan(&b->upper,&a->upper)) - result->upper = a->upper; - else - result->upper = b->upper; + if (ip6_lessthan(&a->lower,&b->lower)) + result->lower = a->lower; + else + result->lower = b->lower; + + if (ip6_lessthan(&b->upper,&a->upper)) + result->upper = a->upper; + else + result->upper = b->upper; - return result; + return result; } static inline IP6R *ip6r_inter_internal(IP6R *a, IP6R *b, IP6R *result) { - if (ip6_lessthan(&a->upper,&b->lower) || ip6_lessthan(&b->upper,&a->lower)) - { - /* disjoint */ - result->lower.bits[0] = 0; - result->lower.bits[1] = 1; - result->upper.bits[0] = 0; /* INVALID VALUE */ - result->upper.bits[1] = 0; /* INVALID VALUE */ - return NULL; - } - - if (ip6_lessthan(&a->upper,&b->upper)) - result->upper = a->upper; - else - result->upper = b->upper; - - if (ip6_lessthan(&b->lower,&a->lower)) - result->lower = a->lower; - else - result->lower = b->lower; + if (ip6_lessthan(&a->upper,&b->lower) || ip6_lessthan(&b->upper,&a->lower)) + { + /* disjoint */ + result->lower.bits[0] = 0; + result->lower.bits[1] = 1; + result->upper.bits[0] = 0; /* INVALID VALUE */ + result->upper.bits[1] = 0; /* INVALID VALUE */ + return NULL; + } + + if (ip6_lessthan(&a->upper,&b->upper)) + result->upper = a->upper; + else + result->upper = b->upper; + + if (ip6_lessthan(&b->lower,&a->lower)) + result->lower = a->lower; + else + result->lower = b->lower; - return result; + return result; } static inline double ip6r_metric(IP6R *v) { - IP6 diff; - double res = 0.0; - if (!v) - return res; + IP6 diff; + double res = 0.0; + if (!v) + return res; - ip6_sub(&v->upper, &v->lower, &diff); + ip6_sub(&v->upper, &v->lower, &diff); - return ( (ldexp((double)diff.bits[0],64)) - + (diff.bits[1] + 1.0) ); + return ( (ldexp((double)diff.bits[0],64)) + + (diff.bits[1] + 1.0) ); } /* comparisons */ @@ -423,50 +423,50 @@ static inline bool ip6_less_eq(IP6 *a, IP6 *b) { - return !ip6_lessthan(b,a); + return !ip6_lessthan(b,a); } static inline bool ip6r_equal(IP6R *a, IP6R *b) { - return ip6_equal(&a->lower,&b->lower) && ip6_equal(&a->upper,&b->upper); + return ip6_equal(&a->lower,&b->lower) && ip6_equal(&a->upper,&b->upper); } static inline bool ip6r_lessthan(IP6R *a, IP6R *b) { - switch (ip6_compare(&a->lower,&b->lower)) - { - default: return ip6_lessthan(&a->upper,&b->upper); - case -1: return true; - case 1: return false; - } + switch (ip6_compare(&a->lower,&b->lower)) + { + default: return ip6_lessthan(&a->upper,&b->upper); + case -1: return true; + case 1: return false; + } } static inline bool ip6r_less_eq(IP6R *a, IP6R *b) { - return !ip6r_lessthan(b,a); + return !ip6r_lessthan(b,a); } static inline bool ip6r_contains_internal(IP6R *left, IP6R *right, bool eqval) { - if (ip6r_equal(left,right)) - return eqval; - return !ip6_lessthan(&right->lower,&left->lower) && !ip6_lessthan(&left->upper,&right->upper); + if (ip6r_equal(left,right)) + return eqval; + return !ip6_lessthan(&right->lower,&left->lower) && !ip6_lessthan(&left->upper,&right->upper); } static inline bool ip6r_overlaps_internal(IP6R *left, IP6R *right) { - return !ip6_lessthan(&left->upper,&right->lower) && !ip6_lessthan(&right->upper,&left->lower); + return !ip6_lessthan(&left->upper,&right->lower) && !ip6_lessthan(&right->upper,&left->lower); } static inline bool ip6_contains_internal(IP6R *left, IP6 *right) { - return !ip6_lessthan(right,&left->lower) && !ip6_lessthan(&left->upper,right); + return !ip6_lessthan(right,&left->lower) && !ip6_lessthan(&left->upper,right); } /* end */ diff -Nru ip4r-2.4.1/src/ipaddr.c ip4r-2.4.2/src/ipaddr.c --- ip4r-2.4.1/src/ipaddr.c 2019-05-22 02:04:18.000000000 +0000 +++ ip4r-2.4.2/src/ipaddr.c 2023-07-29 17:52:21.000000000 +0000 @@ -44,7 +44,7 @@ Datum ipaddr_transform_1d(Datum d, PGFunction ip4func, PGFunction ip6func) { - IP_P ipp = DatumGetIP_P(d); + IP_P ipp = DatumGetIP_P(d); IP ip; int af = ip_unpack(ipp, &ip); @@ -67,7 +67,7 @@ IP_P ipaddr_transform_1(Datum d, PGFunction ip4func, PGFunction ip6func) { - IP_P ipp = DatumGetIP_P(d); + IP_P ipp = DatumGetIP_P(d); IP ip; int af = ip_unpack(ipp, &ip); @@ -85,7 +85,7 @@ ipaddr_internal_error(); } - return ip_pack(af, &ip); + return ip_pack(af, &ip); } @@ -95,7 +95,7 @@ IP_P ipaddr_transform_2d(Datum d1, Datum d2, PGFunction ip4func, PGFunction ip6func) { - IP_P ipp = DatumGetIP_P(d1); + IP_P ipp = DatumGetIP_P(d1); IP ip; int af = ip_unpack(ipp, &ip); @@ -113,7 +113,7 @@ ipaddr_internal_error(); } - return ip_pack(af, &ip); + return ip_pack(af, &ip); } /* func(IP,IP) returns IP; it's an error for the source IPs to be in different families */ @@ -122,8 +122,8 @@ IP_P ipaddr_transform_2(Datum d1, Datum d2, PGFunction ip4func, PGFunction ip6func) { - IP_P ipp1 = DatumGetIP_P(d1); - IP_P ipp2 = DatumGetIP_P(d2); + IP_P ipp1 = DatumGetIP_P(d1); + IP_P ipp2 = DatumGetIP_P(d2); IP ip1; IP ip2; IP out; @@ -149,7 +149,7 @@ ipaddr_internal_error(); } - return ip_pack(af1, &out); + return ip_pack(af1, &out); } @@ -164,21 +164,21 @@ text * make_text(char *str, int len) { - text *ret = (text *) palloc(len + VARHDRSZ); - SET_VARSIZE(ret, len + VARHDRSZ); - if (str) - memcpy(VARDATA(ret), str, len); - else - memset(VARDATA(ret), 0, len); - return ret; + text *ret = (text *) palloc(len + VARHDRSZ); + SET_VARSIZE(ret, len + VARHDRSZ); + if (str) + memcpy(VARDATA(ret), str, len); + else + memset(VARDATA(ret), 0, len); + return ret; } static inline void set_text_len(text *txt, int len) { - if ((len + VARHDRSZ) < VARSIZE(txt)) - SET_VARSIZE(txt, len + VARHDRSZ); + if ((len + VARHDRSZ) < VARSIZE(txt)) + SET_VARSIZE(txt, len + VARHDRSZ); } @@ -190,7 +190,7 @@ Datum ipaddr_in(PG_FUNCTION_ARGS) { - char *str = PG_GETARG_CSTRING(0); + char *str = PG_GETARG_CSTRING(0); IP ip; if (strchr(str,':')) @@ -204,18 +204,17 @@ PG_RETURN_IP_P(ip_pack(PGSQL_AF_INET, &ip)); } - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid IP value: '%s'", str))); - PG_RETURN_NULL(); + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid IP value: '%s'", str))); } PG_FUNCTION_INFO_V1(ipaddr_out); Datum ipaddr_out(PG_FUNCTION_ARGS) { - IP_P ipp = PG_GETARG_IP_P(0); - char *out = palloc(IP6_STRING_MAX); + IP_P ipp = PG_GETARG_IP_P(0); + char *out = palloc(IP6_STRING_MAX); IP ip; switch (ip_unpack(ipp, &ip)) @@ -228,14 +227,14 @@ break; } - PG_RETURN_CSTRING(out); + PG_RETURN_CSTRING(out); } PG_FUNCTION_INFO_V1(ipaddr_recv); Datum ipaddr_recv(PG_FUNCTION_ARGS) { - StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); IP ip; int af, bits, nbytes; @@ -243,18 +242,18 @@ af = pq_getmsgbyte(buf); if (af != PGSQL_AF_INET && af != PGSQL_AF_INET6) - ereport(ERROR, + ereturn(fcinfo->context, (Datum)0, (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), errmsg("invalid address family in external IP value"))); bits = pq_getmsgbyte(buf); if (bits != ipr_af_maxbits(af)) - ereport(ERROR, + ereturn(fcinfo->context, (Datum)0, (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), errmsg("invalid bit length in external IP value"))); - (void) pq_getmsgbyte(buf); /* ignore flag */ + (void) pq_getmsgbyte(buf); /* ignore flag */ nbytes = pq_getmsgbyte(buf); if (nbytes*8 != bits) - ereport(ERROR, + ereturn(fcinfo->context, (Datum)0, (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), errmsg("invalid address length in external IP value"))); @@ -277,12 +276,12 @@ Datum ipaddr_send(PG_FUNCTION_ARGS) { - IP_P arg1 = PG_GETARG_IP_P(0); - StringInfoData buf; + IP_P arg1 = PG_GETARG_IP_P(0); + StringInfoData buf; IP ip; int af = ip_unpack(arg1, &ip); - pq_begintypsend(&buf); + pq_begintypsend(&buf); pq_sendbyte(&buf, af); pq_sendbyte(&buf, (int8) ipr_af_maxbits(af)); pq_sendbyte(&buf, 1); @@ -300,36 +299,36 @@ break; } - PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); } PG_FUNCTION_INFO_V1(ipaddr_hash); Datum ipaddr_hash(PG_FUNCTION_ARGS) { - IP_P arg1 = PG_GETARG_IP_P(0); + IP_P arg1 = PG_GETARG_IP_P(0); - return hash_any((void*)(VARDATA_ANY(arg1)), VARSIZE_ANY_EXHDR(arg1)); + return hash_any((void*)(VARDATA_ANY(arg1)), VARSIZE_ANY_EXHDR(arg1)); } PG_FUNCTION_INFO_V1(ipaddr_hash_extended); Datum ipaddr_hash_extended(PG_FUNCTION_ARGS) { - IP_P arg1 = PG_GETARG_IP_P(0); + IP_P arg1 = PG_GETARG_IP_P(0); uint64 seed = DatumGetUInt64(PG_GETARG_DATUM(1)); - return hash_any_extended((void*)(VARDATA_ANY(arg1)), VARSIZE_ANY_EXHDR(arg1), seed); + return hash_any_extended((void*)(VARDATA_ANY(arg1)), VARSIZE_ANY_EXHDR(arg1), seed); } PG_FUNCTION_INFO_V1(ipaddr_cast_to_text); Datum ipaddr_cast_to_text(PG_FUNCTION_ARGS) { - IP_P ipp = PG_GETARG_IP_P(0); + IP_P ipp = PG_GETARG_IP_P(0); IP ip; int af = ip_unpack(ipp, &ip); - text *out = NULL; + text *out = NULL; switch (af) { @@ -343,23 +342,23 @@ break; } - PG_RETURN_TEXT_P(out); + PG_RETURN_TEXT_P(out); } PG_FUNCTION_INFO_V1(ipaddr_cast_from_text); Datum ipaddr_cast_from_text(PG_FUNCTION_ARGS) { - text *txt = PG_GETARG_TEXT_PP(0); - int tlen = VARSIZE_ANY_EXHDR(txt); - char buf[IP6_STRING_MAX]; + text *txt = PG_GETARG_TEXT_PP(0); + int tlen = VARSIZE_ANY_EXHDR(txt); + char buf[IP6_STRING_MAX]; - if (tlen < sizeof(buf)) - { + if (tlen < sizeof(buf)) + { IP ip; - memcpy(buf, VARDATA_ANY(txt), tlen); - buf[tlen] = 0; + memcpy(buf, VARDATA_ANY(txt), tlen); + buf[tlen] = 0; if (strchr(buf,':')) { @@ -371,20 +370,19 @@ if (ip4_raw_input(buf, &ip.ip4)) PG_RETURN_IP_P(ip_pack(PGSQL_AF_INET, &ip)); } - } + } - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid IP value in text"))); - PG_RETURN_NULL(); + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid IP value in text"))); } PG_FUNCTION_INFO_V1(ipaddr_cast_from_inet); Datum ipaddr_cast_from_inet(PG_FUNCTION_ARGS) { - inet *inetptr = PG_GETARG_INET_P(0); - inet_struct *in = INET_STRUCT_DATA(inetptr); + inet *inetptr = PG_GETARG_INET_P(0); + inet_struct *in = INET_STRUCT_DATA(inetptr); IP ip; switch (in->family) @@ -397,10 +395,9 @@ PG_RETURN_IP_P(ip_pack(PGSQL_AF_INET6, &ip)); } - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid INET value for conversion to IP"))); - PG_RETURN_NULL(); + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid INET value for conversion to IP"))); } PG_FUNCTION_INFO_V1(ipaddr_cast_to_cidr); @@ -454,10 +451,9 @@ PG_RETURN_IP4(ip.ip4); } - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid IP value in cast to IP4"))); - PG_RETURN_NULL(); + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid IP value in cast to IP4"))); } PG_FUNCTION_INFO_V1(ipaddr_cast_to_ip6); @@ -474,10 +470,9 @@ PG_RETURN_IP6_P(out); } - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid IP value in cast to IP4"))); - PG_RETURN_NULL(); + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid IP value in cast to IP4"))); } PG_FUNCTION_INFO_V1(ipaddr_cast_from_bit); @@ -497,10 +492,9 @@ PG_RETURN_IP_P(ip_pack(PGSQL_AF_INET6, &ip)); } - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid BIT value for conversion to IPADDRESS"))); - PG_RETURN_NULL(); + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid BIT value for conversion to IPADDRESS"))); } PG_FUNCTION_INFO_V1(ipaddr_cast_to_bit); @@ -527,10 +521,9 @@ PG_RETURN_IP_P(ip_pack(PGSQL_AF_INET6, &ip)); } - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid BYTEA value for conversion to IPADDRESS"))); - PG_RETURN_NULL(); + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid BYTEA value for conversion to IPADDRESS"))); } PG_FUNCTION_INFO_V1(ipaddr_cast_to_bytea); @@ -559,65 +552,65 @@ Datum ipaddr_net_lower(PG_FUNCTION_ARGS) { - PG_RETURN_IP_P(ipaddr_transform_2d(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), ip4_net_lower, ip6_net_lower)); + PG_RETURN_IP_P(ipaddr_transform_2d(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), ip4_net_lower, ip6_net_lower)); } PG_FUNCTION_INFO_V1(ipaddr_net_upper); Datum ipaddr_net_upper(PG_FUNCTION_ARGS) { - PG_RETURN_IP_P(ipaddr_transform_2d(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), ip4_net_upper, ip6_net_upper)); + PG_RETURN_IP_P(ipaddr_transform_2d(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), ip4_net_upper, ip6_net_upper)); } PG_FUNCTION_INFO_V1(ipaddr_plus_int); Datum ipaddr_plus_int(PG_FUNCTION_ARGS) { - PG_RETURN_IP_P(ipaddr_transform_2d(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), ip4_plus_int, ip6_plus_int)); + PG_RETURN_IP_P(ipaddr_transform_2d(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), ip4_plus_int, ip6_plus_int)); } PG_FUNCTION_INFO_V1(ipaddr_plus_bigint); Datum ipaddr_plus_bigint(PG_FUNCTION_ARGS) { - PG_RETURN_IP_P(ipaddr_transform_2d(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), ip4_plus_bigint, ip6_plus_bigint)); + PG_RETURN_IP_P(ipaddr_transform_2d(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), ip4_plus_bigint, ip6_plus_bigint)); } PG_FUNCTION_INFO_V1(ipaddr_plus_numeric); Datum ipaddr_plus_numeric(PG_FUNCTION_ARGS) { - PG_RETURN_IP_P(ipaddr_transform_2d(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), ip4_plus_numeric, ip6_plus_numeric)); + PG_RETURN_IP_P(ipaddr_transform_2d(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), ip4_plus_numeric, ip6_plus_numeric)); } PG_FUNCTION_INFO_V1(ipaddr_minus_int); Datum ipaddr_minus_int(PG_FUNCTION_ARGS) { - PG_RETURN_IP_P(ipaddr_transform_2d(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), ip4_minus_int, ip6_minus_int)); + PG_RETURN_IP_P(ipaddr_transform_2d(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), ip4_minus_int, ip6_minus_int)); } PG_FUNCTION_INFO_V1(ipaddr_minus_bigint); Datum ipaddr_minus_bigint(PG_FUNCTION_ARGS) { - PG_RETURN_IP_P(ipaddr_transform_2d(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), ip4_minus_bigint, ip6_minus_bigint)); + PG_RETURN_IP_P(ipaddr_transform_2d(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), ip4_minus_bigint, ip6_minus_bigint)); } PG_FUNCTION_INFO_V1(ipaddr_minus_numeric); Datum ipaddr_minus_numeric(PG_FUNCTION_ARGS) { - PG_RETURN_IP_P(ipaddr_transform_2d(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), ip4_minus_numeric, ip6_minus_numeric)); + PG_RETURN_IP_P(ipaddr_transform_2d(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), ip4_minus_numeric, ip6_minus_numeric)); } PG_FUNCTION_INFO_V1(ipaddr_minus_ipaddr); Datum ipaddr_minus_ipaddr(PG_FUNCTION_ARGS) { - Datum minuend = PG_GETARG_DATUM(0); - Datum subtrahend = PG_GETARG_DATUM(1); - Datum res; + Datum minuend = PG_GETARG_DATUM(0); + Datum subtrahend = PG_GETARG_DATUM(1); + Datum res; IP ip1; IP ip2; int af1 = ip_unpack(DatumGetIP_P(minuend), &ip1); @@ -646,7 +639,7 @@ ipaddr_internal_error(); } - PG_RETURN_DATUM(res); + PG_RETURN_DATUM(res); } PG_FUNCTION_INFO_V1(ipaddr_and); @@ -691,8 +684,8 @@ bool mismatch_af1, bool mismatch_af2, PGFunction ip4func, PGFunction ip6func) { - IP_P ipp1 = DatumGetIP_P(d1); - IP_P ipp2 = DatumGetIP_P(d2); + IP_P ipp1 = DatumGetIP_P(d1); + IP_P ipp2 = DatumGetIP_P(d2); IP ip1; IP ip2; int af1 = ip_unpack(ipp1, &ip1); @@ -725,7 +718,7 @@ if ((Pointer)ipp2 != DatumGetPointer(d2)) pfree(ipp2); - return retval; + return retval; } PG_FUNCTION_INFO_V1(ipaddr_lt); @@ -790,14 +783,14 @@ /***************************************************************************** - * Btree functions + * Btree functions *****************************************************************************/ PG_FUNCTION_INFO_V1(ipaddr_cmp); Datum ipaddr_cmp(PG_FUNCTION_ARGS) { - IP_P ipp1 = PG_GETARG_IP_P(0); + IP_P ipp1 = PG_GETARG_IP_P(0); IP_P ipp2 = PG_GETARG_IP_P(1); IP ip1; IP ip2; @@ -829,7 +822,7 @@ PG_FREE_IF_COPY(ipp1,0); PG_FREE_IF_COPY(ipp2,1); - PG_RETURN_INT32(retval); + PG_RETURN_INT32(retval); } /* end */ diff -Nru ip4r-2.4.1/src/iprange.c ip4r-2.4.2/src/iprange.c --- ip4r-2.4.1/src/iprange.c 2019-05-22 02:04:18.000000000 +0000 +++ ip4r-2.4.2/src/iprange.c 2023-07-29 17:52:21.000000000 +0000 @@ -63,24 +63,24 @@ * * So we allow the following formats (excluding varlena header): * - * 0 bytes - special 'match all' range (af==0) - * 8 bytes - IP4R - * 1 byte pfxlen + 8 bytes - IP6R cidr range /64 or shorter - * 1 byte pfxlen + 16 bytes - IP6R cidr range /65 or longer - * 32 bytes - arbitrary IP6R range + * 0 bytes - special 'match all' range (af==0) + * 8 bytes - IP4R + * 1 byte pfxlen + 8 bytes - IP6R cidr range /64 or shorter + * 1 byte pfxlen + 16 bytes - IP6R cidr range /65 or longer + * 32 bytes - arbitrary IP6R range */ int ipr_unpack(IPR_P in, IPR *out) { unsigned char *ptr = (unsigned char *) VARDATA_ANY(in); - switch (VARSIZE_ANY_EXHDR(in)) - { + switch (VARSIZE_ANY_EXHDR(in)) + { case 0: return 0; - case sizeof(IP4R): - memcpy(&out->ip4r, ptr, sizeof(IP4R)); + case sizeof(IP4R): + memcpy(&out->ip4r, ptr, sizeof(IP4R)); return PGSQL_AF_INET; case 1+sizeof(uint64): @@ -102,18 +102,18 @@ return PGSQL_AF_INET6; } - case sizeof(IP6R): - memcpy(&out->ip6r, ptr, sizeof(IP6R)); + case sizeof(IP6R): + memcpy(&out->ip6r, ptr, sizeof(IP6R)); return PGSQL_AF_INET6; - default: + default: iprange_internal_error(); - } + } } IPR_P ipr_pack(int af, IPR *val) { - IPR_P out = palloc(VARHDRSZ + sizeof(IP6R)); + IPR_P out = palloc(VARHDRSZ + sizeof(IP6R)); unsigned char *ptr = (unsigned char *) VARDATA(out); switch (af) @@ -172,8 +172,8 @@ Datum iprange_in(PG_FUNCTION_ARGS) { - char *str = PG_GETARG_CSTRING(0); - IPR ipr; + char *str = PG_GETARG_CSTRING(0); + IPR ipr; if (str[0] == '-' && str[1] == 0) { @@ -181,12 +181,18 @@ } else if (strchr(str,':')) { - ipr.ip6r = *DatumGetIP6RP(DirectFunctionCall1(ip6r_in,CStringGetDatum(str))); + Datum res = ip6r_in(fcinfo); + if (SOFT_ERROR_OCCURRED(fcinfo->context)) + PG_RETURN_DATUM(res); + ipr.ip6r = *DatumGetIP6RP(res); PG_RETURN_IPR_P(ipr_pack(PGSQL_AF_INET6, &ipr)); } else { - ipr.ip4r = *DatumGetIP4RP(DirectFunctionCall1(ip4r_in,CStringGetDatum(str))); + Datum res = ip4r_in(fcinfo); + if (SOFT_ERROR_OCCURRED(fcinfo->context)) + PG_RETURN_DATUM(res); + ipr.ip4r = *DatumGetIP4RP(res); PG_RETURN_IPR_P(ipr_pack(PGSQL_AF_INET, &ipr)); } } @@ -223,8 +229,8 @@ Datum iprange_recv(PG_FUNCTION_ARGS) { - StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); - IPR ipr; + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); + IPR ipr; unsigned af, bits, nbytes; /* @@ -240,20 +246,20 @@ af = pq_getmsgbyte(buf); if (af != 0 && af != PGSQL_AF_INET && af != PGSQL_AF_INET6) - ereport(ERROR, + ereturn(fcinfo->context, (Datum)0, (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), errmsg("invalid address family in external IPR value"))); bits = pq_getmsgbyte(buf); if (bits != 255 && bits > ipr_af_maxbits(af)) - ereport(ERROR, + ereturn(fcinfo->context, (Datum)0, (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), errmsg("invalid bit length in external IP value"))); - (void) pq_getmsgbyte(buf); /* ignore flag */ + (void) pq_getmsgbyte(buf); /* ignore flag */ nbytes = pq_getmsgbyte(buf); switch (af) { - case 0: /* special 'match all' range */ + case 0: /* special 'match all' range */ if (nbytes == 0) PG_RETURN_IPR_P(ipr_pack(0,NULL)); break; @@ -269,6 +275,12 @@ { ipr.ip4r.lower = (IP4) pq_getmsgint(buf, sizeof(IP4)); ipr.ip4r.upper = (IP4) pq_getmsgint(buf, sizeof(IP4)); + if (ipr.ip4r.upper < ipr.ip4r.lower) + { + IP4 t = ipr.ip4r.upper; + ipr.ip4r.upper = ipr.ip4r.lower; + ipr.ip4r.lower = t; + } PG_RETURN_IPR_P(ipr_pack(PGSQL_AF_INET,&ipr)); } break; @@ -296,25 +308,30 @@ ipr.ip6r.lower.bits[1] = (uint64) pq_getmsgint64(buf); ipr.ip6r.upper.bits[0] = (uint64) pq_getmsgint64(buf); ipr.ip6r.upper.bits[1] = (uint64) pq_getmsgint64(buf); + if (ip6_lessthan(&ipr.ip6r.upper, &ipr.ip6r.lower)) + { + IP6 t = ipr.ip6r.upper; + ipr.ip6r.upper = ipr.ip6r.lower; + ipr.ip6r.lower = t; + } PG_RETURN_IPR_P(ipr_pack(PGSQL_AF_INET6,&ipr)); } break; } - ereport(ERROR, + ereturn(fcinfo->context, (Datum)0, (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION), errmsg("invalid address length in external IPR value"))); - PG_RETURN_NULL(); } PG_FUNCTION_INFO_V1(iprange_send); Datum iprange_send(PG_FUNCTION_ARGS) { - IPR_P *iprp = PG_GETARG_IPR_P(0); + IPR_P *iprp = PG_GETARG_IPR_P(0); IPR ipr; int af = ipr_unpack(iprp, &ipr); - StringInfoData buf; + StringInfoData buf; unsigned bits = ~0; switch (af) @@ -327,7 +344,7 @@ break; } - pq_begintypsend(&buf); + pq_begintypsend(&buf); pq_sendbyte(&buf, af); pq_sendbyte(&buf, (int8) bits); pq_sendbyte(&buf, 1); @@ -375,7 +392,7 @@ break; } - PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); } /* Unfortunately due to a historical oversight, this function produces @@ -394,9 +411,9 @@ Datum iprange_hash(PG_FUNCTION_ARGS) { - IPR_P arg1 = PG_GETARG_IPR_P(0); + IPR_P arg1 = PG_GETARG_IPR_P(0); - return hash_any((void *) VARDATA_ANY(arg1), VARSIZE_ANY_EXHDR(arg1)); + return hash_any((void *) VARDATA_ANY(arg1), VARSIZE_ANY_EXHDR(arg1)); } /* below are the fixed hash functions @@ -406,7 +423,7 @@ Datum iprange_hash_new(PG_FUNCTION_ARGS) { - IPR_P arg1 = PG_GETARG_IPR_P(0); + IPR_P arg1 = PG_GETARG_IPR_P(0); IPR tmp; uint32 vsize = VARSIZE_ANY_EXHDR(arg1); @@ -423,7 +440,7 @@ Datum iprange_hash_extended(PG_FUNCTION_ARGS) { - IPR_P arg1 = PG_GETARG_IPR_P(0); + IPR_P arg1 = PG_GETARG_IPR_P(0); IPR tmp; uint32 vsize = VARSIZE_ANY_EXHDR(arg1); uint32 seed = DatumGetUInt32(PG_GETARG_DATUM(1)); @@ -441,7 +458,7 @@ Datum iprange_cast_to_text(PG_FUNCTION_ARGS) { - IPR_P iprp = PG_GETARG_IPR_P(0); + IPR_P iprp = PG_GETARG_IPR_P(0); IPR ipr; int af = ipr_unpack(iprp,&ipr); @@ -468,34 +485,41 @@ Datum iprange_cast_from_text(PG_FUNCTION_ARGS) { - text *txt = PG_GETARG_TEXT_PP(0); - int tlen = VARSIZE_ANY_EXHDR(txt); - char buf[IP6R_STRING_MAX]; - - if (tlen < sizeof(buf)) - { - memcpy(buf, VARDATA_ANY(txt), tlen); - buf[tlen] = 0; - - PG_RETURN_DATUM(DirectFunctionCall1(iprange_in, CStringGetDatum(buf))); - } - - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid IPR value in text"))); - PG_RETURN_NULL(); + text *txt = PG_GETARG_TEXT_PP(0); + int tlen = VARSIZE_ANY_EXHDR(txt); + char buf[IP6R_STRING_MAX]; + LOCAL_FCINFO(fc, 3); + Datum res; + + if (tlen < sizeof(buf)) + { + memcpy(buf, VARDATA_ANY(txt), tlen); + buf[tlen] = 0; + + InitFunctionCallInfoData(*fc, NULL, 1, fcinfo->fncollation, fcinfo->context, NULL); + LFCI_ARG_VALUE(fc, 0) = CStringGetDatum(buf); + LFCI_ARGISNULL(fc, 0) = false; + + res = iprange_in(fc); + fcinfo->isnull = fc->isnull; + return res; + } + + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid IPR value in text"))); } PG_FUNCTION_INFO_V1(iprange_cast_from_cidr); Datum iprange_cast_from_cidr(PG_FUNCTION_ARGS) { - inet *inetptr = PG_GETARG_INET_P(0); - inet_struct *in = INET_STRUCT_DATA(inetptr); + inet *inetptr = PG_GETARG_INET_P(0); + inet_struct *in = INET_STRUCT_DATA(inetptr); unsigned char *p = in->ipaddr; IPR ipr; - if (in->bits <= ipr_af_maxbits(in->family)) + if (in->bits <= ipr_af_maxbits(in->family)) { switch (in->family) { @@ -533,21 +557,20 @@ } } - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid CIDR value for conversion to IPR"))); - PG_RETURN_NULL(); + ereturn(fcinfo->context, (Datum)0, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid CIDR value for conversion to IPR"))); } PG_FUNCTION_INFO_V1(iprange_cast_to_cidr); Datum iprange_cast_to_cidr(PG_FUNCTION_ARGS) { - IPR_P iprp = PG_GETARG_IPR_P(0); + IPR_P iprp = PG_GETARG_IPR_P(0); IPR ipr; int af = ipr_unpack(iprp, &ipr); - inet *res; - inet_struct *in; + inet *res; + inet_struct *in; unsigned bits; switch (af) @@ -572,7 +595,7 @@ p[0] = (ip >> 24); p[1] = (ip >> 16); p[2] = (ip >> 8); - p[3] = (ip ); + p[3] = (ip ); } PG_RETURN_INET_P(res); @@ -621,39 +644,39 @@ Datum iprange_cast_from_ip4(PG_FUNCTION_ARGS) { - IP4 ip = PG_GETARG_IP4(0); + IP4 ip = PG_GETARG_IP4(0); IPR res; - if (ip4r_from_inet(ip, 32, &res.ip4r)) - PG_RETURN_IPR_P(ipr_pack(PGSQL_AF_INET, &res)); + if (ip4r_from_inet(ip, 32, &res.ip4r)) + PG_RETURN_IPR_P(ipr_pack(PGSQL_AF_INET, &res)); - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid IP4 value for conversion to IPR (shouldn't be possible)"))); - PG_RETURN_NULL(); + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid IP4 value for conversion to IPR (shouldn't be possible)"))); + PG_RETURN_NULL(); } PG_FUNCTION_INFO_V1(iprange_cast_from_ip6); Datum iprange_cast_from_ip6(PG_FUNCTION_ARGS) { - IP6 *ip = PG_GETARG_IP6_P(0); + IP6 *ip = PG_GETARG_IP6_P(0); IPR res; - if (ip6r_from_inet(ip, 128, &res.ip6r)) - PG_RETURN_IPR_P(ipr_pack(PGSQL_AF_INET6, &res)); + if (ip6r_from_inet(ip, 128, &res.ip6r)) + PG_RETURN_IPR_P(ipr_pack(PGSQL_AF_INET6, &res)); - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid IP6 value for conversion to IPR (shouldn't be possible)"))); - PG_RETURN_NULL(); + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid IP6 value for conversion to IPR (shouldn't be possible)"))); + PG_RETURN_NULL(); } PG_FUNCTION_INFO_V1(iprange_cast_from_ipaddr); Datum iprange_cast_from_ipaddr(PG_FUNCTION_ARGS) { - IP_P ipp = PG_GETARG_IP_P(0); + IP_P ipp = PG_GETARG_IP_P(0); IP ip; IPR res; int af = ip_unpack(ipp, &ip); @@ -671,17 +694,17 @@ break; } - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("invalid IP6 value for conversion to IPR (shouldn't be possible)"))); - PG_RETURN_NULL(); + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("invalid IP6 value for conversion to IPR (shouldn't be possible)"))); + PG_RETURN_NULL(); } PG_FUNCTION_INFO_V1(iprange_cast_from_ip4r); Datum iprange_cast_from_ip4r(PG_FUNCTION_ARGS) { - IP4R *ipr = PG_GETARG_IP4R_P(0); + IP4R *ipr = PG_GETARG_IP4R_P(0); IPR res; res.ip4r = *ipr; @@ -692,7 +715,7 @@ Datum iprange_cast_from_ip6r(PG_FUNCTION_ARGS) { - IP6R *ipr = PG_GETARG_IP6R_P(0); + IP6R *ipr = PG_GETARG_IP6R_P(0); IPR res; res.ip6r = *ipr; @@ -703,13 +726,13 @@ Datum iprange_cast_to_ip4r(PG_FUNCTION_ARGS) { - IPR_P iprp = PG_GETARG_IPR_P(0); + IPR_P iprp = PG_GETARG_IPR_P(0); IPR ipr; int af = ipr_unpack(iprp,&ipr); IP4R *res; if (af != PGSQL_AF_INET) - ereport(ERROR, + ereturn(fcinfo->context, (Datum)0, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid IPR value for conversion to IP4R"))); @@ -723,13 +746,13 @@ Datum iprange_cast_to_ip6r(PG_FUNCTION_ARGS) { - IPR_P iprp = PG_GETARG_IPR_P(0); + IPR_P iprp = PG_GETARG_IPR_P(0); IPR ipr; int af = ipr_unpack(iprp,&ipr); IP6R *res; if (af != PGSQL_AF_INET6) - ereport(ERROR, + ereturn(fcinfo->context, (Datum)0, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("invalid IPR value for conversion to IP6R"))); @@ -743,7 +766,7 @@ Datum iprange_cast_to_bit(PG_FUNCTION_ARGS) { - IPR_P iprp = PG_GETARG_IPR_P(0); + IPR_P iprp = PG_GETARG_IPR_P(0); IPR ipr; int af = ipr_unpack(iprp, &ipr); unsigned bits; @@ -765,8 +788,8 @@ IP4 ip = ipr.ip4r.lower; buf[0] = (ip >> 24); buf[1] = (ip >> 16); - buf[2] = (ip >> 8); - buf[3] = (ip ); + buf[2] = (ip >> 8); + buf[3] = (ip ); } break; @@ -823,8 +846,8 @@ Datum iprange_from_ip4s(PG_FUNCTION_ARGS) { - IP4 a = PG_GETARG_IP4(0); - IP4 b = PG_GETARG_IP4(1); + IP4 a = PG_GETARG_IP4(0); + IP4 b = PG_GETARG_IP4(1); PG_RETURN_DATUM(iprange_from_ipaddrs_internal(PGSQL_AF_INET, a, b, NULL, NULL)); } @@ -833,8 +856,8 @@ Datum iprange_from_ip6s(PG_FUNCTION_ARGS) { - IP6 *a = PG_GETARG_IP6_P(0); - IP6 *b = PG_GETARG_IP6_P(1); + IP6 *a = PG_GETARG_IP6_P(0); + IP6 *b = PG_GETARG_IP6_P(1); PG_RETURN_DATUM(iprange_from_ipaddrs_internal(PGSQL_AF_INET6, 0, 0, a, b)); } @@ -843,8 +866,8 @@ Datum iprange_from_ipaddrs(PG_FUNCTION_ARGS) { - IP_P ap = PG_GETARG_IP_P(0); - IP_P bp = PG_GETARG_IP_P(1); + IP_P ap = PG_GETARG_IP_P(0); + IP_P bp = PG_GETARG_IP_P(1); IP a,b; int af_a = ip_unpack(ap,&a); int af_b = ip_unpack(bp,&b); @@ -861,12 +884,12 @@ { IPR res; - if (pfxlen < 0 || pfxlen > ipr_af_maxbits(af)) - { - ereport(ERROR, - (errcode(ERRCODE_INVALID_PARAMETER_VALUE), - errmsg("prefix length out of range"))); - } + if (pfxlen < 0 || pfxlen > ipr_af_maxbits(af)) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("prefix length out of range"))); + } switch (af) { @@ -887,8 +910,8 @@ Datum iprange_net_prefix_ip4(PG_FUNCTION_ARGS) { - IP4 ip = PG_GETARG_IP4(0); - int pfxlen = PG_GETARG_INT32(1); + IP4 ip = PG_GETARG_IP4(0); + int pfxlen = PG_GETARG_INT32(1); PG_RETURN_DATUM(iprange_net_prefix_internal(PGSQL_AF_INET, ip, NULL, pfxlen)); } @@ -897,8 +920,8 @@ Datum iprange_net_prefix_ip6(PG_FUNCTION_ARGS) { - IP6 *ip = PG_GETARG_IP6_P(0); - int pfxlen = PG_GETARG_INT32(1); + IP6 *ip = PG_GETARG_IP6_P(0); + int pfxlen = PG_GETARG_INT32(1); PG_RETURN_DATUM(iprange_net_prefix_internal(PGSQL_AF_INET6, 0, ip, pfxlen)); } @@ -907,9 +930,9 @@ Datum iprange_net_prefix(PG_FUNCTION_ARGS) { - IP_P ipp = PG_GETARG_IP_P(0); + IP_P ipp = PG_GETARG_IP_P(0); IP ip; - int pfxlen = PG_GETARG_INT32(1); + int pfxlen = PG_GETARG_INT32(1); int af = ip_unpack(ipp,&ip); PG_RETURN_DATUM(iprange_net_prefix_internal(af, ip.ip4, &ip.ip6, pfxlen)); @@ -953,8 +976,8 @@ Datum iprange_net_mask_ip4(PG_FUNCTION_ARGS) { - IP4 ip = PG_GETARG_IP4(0); - IP4 mask = PG_GETARG_IP4(1); + IP4 ip = PG_GETARG_IP4(0); + IP4 mask = PG_GETARG_IP4(1); PG_RETURN_DATUM(iprange_net_mask_internal(PGSQL_AF_INET, ip, NULL, mask, NULL)); } @@ -963,8 +986,8 @@ Datum iprange_net_mask_ip6(PG_FUNCTION_ARGS) { - IP6 *ip = PG_GETARG_IP6_P(0); - IP6 *mask = PG_GETARG_IP6_P(1); + IP6 *ip = PG_GETARG_IP6_P(0); + IP6 *mask = PG_GETARG_IP6_P(1); PG_RETURN_DATUM(iprange_net_mask_internal(PGSQL_AF_INET6, 0, ip, 0, mask)); } @@ -973,8 +996,8 @@ Datum iprange_net_mask(PG_FUNCTION_ARGS) { - IP_P ipp = PG_GETARG_IP_P(0); - IP_P maskp = PG_GETARG_IP_P(1); + IP_P ipp = PG_GETARG_IP_P(0); + IP_P maskp = PG_GETARG_IP_P(1); IP ip XINIT(IP_INITIALIZER); IP mask XINIT(IP_INITIALIZER); int af1 = ip_unpack(ipp,&ip); @@ -990,7 +1013,7 @@ Datum iprange_lower(PG_FUNCTION_ARGS) { - IPR_P iprp = PG_GETARG_IPR_P(0); + IPR_P iprp = PG_GETARG_IPR_P(0); IPR ipr; IP ip; int af = ipr_unpack(iprp,&ipr); @@ -1018,7 +1041,7 @@ Datum iprange_upper(PG_FUNCTION_ARGS) { - IPR_P iprp = PG_GETARG_IPR_P(0); + IPR_P iprp = PG_GETARG_IPR_P(0); IPR ipr; IP ip; int af = ipr_unpack(iprp,&ipr); @@ -1046,7 +1069,7 @@ Datum iprange_is_cidr(PG_FUNCTION_ARGS) { - IPR_P iprp = PG_GETARG_IPR_P(0); + IPR_P iprp = PG_GETARG_IPR_P(0); IPR ipr; int af = ipr_unpack(iprp,&ipr); @@ -1070,7 +1093,7 @@ Datum iprange_family(PG_FUNCTION_ARGS) { - IPR_P iprp = PG_GETARG_IPR_P(0); + IPR_P iprp = PG_GETARG_IPR_P(0); IPR ipr; int af = ipr_unpack(iprp,&ipr); @@ -1142,7 +1165,7 @@ } else { - funcctx->user_fctx = NULL; /* this is the last row */ + funcctx->user_fctx = NULL; /* this is the last row */ res.ip6r.lower.bits[0] = netmask6_hi(0); res.ip6r.lower.bits[1] = netmask6_lo(0); res.ip6r.upper.bits[0] = hostmask6_hi(0); @@ -1220,49 +1243,49 @@ if ((Pointer)ipp2 != DatumGetPointer(d2)) pfree(ipp2); - return retval; + return retval; } PG_FUNCTION_INFO_V1(iprange_lt); Datum iprange_lt(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( iprange_cmp_internal(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1)) < 0 ); + PG_RETURN_BOOL( iprange_cmp_internal(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1)) < 0 ); } PG_FUNCTION_INFO_V1(iprange_le); Datum iprange_le(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( iprange_cmp_internal(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1)) <= 0 ); + PG_RETURN_BOOL( iprange_cmp_internal(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1)) <= 0 ); } PG_FUNCTION_INFO_V1(iprange_gt); Datum iprange_gt(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( iprange_cmp_internal(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1)) > 0 ); + PG_RETURN_BOOL( iprange_cmp_internal(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1)) > 0 ); } PG_FUNCTION_INFO_V1(iprange_ge); Datum iprange_ge(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( iprange_cmp_internal(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1)) >= 0 ); + PG_RETURN_BOOL( iprange_cmp_internal(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1)) >= 0 ); } PG_FUNCTION_INFO_V1(iprange_eq); Datum iprange_eq(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( iprange_cmp_internal(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1)) == 0 ); + PG_RETURN_BOOL( iprange_cmp_internal(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1)) == 0 ); } PG_FUNCTION_INFO_V1(iprange_neq); Datum iprange_neq(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( iprange_cmp_internal(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1)) != 0 ); + PG_RETURN_BOOL( iprange_cmp_internal(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1)) != 0 ); } static bool @@ -1304,7 +1327,7 @@ if ((Pointer)ipp2 != DatumGetPointer(d2)) pfree(ipp2); - return retval; + return retval; } static int @@ -1346,7 +1369,7 @@ if ((Pointer)ipp2 != DatumGetPointer(d2)) pfree(ipp2); - return retval; + return retval; } static int @@ -1383,14 +1406,14 @@ if ((Pointer)ipp1 != DatumGetPointer(d1)) pfree(ipp1); - return retval; + return retval; } PG_FUNCTION_INFO_V1(iprange_overlaps); Datum iprange_overlaps(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( iprange_overlaps_internal(PG_GETARG_DATUM(0), + PG_RETURN_BOOL( iprange_overlaps_internal(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1)) ); } @@ -1398,7 +1421,7 @@ Datum iprange_contains(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( iprange_contains_internal(PG_GETARG_DATUM(0), + PG_RETURN_BOOL( iprange_contains_internal(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), true) ); } @@ -1407,7 +1430,7 @@ Datum iprange_contains_strict(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( iprange_contains_internal(PG_GETARG_DATUM(0), + PG_RETURN_BOOL( iprange_contains_internal(PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), false) ); } @@ -1416,7 +1439,7 @@ Datum iprange_contained_by(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( iprange_contains_internal(PG_GETARG_DATUM(1), + PG_RETURN_BOOL( iprange_contains_internal(PG_GETARG_DATUM(1), PG_GETARG_DATUM(0), true) ); } @@ -1425,7 +1448,7 @@ Datum iprange_contained_by_strict(PG_FUNCTION_ARGS) { - PG_RETURN_BOOL( iprange_contains_internal(PG_GETARG_DATUM(1), + PG_RETURN_BOOL( iprange_contains_internal(PG_GETARG_DATUM(1), PG_GETARG_DATUM(0), false) ); } @@ -1464,7 +1487,7 @@ iprange_ip6_contained_by(PG_FUNCTION_ARGS) { IP6 *ip = PG_GETARG_IP6_P(0); - PG_RETURN_BOOL( iprange_contains_ip_internal(PG_GETARG_DATUM(1), PGSQL_AF_INET6, 0, ip) ); + PG_RETURN_BOOL( iprange_contains_ip_internal(PG_GETARG_DATUM(1), PGSQL_AF_INET6, 0, ip) ); } PG_FUNCTION_INFO_V1(iprange_ip4_contained_by); @@ -1472,7 +1495,7 @@ iprange_ip4_contained_by(PG_FUNCTION_ARGS) { IP4 ip = PG_GETARG_IP4(0); - PG_RETURN_BOOL( iprange_contains_ip_internal(PG_GETARG_DATUM(1), PGSQL_AF_INET, ip, NULL) ); + PG_RETURN_BOOL( iprange_contains_ip_internal(PG_GETARG_DATUM(1), PGSQL_AF_INET, ip, NULL) ); } PG_FUNCTION_INFO_V1(iprange_ip_contained_by); @@ -1561,7 +1584,7 @@ else if (af2 == 0) PG_RETURN_IPR_P(ipr_pack(af1,&ipr1)); - PG_RETURN_NULL(); + PG_RETURN_NULL(); } PG_FUNCTION_INFO_V1(iprange_size); @@ -1626,7 +1649,7 @@ Datum iprange_prefixlen(PG_FUNCTION_ARGS) { - IPR_P iprp = PG_GETARG_IPR_P(0); + IPR_P iprp = PG_GETARG_IPR_P(0); IPR ipr; int af = ipr_unpack(iprp,&ipr); unsigned len = ~0; @@ -1645,7 +1668,7 @@ /***************************************************************************** - * Btree functions + * Btree functions *****************************************************************************/ PG_FUNCTION_INFO_V1(iprange_cmp); @@ -1657,7 +1680,7 @@ /***************************************************************************** - * GiST functions + * GiST functions *****************************************************************************/ /* @@ -1694,7 +1717,7 @@ Datum gipr_compress(PG_FUNCTION_ARGS) { - GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); + GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); GISTENTRY *retval = entry; if (!entry->leafkey) @@ -1718,7 +1741,7 @@ Datum gipr_decompress(PG_FUNCTION_ARGS) { - GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); + GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); GISTENTRY *retval = palloc(sizeof(GISTENTRY)); IPR_KEY *key = palloc(sizeof(IPR_KEY)); @@ -1729,14 +1752,14 @@ entry->rel, entry->page, entry->offset, false); - PG_RETURN_POINTER(retval); + PG_RETURN_POINTER(retval); } PG_FUNCTION_INFO_V1(gipr_fetch); Datum gipr_fetch(PG_FUNCTION_ARGS) { - PG_RETURN_POINTER(PG_GETARG_POINTER(0)); + PG_RETURN_POINTER(PG_GETARG_POINTER(0)); } @@ -1751,28 +1774,28 @@ Datum gipr_consistent(PG_FUNCTION_ARGS) { - GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); - IPR_P query = (IPR_P) PG_GETARG_POINTER(1); - StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); - bool *recheck = (bool *) PG_GETARG_POINTER(4); - IPR_KEY *key = (IPR_KEY *) DatumGetPointer(entry->key); - bool retval; - - /* recheck is never needed with this type */ - if (recheck) - *recheck = false; - - /* - * * if entry is not leaf, use gipr_internal_consistent, * else use - * gipr_leaf_consistent - */ - - if (GIST_LEAF(entry)) - retval = gipr_leaf_consistent(key, query, strategy); - else - retval = gipr_internal_consistent(key, query, strategy); + GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); + IPR_P query = (IPR_P) PG_GETARG_POINTER(1); + StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); + bool *recheck = (bool *) PG_GETARG_POINTER(4); + IPR_KEY *key = (IPR_KEY *) DatumGetPointer(entry->key); + bool retval; - PG_RETURN_BOOL(retval); + /* recheck is never needed with this type */ + if (recheck) + *recheck = false; + + /* + * * if entry is not leaf, use gipr_internal_consistent, * else use + * gipr_leaf_consistent + */ + + if (GIST_LEAF(entry)) + retval = gipr_leaf_consistent(key, query, strategy); + else + retval = gipr_internal_consistent(key, query, strategy); + + PG_RETURN_BOOL(retval); } /* @@ -1823,7 +1846,7 @@ bool afequal = true; IPR_KEY *tmp; - tmp = (IPR_KEY *) DatumGetPointer(ent[0].key); + tmp = (IPR_KEY *) DatumGetPointer(ent[0].key); *out = *tmp; for (i = 1; out->af != 0 && i < numranges; ++i) @@ -1896,23 +1919,23 @@ Datum gipr_union(PG_FUNCTION_ARGS) { - GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); - int *sizep = (int *) PG_GETARG_POINTER(1); - GISTENTRY *ent = GISTENTRYVEC(entryvec); - int numranges; + GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); + int *sizep = (int *) PG_GETARG_POINTER(1); + GISTENTRY *ent = GISTENTRYVEC(entryvec); + int numranges; IPR_KEY *out = palloc(sizeof(IPR_KEY)); #ifdef GIST_DEBUG - fprintf(stderr, "union\n"); + fprintf(stderr, "union\n"); #endif - numranges = GISTENTRYCOUNT(entryvec); + numranges = GISTENTRYCOUNT(entryvec); gipr_union_internal(out, NULL, NULL, ent, numranges); *sizep = sizeof(IPR_KEY); - PG_RETURN_POINTER(out); + PG_RETURN_POINTER(out); } @@ -1924,13 +1947,13 @@ Datum gipr_penalty(PG_FUNCTION_ARGS) { - GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); - GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1); - float *result = (float *) PG_GETARG_POINTER(2); - IPR_KEY *key = (IPR_KEY *) DatumGetPointer(origentry->key); - IPR_KEY *newkey = (IPR_KEY *) DatumGetPointer(newentry->key); - IP4R ud4; - IP6R ud6; + GISTENTRY *origentry = (GISTENTRY *) PG_GETARG_POINTER(0); + GISTENTRY *newentry = (GISTENTRY *) PG_GETARG_POINTER(1); + float *result = (float *) PG_GETARG_POINTER(2); + IPR_KEY *key = (IPR_KEY *) DatumGetPointer(origentry->key); + IPR_KEY *newkey = (IPR_KEY *) DatumGetPointer(newentry->key); + IP4R ud4; + IP6R ud6; double tmp = 0.0; if (key->af != newkey->af) @@ -2004,11 +2027,11 @@ *result = (float) tmp; #ifdef GIST_DEBUG - fprintf(stderr, "penalty\n"); - fprintf(stderr, "\t%g\n", *result); + fprintf(stderr, "penalty\n"); + fprintf(stderr, "\t%g\n", *result); #endif - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(result); } @@ -2019,8 +2042,8 @@ struct gipr_sort { - IPR_KEY *key; - OffsetNumber pos; + IPR_KEY *key; + OffsetNumber pos; }; static int @@ -2053,41 +2076,41 @@ Datum gipr_picksplit(PG_FUNCTION_ARGS) { - GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); - GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1); - GISTENTRY *ent = GISTENTRYVEC(entryvec); - OffsetNumber i; - int nbytes; - OffsetNumber maxoff; - OffsetNumber *listL; - OffsetNumber *listR; - bool allisequal = true; - bool allafequal = true; - IPR_KEY pageunion; - IPR_KEY *cur; - IPR_KEY *unionL; - IPR_KEY *unionR; - int posL = 0; - int posR = 0; + GistEntryVector *entryvec = (GistEntryVector *) PG_GETARG_POINTER(0); + GIST_SPLITVEC *v = (GIST_SPLITVEC *) PG_GETARG_POINTER(1); + GISTENTRY *ent = GISTENTRYVEC(entryvec); + OffsetNumber i; + int nbytes; + OffsetNumber maxoff; + OffsetNumber *listL; + OffsetNumber *listR; + bool allisequal = true; + bool allafequal = true; + IPR_KEY pageunion; + IPR_KEY *cur; + IPR_KEY *unionL; + IPR_KEY *unionR; + int posL = 0; + int posR = 0; - posL = posR = 0; - maxoff = GISTENTRYCOUNT(entryvec) - 1; + posL = posR = 0; + maxoff = GISTENTRYCOUNT(entryvec) - 1; gipr_union_internal(&pageunion, &allisequal, &allafequal, &ent[FirstOffsetNumber], maxoff); - nbytes = (maxoff + 2) * sizeof(OffsetNumber); - listL = (OffsetNumber *) palloc(nbytes); - listR = (OffsetNumber *) palloc(nbytes); - unionL = palloc(sizeof(IPR_KEY)); - unionR = palloc(sizeof(IPR_KEY)); - v->spl_ldatum = PointerGetDatum(unionL); - v->spl_rdatum = PointerGetDatum(unionR); - v->spl_left = listL; - v->spl_right = listR; + nbytes = (maxoff + 2) * sizeof(OffsetNumber); + listL = (OffsetNumber *) palloc(nbytes); + listR = (OffsetNumber *) palloc(nbytes); + unionL = palloc(sizeof(IPR_KEY)); + unionR = palloc(sizeof(IPR_KEY)); + v->spl_ldatum = PointerGetDatum(unionL); + v->spl_rdatum = PointerGetDatum(unionR); + v->spl_left = listL; + v->spl_right = listR; - if (allisequal) - { + if (allisequal) + { OffsetNumber split_at = FirstOffsetNumber + (maxoff - FirstOffsetNumber + 1)/2; v->spl_nleft = v->spl_nright = 0; *unionL = pageunion; @@ -2099,7 +2122,7 @@ v->spl_right[v->spl_nright++] = i; PG_RETURN_POINTER(v); - } + } /* * if we have a mix of address families present, then we split by AF regardless @@ -2110,12 +2133,12 @@ */ #define ADDLIST( list_, u_, pos_, num_ ) do { \ - if ( pos_ ) { \ + if ( pos_ ) { \ gipr_union_internal_1(u_, cur); \ - } else { \ - *(u_) = *(cur); \ - } \ - (list_)[(pos_)++] = (num_); \ + } else { \ + *(u_) = *(cur); \ + } \ + (list_)[(pos_)++] = (num_); \ } while(0) if (!allafequal) @@ -2167,26 +2190,26 @@ } } - /* bad disposition, sort by ascending size and resplit */ - if (posR == 0 || posL == 0) - { - struct gipr_sort *arr = (struct gipr_sort *) - palloc(sizeof(struct gipr_sort) * (maxoff + FirstOffsetNumber)); + /* bad disposition, sort by ascending size and resplit */ + if (posR == 0 || posL == 0) + { + struct gipr_sort *arr = (struct gipr_sort *) + palloc(sizeof(struct gipr_sort) * (maxoff + FirstOffsetNumber)); Assert(allafequal); - for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) - { - arr[i].key = (IPR_KEY *) DatumGetPointer(ent[i].key); - arr[i].pos = i; - } - - qsort(arr + FirstOffsetNumber, - maxoff - FirstOffsetNumber + 1, - sizeof(struct gipr_sort), + for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) + { + arr[i].key = (IPR_KEY *) DatumGetPointer(ent[i].key); + arr[i].pos = i; + } + + qsort(arr + FirstOffsetNumber, + maxoff - FirstOffsetNumber + 1, + sizeof(struct gipr_sort), (pageunion.af == PGSQL_AF_INET6) ? gipr_sort_compare_v6 : gipr_sort_compare_v4); - posL = posR = 0; + posL = posR = 0; for (i = FirstOffsetNumber; i <= maxoff; i = OffsetNumberNext(i)) { @@ -2222,13 +2245,13 @@ } } - pfree(arr); - } + pfree(arr); + } - v->spl_nleft = posL; - v->spl_nright = posR; + v->spl_nleft = posL; + v->spl_nright = posR; - PG_RETURN_POINTER(v); + PG_RETURN_POINTER(v); } #undef ADDLIST @@ -2240,9 +2263,9 @@ Datum gipr_same(PG_FUNCTION_ARGS) { - IPR_KEY *v1 = (IPR_KEY *) PG_GETARG_POINTER(0); - IPR_KEY *v2 = (IPR_KEY *) PG_GETARG_POINTER(1); - bool *result = (bool *) PG_GETARG_POINTER(2); + IPR_KEY *v1 = (IPR_KEY *) PG_GETARG_POINTER(0); + IPR_KEY *v2 = (IPR_KEY *) PG_GETARG_POINTER(1); + bool *result = (bool *) PG_GETARG_POINTER(2); if (!v1 || !v2) *result = (v1 == NULL && v2 == NULL); @@ -2267,21 +2290,21 @@ } #ifdef GIST_DEBUG - fprintf(stderr, "same: %s\n", (*result ? "true" : "false")); + fprintf(stderr, "same: %s\n", (*result ? "true" : "false")); #endif - PG_RETURN_POINTER(result); + PG_RETURN_POINTER(result); } /* * Strategy numbers: - * OPERATOR 1 >>= , - * OPERATOR 2 <<= , - * OPERATOR 3 >> , - * OPERATOR 4 << , - * OPERATOR 5 && , - * OPERATOR 6 = , + * OPERATOR 1 >>= , + * OPERATOR 2 <<= , + * OPERATOR 3 >> , + * OPERATOR 4 << , + * OPERATOR 5 && , + * OPERATOR 6 = , */ /* @@ -2297,42 +2320,42 @@ int af = ipr_unpack(queryp, &query); #ifdef GIST_QUERY_DEBUG - fprintf(stderr, "leaf_consistent, %d\n", strategy); + fprintf(stderr, "leaf_consistent, %d\n", strategy); #endif if (key->af == 0) { switch (strategy) { - case 1: /* left contains right nonstrict */ + case 1: /* left contains right nonstrict */ return true; - case 2: /* left contained in right nonstrict */ + case 2: /* left contained in right nonstrict */ return (af == 0); - case 3: /* left contains right strict */ + case 3: /* left contains right strict */ return !(af == 0); - case 4: /* left contained in right strict */ + case 4: /* left contained in right strict */ return false; - case 5: /* left overlaps right */ + case 5: /* left overlaps right */ return true; - case 6: /* left equal right */ + case 6: /* left equal right */ return (af == 0); } - } + } else if (af == 0) { switch (strategy) { - case 1: /* left contains right nonstrict */ + case 1: /* left contains right nonstrict */ return false; - case 2: /* left contained in right nonstrict */ + case 2: /* left contained in right nonstrict */ return true; - case 3: /* left contains right strict */ + case 3: /* left contains right strict */ return false; - case 4: /* left contained in right strict */ + case 4: /* left contained in right strict */ return true; - case 5: /* left overlaps right */ + case 5: /* left overlaps right */ return true; - case 6: /* left equal right */ + case 6: /* left equal right */ return false; } } @@ -2342,17 +2365,17 @@ { switch (strategy) { - case 1: /* left contains right nonstrict */ + case 1: /* left contains right nonstrict */ return ip4r_contains_internal(&key->ipr.ip4r, &query.ip4r, true); - case 2: /* left contained in right nonstrict */ + case 2: /* left contained in right nonstrict */ return ip4r_contains_internal(&query.ip4r, &key->ipr.ip4r, true); - case 3: /* left contains right strict */ + case 3: /* left contains right strict */ return ip4r_contains_internal(&key->ipr.ip4r, &query.ip4r, false); - case 4: /* left contained in right strict */ + case 4: /* left contained in right strict */ return ip4r_contains_internal(&query.ip4r, &key->ipr.ip4r, false); - case 5: /* left overlaps right */ + case 5: /* left overlaps right */ return ip4r_overlaps_internal(&key->ipr.ip4r, &query.ip4r); - case 6: /* left equal right */ + case 6: /* left equal right */ return ip4r_equal(&key->ipr.ip4r, &query.ip4r); } } @@ -2360,20 +2383,20 @@ { switch (strategy) { - case 1: /* left contains right nonstrict */ + case 1: /* left contains right nonstrict */ return ip6r_contains_internal(&key->ipr.ip6r, &query.ip6r, true); - case 2: /* left contained in right nonstrict */ + case 2: /* left contained in right nonstrict */ return ip6r_contains_internal(&query.ip6r, &key->ipr.ip6r, true); - case 3: /* left contains right strict */ + case 3: /* left contains right strict */ return ip6r_contains_internal(&key->ipr.ip6r, &query.ip6r, false); - case 4: /* left contained in right strict */ + case 4: /* left contained in right strict */ return ip6r_contains_internal(&query.ip6r, &key->ipr.ip6r, false); - case 5: /* left overlaps right */ + case 5: /* left overlaps right */ return ip6r_overlaps_internal(&key->ipr.ip6r, &query.ip6r); - case 6: /* left equal right */ + case 6: /* left equal right */ return ip6r_equal(&key->ipr.ip6r, &query.ip6r); } - } + } return false; } @@ -2398,7 +2421,7 @@ int af = ipr_unpack(queryp, &query); #ifdef GIST_QUERY_DEBUG - fprintf(stderr, "leaf_consistent, %d\n", strategy); + fprintf(stderr, "leaf_consistent, %d\n", strategy); #endif if (af == 0 && strategy == 4) @@ -2411,14 +2434,14 @@ { switch (strategy) { - case 2: /* left contained in right nonstrict */ - case 4: /* left contained in right strict */ - case 5: /* left overlaps right */ + case 2: /* left contained in right nonstrict */ + case 4: /* left contained in right strict */ + case 5: /* left overlaps right */ return ip4r_overlaps_internal(&key->ipr.ip4r, &query.ip4r); - case 3: /* left contains right strict */ + case 3: /* left contains right strict */ return ip4r_contains_internal(&key->ipr.ip4r, &query.ip4r, false); - case 1: /* left contains right nonstrict */ - case 6: /* left equal right */ + case 1: /* left contains right nonstrict */ + case 6: /* left equal right */ return ip4r_contains_internal(&key->ipr.ip4r, &query.ip4r, true); } } @@ -2426,17 +2449,17 @@ { switch (strategy) { - case 2: /* left contained in right nonstrict */ - case 4: /* left contained in right strict */ - case 5: /* left overlaps right */ + case 2: /* left contained in right nonstrict */ + case 4: /* left contained in right strict */ + case 5: /* left overlaps right */ return ip6r_overlaps_internal(&key->ipr.ip6r, &query.ip6r); - case 3: /* left contains right strict */ + case 3: /* left contains right strict */ return ip6r_contains_internal(&key->ipr.ip6r, &query.ip6r, false); - case 1: /* left contains right nonstrict */ - case 6: /* left equal right */ + case 1: /* left contains right nonstrict */ + case 6: /* left equal right */ return ip6r_contains_internal(&key->ipr.ip6r, &query.ip6r, true); } - } + } return false; } diff -Nru ip4r-2.4.1/src/ipr.h ip4r-2.4.2/src/ipr.h --- ip4r-2.4.1/src/ipr.h 2019-05-22 02:04:18.000000000 +0000 +++ ip4r-2.4.2/src/ipr.h 2023-07-29 17:52:21.000000000 +0000 @@ -2,6 +2,13 @@ #ifndef IPR_H #define IPR_H +#if !defined(PG_VERSION_NUM) +#error "Unknown or unsupported postgresql version" +#endif +#if PG_VERSION_NUM < 90100 +#error "Unknown or unsupported postgresql version" +#endif + #include #include @@ -10,11 +17,8 @@ #include "utils/inet.h" #include "utils/palloc.h" -#if !defined(PG_VERSION_NUM) -#error "Unknown or unsupported postgresql version" -#endif -#if PG_VERSION_NUM < 80400 -#error "Unknown or unsupported postgresql version" +#if PG_VERSION_NUM >= 160000 +#include "varatt.h" #endif #ifndef PGDLLEXPORT @@ -33,8 +37,8 @@ /* IP4R = range of IP4, stored in host-order. fixed-length by reference */ typedef struct IP4R { - IP4 lower; - IP4 upper; + IP4 lower; + IP4 upper; } IP4R; #define IP4R_INITIALIZER {0,0} @@ -44,15 +48,15 @@ * fixed-length and pass by reference. */ typedef struct IP6 { - uint64 bits[2]; + uint64 bits[2]; } IP6; #define IP6_INITIALIZER {{0,0}} /* IP6R = range of IP6. fixed-length by reference */ typedef struct IP6R { - IP6 lower; - IP6 upper; + IP6 lower; + IP6 upper; } IP6R; #define IP6R_INITIALIZER {IP6_INITIALIZER,IP6_INITIALIZER} @@ -74,31 +78,31 @@ #define ip_sizeof(af_) ((af_) == PGSQL_AF_INET ? sizeof(IP4) : sizeof(IP6)) #define ipr_sizeof(af_) ((af_) == PGSQL_AF_INET ? sizeof(IP4R) : sizeof(IP6R)) -typedef void *IP_P; /* unaligned! */ +typedef void *IP_P; /* unaligned! */ PGDLLEXPORT void ipaddr_internal_error(void) __attribute__((noreturn)); static inline int ip_unpack(IP_P in, IP *out) { - switch (VARSIZE_ANY_EXHDR(in)) - { - case sizeof(IP4): - memcpy(&out->ip4, VARDATA_ANY(in), sizeof(IP4)); - return PGSQL_AF_INET; - case sizeof(IP6): - memcpy(&out->ip6, VARDATA_ANY(in), sizeof(IP6)); - return PGSQL_AF_INET6; - default: + switch (VARSIZE_ANY_EXHDR(in)) + { + case sizeof(IP4): + memcpy(&out->ip4, VARDATA_ANY(in), sizeof(IP4)); + return PGSQL_AF_INET; + case sizeof(IP6): + memcpy(&out->ip6, VARDATA_ANY(in), sizeof(IP6)); + return PGSQL_AF_INET6; + default: ipaddr_internal_error(); - } + } } static inline IP_P ip_pack(int af, IP *val) { int sz = ip_sizeof(af); - IP_P out = palloc(VARHDRSZ + sz); + IP_P out = palloc(VARHDRSZ + sz); SET_VARSIZE(out, VARHDRSZ + sz); memcpy(VARDATA(out), val, sz); diff -Nru ip4r-2.4.1/src/ipr_internal.h ip4r-2.4.2/src/ipr_internal.h --- ip4r-2.4.1/src/ipr_internal.h 2019-05-22 02:04:18.000000000 +0000 +++ ip4r-2.4.2/src/ipr_internal.h 2023-07-29 17:52:21.000000000 +0000 @@ -4,8 +4,8 @@ #include "ipr.h" -#define IP4R_VERSION_STR "2.4.1" -#define IP4R_VERSION_NUM 20401 +#define IP4R_VERSION_STR "2.4.2" +#define IP4R_VERSION_NUM 20402 /* PG version dependencies */ @@ -40,6 +40,28 @@ #endif +/* cope with variable-length fcinfo in pg12 */ +#if PG_VERSION_NUM < 120000 +#define LOCAL_FCINFO(name_,nargs_) \ + FunctionCallInfoData name_##data; \ + FunctionCallInfo name_ = &name_##data + +#define LFCI_ARG_VALUE(fci_,n_) ((fci_)->arg[n_]) +#define LFCI_ARGISNULL(fci_,n_) ((fci_)->argnull[n_]) +#else +#define LFCI_ARG_VALUE(fci_,n_) ((fci_)->args[n_].value) +#define LFCI_ARGISNULL(fci_,n_) ((fci_)->args[n_].isnull) +#endif + +/* Soft-error handling is new in pg16 */ +#if PG_VERSION_NUM >= 160000 +#include "nodes/miscnodes.h" +#else +#define ereturn(context_, dummy_value_, ...) \ + do { ereport(ERROR, __VA_ARGS__); return dummy_value_; } while(0) +#define SOFT_ERROR_OCCURRED(escontext) false +#endif + /* funcs */ Datum ip4_in(PG_FUNCTION_ARGS); diff -Nru ip4r-2.4.1/src/raw_io.c ip4r-2.4.2/src/raw_io.c --- ip4r-2.4.1/src/raw_io.c 2019-05-22 02:04:18.000000000 +0000 +++ ip4r-2.4.2/src/raw_io.c 2023-07-29 17:52:21.000000000 +0000 @@ -23,7 +23,7 @@ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (digits++ && octet == 0) - return false; /* must have been a leading 0, reject */ + return false; /* must have been a leading 0, reject */ octet = (octet * 10) + (ch - '0'); if (octet > 255) return false; @@ -91,7 +91,7 @@ gap = words; } else if (!*src) - return false; /* trailing : not valid except as :: */ + return false; /* trailing : not valid except as :: */ tmp[words++] = word; if (words > 7 && *src) @@ -146,7 +146,7 @@ int ip4_raw_output(uint32 ip, char *str, int len) { - return snprintf(str, len, "%u.%u.%u.%u", + return snprintf(str, len, "%u.%u.%u.%u", (ip >> 24)&0xff, (ip >> 16)&0xff, (ip >> 8)&0xff, (ip)&0xff); } @@ -173,9 +173,9 @@ /* * Find the best place to put :: in the output. Per RFC5952, we must: - * - not use :: to replace a single 0 word - * - use :: to replace the longest string of 0 words - * - use :: to replace the leftmost candidate string of equal length + * - not use :: to replace a single 0 word + * - use :: to replace the longest string of 0 words + * - use :: to replace the leftmost candidate string of equal length * * The bitmask we construct here has the least significant bit * representing the leftmost word, and we process the bitmask by @@ -201,7 +201,7 @@ * all zeros (8 zero words) - '::' * 6 zero words followed by a non-zero word - '::1.2.3.4' * 5 zero words followed by 0xffff - '::ffff:1.2.3.4' - * 4 zero words followed by ffff:0 - '::ffff:0:1.2.3.4' [rfc2765] + * 4 zero words followed by ffff:0 - '::ffff:0:1.2.3.4' [rfc2765] * * The case of 7 zero words we leave alone; that avoids trying to output * '::1' as '::0.0.0.1'. We assume that '0.0.x.y' will never be a valid diff -Nru ip4r-2.4.1/tools/legacy-r.sed ip4r-2.4.2/tools/legacy-r.sed --- ip4r-2.4.1/tools/legacy-r.sed 2019-05-22 02:04:18.000000000 +0000 +++ ip4r-2.4.2/tools/legacy-r.sed 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ -# -/^..CUT-HERE/,/^..CUT-END/c\ -SET client_min_messages = warning;\ -\\set ECHO none\ -\\i ip4r.sql\ -\\set ECHO all\ -RESET client_min_messages; diff -Nru ip4r-2.4.1/tools/legacy.sed ip4r-2.4.2/tools/legacy.sed --- ip4r-2.4.1/tools/legacy.sed 2019-05-22 02:04:18.000000000 +0000 +++ ip4r-2.4.2/tools/legacy.sed 1970-01-01 00:00:00.000000000 +0000 @@ -1,22 +0,0 @@ -# -/^-- complain.*CREATE EXTENSION/,/^$/c\ --- Adjust this setting to control where the objects get created.\ -SET search_path = public;\ -\ - -# -/^-- Type definitions/a\ -\ -BEGIN; -# -/^-- type creation is needlessly chatty/a\ -\ -SET LOCAL client_min_messages = warning; - -# -/^COMMENT ON TYPE iprange/a\ -\ -COMMIT; -# -/^CREATE TYPE [^()]*;/,/^$/d -/^CREATE FUNCTION/s/CREATE FUNCTION/CREATE OR REPLACE FUNCTION/ diff -Nru ip4r-2.4.1/tools/numeric.mk ip4r-2.4.2/tools/numeric.mk --- ip4r-2.4.1/tools/numeric.mk 1970-01-01 00:00:00.000000000 +0000 +++ ip4r-2.4.2/tools/numeric.mk 2023-07-29 17:52:21.000000000 +0000 @@ -0,0 +1,35 @@ +##-- +## Hacks for numeric comparisons. + +# $(call version_ge,a,b) +# true iff a >= b when treated as vectors of integers separated by . or space +version_ge = $(strip $(call vge_2,$(subst ., ,$(1)),$(subst ., ,$(2)))) + +# if a is empty, result is true if b is empty otherwise false. +# if b is empty, result is true. +# if neither is empty, compare first words; if equal, strip one word and recurse. +define vge_2 +$(if $(strip $(1)), + $(if $(strip $(2)), + $(if $(call numeric_lt,$(firstword $(2)),$(firstword $(1))), + t, + $(if $(call numeric_lt,$(firstword $(1)),$(firstword $(2))), + , + $(call vge_2, + $(wordlist 2,$(words $(1)),$(1)), + $(wordlist 2,$(words $(2)),$(2))))), + t), + $(if $(strip $(2)),,t)) +endef + +# $(call numeric_le,a,b) - true if a <= b, i.e. either a is 0 or a can index a [1..b] list +numeric_le = $(if $(filter 0,$(1)),t,$(word $(1),$(call nwords,$(2),))) + +# $(call numeric_lt,a,b) - true if a < b, i.e. !(b <= a) +numeric_lt = $(if $(call numeric_le,$(2),$(1)),,t) + +# list of N words +nwords = $(if $(filter-out 0,$(1)),$(if $(word $(1),$(2)),$(2),$(call nwords,$(1),$(2) t))) + +## end of hacks. +##-- diff -Nru ip4r-2.4.1/.travis.yml ip4r-2.4.2/.travis.yml --- ip4r-2.4.1/.travis.yml 2019-05-22 02:04:18.000000000 +0000 +++ ip4r-2.4.2/.travis.yml 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ - -addons: - apt: - sources: - - sourceline: "deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main 12" - key_url: "https://www.postgresql.org/media/keys/ACCC4CF8.asc" - - sourceline: "deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg-testing main 12" - key_url: "https://www.postgresql.org/media/keys/ACCC4CF8.asc" - -before_install: - - sudo /etc/init.d/postgresql stop - - sudo apt-get -y --purge remove postgresql libpq-dev libpq5 postgresql-client-common postgresql-common - - sudo rm -rf /var/lib/postgresql - - sudo apt-get update -qq - - sudo apt-get -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::="--force-confnew" ${PGREPO:+-t "$PGREPO"} install postgresql-${PG:?} postgresql-server-dev-${PG:?} - -before_script: - - sudo -u postgres createuser -s "$USER" - -env: - matrix: - - PG=9.2 - - PG=9.3 - - PG=9.4 - - PG=9.5 - - PG=9.6 - - PG=10 - - PG=11 - - PG=12 PGREPO=xenial-pgdg-testing - -dist: xenial - -sudo: required - -language: c - -compiler: - - gcc - -script: - - make && sudo make install && make installcheck - -after_script: - - cat regression.diffs || true -