Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 1372515

Browse files
committed
Add INET/CIDR operators: and, or, not, plus int8, minus int8, and inet
minus inet. Stephen R. van den Berg
1 parent 9bf2ac2 commit 1372515

File tree

7 files changed

+411
-5
lines changed

7 files changed

+411
-5
lines changed

doc/src/sgml/func.sgml

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.303 2006/01/26 02:35:48 tgl Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.304 2006/02/11 03:32:38 momjian Exp $
33
PostgreSQL documentation
44
-->
55

@@ -6787,6 +6787,36 @@ SELECT pg_sleep(1.5);
67876787
<entry>contains or equals</entry>
67886788
<entry><literal>inet '192.168.1/24' &gt;&gt;= inet '192.168.1/24'</literal></entry>
67896789
</row>
6790+
<row>
6791+
<entry> <literal>~</literal> </entry>
6792+
<entry>bitwise NOT</entry>
6793+
<entry><literal>~ inet '192.168.1.6'</literal></entry>
6794+
</row>
6795+
<row>
6796+
<entry> <literal>&amp;</literal> </entry>
6797+
<entry>bitwise AND</entry>
6798+
<entry><literal>inet '192.168.1.6' &amp; inet '0.0.0.255'</literal></entry>
6799+
</row>
6800+
<row>
6801+
<entry> <literal>|</literal> </entry>
6802+
<entry>bitwise OR</entry>
6803+
<entry><literal>inet '192.168.1.6' | inet '0.0.0.255'</literal></entry>
6804+
</row>
6805+
<row>
6806+
<entry> <literal>+</literal> </entry>
6807+
<entry>addition</entry>
6808+
<entry><literal>inet '192.168.1.6' + 25</literal></entry>
6809+
</row>
6810+
<row>
6811+
<entry> <literal>-</literal> </entry>
6812+
<entry>subtraction</entry>
6813+
<entry><literal>inet '192.168.1.43' - 36</literal></entry>
6814+
</row>
6815+
<row>
6816+
<entry> <literal>-</literal> </entry>
6817+
<entry>subtraction</entry>
6818+
<entry><literal>inet '192.168.1.43' - inet '192.168.1.19'</literal></entry>
6819+
</row>
67906820
</tbody>
67916821
</tgroup>
67926822
</table>

src/backend/utils/adt/network.c

Lines changed: 207 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* PostgreSQL type definitions for the INET and CIDR types.
33
*
4-
* $PostgreSQL: pgsql/src/backend/utils/adt/network.c,v 1.63 2006/02/07 17:04:04 momjian Exp $
4+
* $PostgreSQL: pgsql/src/backend/utils/adt/network.c,v 1.64 2006/02/11 03:32:39 momjian Exp $
55
*
66
* Jon Postel RIP 16 Oct 1998
77
*/
@@ -27,6 +27,7 @@ static int32 network_cmp_internal(inet *a1, inet *a2);
2727
static int bitncmp(void *l, void *r, int n);
2828
static bool addressOK(unsigned char *a, int bits, int family);
2929
static int ip_addrsize(inet *inetptr);
30+
static Datum internal_inetpl(inet *ip, int64 iarg);
3031

3132
/*
3233
* Access macros.
@@ -1250,3 +1251,208 @@ inet_server_port(PG_FUNCTION_ARGS)
12501251

12511252
PG_RETURN_DATUM(DirectFunctionCall1(int4in, CStringGetDatum(local_port)));
12521253
}
1254+
1255+
1256+
Datum
1257+
inetnot(PG_FUNCTION_ARGS)
1258+
{
1259+
inet *ip = PG_GETARG_INET_P(0);
1260+
inet *dst;
1261+
1262+
dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
1263+
1264+
{
1265+
int nb = ip_addrsize(ip);
1266+
unsigned char *pip = ip_addr(ip);
1267+
unsigned char *pdst = ip_addr(dst);
1268+
1269+
while (nb-- > 0)
1270+
pdst[nb] = ~pip[nb];
1271+
}
1272+
ip_bits(dst) = ip_bits(ip);
1273+
1274+
ip_family(dst) = ip_family(ip);
1275+
VARATT_SIZEP(dst) = VARHDRSZ +
1276+
((char *) ip_addr(dst) - (char *) VARDATA(dst)) +
1277+
ip_addrsize(dst);
1278+
1279+
PG_RETURN_INET_P(dst);
1280+
}
1281+
1282+
1283+
Datum
1284+
inetand(PG_FUNCTION_ARGS)
1285+
{
1286+
inet *ip = PG_GETARG_INET_P(0);
1287+
inet *ip2 = PG_GETARG_INET_P(1);
1288+
inet *dst;
1289+
1290+
dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
1291+
1292+
if (ip_family(ip) != ip_family(ip2))
1293+
ereport(ERROR,
1294+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1295+
errmsg("mismatch in address family (%d) != (%d)",
1296+
ip_family(ip), ip_family(ip2))));
1297+
else
1298+
{
1299+
int nb = ip_addrsize(ip);
1300+
unsigned char *pip = ip_addr(ip);
1301+
unsigned char *pip2 = ip_addr(ip2);
1302+
unsigned char *pdst = ip_addr(dst);
1303+
1304+
while (nb-- > 0)
1305+
pdst[nb] = pip[nb] & pip2[nb];
1306+
}
1307+
ip_bits(dst) = Max(ip_bits(ip), ip_bits(ip2));
1308+
1309+
ip_family(dst) = ip_family(ip);
1310+
VARATT_SIZEP(dst) = VARHDRSZ +
1311+
((char *) ip_addr(dst) - (char *) VARDATA(dst)) +
1312+
ip_addrsize(dst);
1313+
1314+
PG_RETURN_INET_P(dst);
1315+
}
1316+
1317+
1318+
Datum
1319+
inetor(PG_FUNCTION_ARGS)
1320+
{
1321+
inet *ip = PG_GETARG_INET_P(0);
1322+
inet *ip2 = PG_GETARG_INET_P(1);
1323+
inet *dst;
1324+
1325+
dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
1326+
1327+
if (ip_family(ip) != ip_family(ip2))
1328+
ereport(ERROR,
1329+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1330+
errmsg("mismatch in address family (%d) != (%d)",
1331+
ip_family(ip), ip_family(ip2))));
1332+
else
1333+
{
1334+
int nb = ip_addrsize(ip);
1335+
unsigned char *pip = ip_addr(ip);
1336+
unsigned char *pip2 = ip_addr(ip2);
1337+
unsigned char *pdst = ip_addr(dst);
1338+
1339+
while (nb-- > 0)
1340+
pdst[nb] = pip[nb] | pip2[nb];
1341+
}
1342+
ip_bits(dst) = Max(ip_bits(ip), ip_bits(ip2));
1343+
1344+
ip_family(dst) = ip_family(ip);
1345+
VARATT_SIZEP(dst) = VARHDRSZ +
1346+
((char *) ip_addr(dst) - (char *) VARDATA(dst)) +
1347+
ip_addrsize(dst);
1348+
1349+
PG_RETURN_INET_P(dst);
1350+
}
1351+
1352+
1353+
static Datum
1354+
internal_inetpl(inet *ip, int64 plus)
1355+
{
1356+
inet *dst;
1357+
1358+
dst = (inet *) palloc0(VARHDRSZ + sizeof(inet_struct));
1359+
1360+
{
1361+
int nb = ip_addrsize(ip);
1362+
unsigned char *pip = ip_addr(ip);
1363+
unsigned char *pdst = ip_addr(dst);
1364+
int carry = 0;
1365+
1366+
while (nb-- > 0)
1367+
{
1368+
pdst[nb] = carry = pip[nb] + plus + carry;
1369+
plus /= 0x100; /* process next byte */
1370+
carry /= 0x100; /* remove low byte */
1371+
/* Overflow on high byte? */
1372+
if (nb == 0 && (plus != 0 || carry != 0))
1373+
ereport(ERROR,
1374+
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1375+
errmsg("result out of range")));
1376+
}
1377+
}
1378+
ip_bits(dst) = ip_bits(ip);
1379+
1380+
ip_family(dst) = ip_family(ip);
1381+
VARATT_SIZEP(dst) = VARHDRSZ +
1382+
((char *) ip_addr(dst) - (char *) VARDATA(dst)) +
1383+
ip_addrsize(dst);
1384+
1385+
PG_RETURN_INET_P(dst);
1386+
}
1387+
1388+
1389+
Datum
1390+
inetpl(PG_FUNCTION_ARGS)
1391+
{
1392+
inet *ip = PG_GETARG_INET_P(0);
1393+
int64 plus = PG_GETARG_INT64(1);
1394+
1395+
return internal_inetpl(ip, plus);
1396+
}
1397+
1398+
1399+
Datum
1400+
inetmi_int8(PG_FUNCTION_ARGS)
1401+
{
1402+
inet *ip = PG_GETARG_INET_P(0);
1403+
int64 plus = PG_GETARG_INT64(1);
1404+
1405+
return internal_inetpl(ip, -plus);
1406+
}
1407+
1408+
1409+
Datum
1410+
inetmi(PG_FUNCTION_ARGS)
1411+
{
1412+
inet *ip = PG_GETARG_INET_P(0);
1413+
inet *ip2 = PG_GETARG_INET_P(1);
1414+
int64 res = 0;
1415+
1416+
if (ip_family(ip) != ip_family(ip2))
1417+
ereport(ERROR,
1418+
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
1419+
errmsg("mismatch in address family (%d) != (%d)",
1420+
ip_family(ip), ip_family(ip2))));
1421+
else
1422+
{
1423+
int nb = ip_addrsize(ip);
1424+
int byte = 0;
1425+
unsigned char *pip = ip_addr(ip);
1426+
unsigned char *pip2 = ip_addr(ip2);
1427+
1428+
while (nb-- > 0)
1429+
{
1430+
/*
1431+
* Error if overflow on last byte. This test is tricky
1432+
* because if the subtraction == 128 and res is negative, or
1433+
* if subtraction == -128 and res is positive, the result
1434+
* would still fit in int64.
1435+
*/
1436+
if (byte + 1 == sizeof(int64) &&
1437+
(pip[nb] - pip2[nb] >= 128 + (res < 0) ||
1438+
pip[nb] - pip2[nb] <= -128 - (res > 0)))
1439+
ereport(ERROR,
1440+
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1441+
errmsg("result out of range")));
1442+
if (byte >= sizeof(int64))
1443+
{
1444+
/* Error if bytes beyond int64 length differ. */
1445+
if (pip[nb] != pip2[nb])
1446+
ereport(ERROR,
1447+
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
1448+
errmsg("result out of range")));
1449+
}
1450+
else
1451+
res += (int64)(pip[nb] - pip2[nb]) << (byte * 8);
1452+
1453+
byte++;
1454+
}
1455+
}
1456+
1457+
PG_RETURN_INT64(res);
1458+
}

src/include/catalog/pg_operator.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
99
* Portions Copyright (c) 1994, Regents of the University of California
1010
*
11-
* $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.138 2006/01/26 02:35:49 tgl Exp $
11+
* $PostgreSQL: pgsql/src/include/catalog/pg_operator.h,v 1.139 2006/02/11 03:32:39 momjian Exp $
1212
*
1313
* NOTES
1414
* the genbki.sh script reads this file and generates .bki
@@ -653,6 +653,15 @@ DATA(insert OID = 933 ( ">>" PGNSP PGUID b f 869 869 16 931 0 0 0 0
653653
DATA(insert OID = 934 ( ">>=" PGNSP PGUID b f 869 869 16 932 0 0 0 0 0 network_supeq - - ));
654654
#define OID_INET_SUPEQ_OP 934
655655

656+
DATA(insert OID = 2634 ( "~" PGNSP PGUID l f 0 869 869 0 0 0 0 0 0 inetnot - - ));
657+
DATA(insert OID = 2635 ( "&" PGNSP PGUID b f 869 869 869 0 0 0 0 0 0 inetand - - ));
658+
DATA(insert OID = 2636 ( "|" PGNSP PGUID b f 869 869 869 0 0 0 0 0 0 inetor - - ));
659+
DATA(insert OID = 2637 ( "+" PGNSP PGUID b f 869 20 869 2638 0 0 0 0 0 inetpl - - ));
660+
DATA(insert OID = 2638 ( "+" PGNSP PGUID b f 20 869 869 2637 0 0 0 0 0 int8pl_inet - - ));
661+
DATA(insert OID = 2639 ( "-" PGNSP PGUID b f 869 20 869 0 0 0 0 0 0 inetmi_int8 - - ));
662+
DATA(insert OID = 2640 ( "-" PGNSP PGUID b f 869 869 20 0 0 0 0 0 0 inetmi - - ));
663+
664+
656665
/* case-insensitive LIKE hacks */
657666
DATA(insert OID = 1625 ( "~~*" PGNSP PGUID b f 19 25 16 0 1626 0 0 0 0 nameiclike iclikesel iclikejoinsel ));
658667
#define OID_NAME_ICLIKE_OP 1625

src/include/catalog/pg_proc.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.394 2006/02/09 14:53:51 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/catalog/pg_proc.h,v 1.395 2006/02/11 03:32:39 momjian Exp $
1111
*
1212
* NOTES
1313
* The script catalog/genbki.sh reads this file and generates .bki
@@ -2431,6 +2431,21 @@ DESCR("INET address of the server");
24312431
DATA(insert OID = 2199 ( inet_server_port PGNSP PGUID 12 f f f f s 0 23 "" _null_ _null_ _null_ inet_server_port - _null_ ));
24322432
DESCR("server's port number for this connection");
24332433

2434+
DATA(insert OID = 2627 ( inetnot PGNSP PGUID 12 f f t f i 1 869 "869" _null_ _null_ _null_ inetnot - _null_ ));
2435+
DESCR("binary NOT");
2436+
DATA(insert OID = 2628 ( inetand PGNSP PGUID 12 f f t f i 2 869 "869 869" _null_ _null_ _null_ inetand - _null_ ));
2437+
DESCR("binary AND");
2438+
DATA(insert OID = 2629 ( inetor PGNSP PGUID 12 f f t f i 2 869 "869 869" _null_ _null_ _null_ inetor - _null_ ));
2439+
DESCR("binary OR");
2440+
DATA(insert OID = 2630 ( inetpl PGNSP PGUID 12 f f t f i 2 869 "869 20" _null_ _null_ _null_ inetpl - _null_ ));
2441+
DESCR("add integer to INET value");
2442+
DATA(insert OID = 2631 ( int8pl_inet PGNSP PGUID 14 f f t f i 2 869 "20 869" _null_ _null_ _null_ "select $2 + $1" - _null_ ));
2443+
DESCR("add integer to INET value");
2444+
DATA(insert OID = 2632 ( inetmi_int8 PGNSP PGUID 12 f f t f i 2 869 "869 20" _null_ _null_ _null_ inetmi_int8 - _null_ ));
2445+
DESCR("subtract integer from INET value");
2446+
DATA(insert OID = 2633 ( inetmi PGNSP PGUID 12 f f t f i 2 20 "869 869" _null_ _null_ _null_ inetmi - _null_ ));
2447+
DESCR("subtract INET values");
2448+
24342449
DATA(insert OID = 1686 ( numeric PGNSP PGUID 12 f f t f i 1 1700 "25" _null_ _null_ _null_ text_numeric - _null_ ));
24352450
DESCR("(internal)");
24362451
DATA(insert OID = 1688 ( text PGNSP PGUID 12 f f t f i 1 25 "1700" _null_ _null_ _null_ numeric_text - _null_ ));

src/include/utils/builtins.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.272 2006/01/26 02:35:50 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/utils/builtins.h,v 1.273 2006/02/11 03:32:41 momjian Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -734,6 +734,12 @@ extern Datum inet_client_addr(PG_FUNCTION_ARGS);
734734
extern Datum inet_client_port(PG_FUNCTION_ARGS);
735735
extern Datum inet_server_addr(PG_FUNCTION_ARGS);
736736
extern Datum inet_server_port(PG_FUNCTION_ARGS);
737+
extern Datum inetnot(PG_FUNCTION_ARGS);
738+
extern Datum inetand(PG_FUNCTION_ARGS);
739+
extern Datum inetor(PG_FUNCTION_ARGS);
740+
extern Datum inetpl(PG_FUNCTION_ARGS);
741+
extern Datum inetmi_int8(PG_FUNCTION_ARGS);
742+
extern Datum inetmi(PG_FUNCTION_ARGS);
737743

738744
/* mac.c */
739745
extern Datum macaddr_in(PG_FUNCTION_ARGS);

0 commit comments

Comments
 (0)