From d4a4d4c32608fd7c84aeab655072a7667e57c02a Mon Sep 17 00:00:00 2001 From: Bruce Momjian Date: Wed, 13 Jun 2001 21:09:00 +0000 Subject: [PATCH] Attached is a patch adding following functions: inet(text), cidr(text): convert a text value into inet/cidr set_masklen(inet): set masklen on the inet value Patch also contains regression checks for these functions. Alex Pilosov --- src/backend/utils/adt/network.c | 48 +++++++++++++++++++++++++++++++++++++- src/include/catalog/pg_proc.h | 8 ++++++- src/include/utils/builtins.h | 5 +++- src/test/regress/expected/inet.out | 19 +++++++++++++++ src/test/regress/sql/inet.sql | 4 ++++ 5 files changed, 81 insertions(+), 3 deletions(-) diff --git a/src/backend/utils/adt/network.c b/src/backend/utils/adt/network.c index 0a6e10f174..126883a769 100644 --- a/src/backend/utils/adt/network.c +++ b/src/backend/utils/adt/network.c @@ -3,7 +3,7 @@ * is for IP V4 CIDR notation, but prepared for V6: just * add the necessary bits where the comments indicate. * - * $Header: /cvsroot/pgsql/src/backend/utils/adt/network.c,v 1.30 2001/06/09 22:16:18 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/network.c,v 1.31 2001/06/13 21:08:59 momjian Exp $ * * Jon Postel RIP 16 Oct 1998 */ @@ -21,6 +21,7 @@ #include "utils/inet.h" +static Datum text_network(text *src, int type); static int32 network_cmp_internal(inet *a1, inet *a2); static int v4bitncmp(unsigned long a1, unsigned long a2, int bits); static bool v4addressOK(unsigned long a1, int bits); @@ -149,6 +150,51 @@ cidr_out(PG_FUNCTION_ARGS) } +Datum +text_network(text *src, int type) +{ + int len = VARSIZE(src) - VARHDRSZ; + + char *str = palloc(len + 1); + memcpy(str, VARDATA(src), len); + *(str + len) = '\0'; + + PG_RETURN_INET_P(network_in( str, type)); +} + +Datum +text_cidr(PG_FUNCTION_ARGS) +{ + return text_network( PG_GETARG_TEXT_P(0), 1); +} + +Datum +text_inet(PG_FUNCTION_ARGS) +{ + return text_network( PG_GETARG_TEXT_P(0), 0); +} + +Datum +inet_set_masklen(PG_FUNCTION_ARGS) +{ + inet *src = PG_GETARG_INET_P(0); + int bits = PG_GETARG_INT32(1); + inet *dst; + + if ((bits < 0) || (bits > 32)) /* no support for v6 yet */ + { + elog(ERROR, "set_masklen - invalid value '%d'", bits); + } + + /* clone the original data */ + dst = (inet *) palloc(VARHDRSZ + sizeof(inet_struct)); + memcpy(dst, src, VARHDRSZ + sizeof(inet_struct)); + + ip_bits(dst) = bits; + + PG_RETURN_INET_P(dst); +} + /* * Basic comparison function for sorting and inet/cidr comparisons. * diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index b88af0b91f..80441957eb 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pg_proc.h,v 1.191 2001/06/12 16:34:26 momjian Exp $ + * $Id: pg_proc.h,v 1.192 2001/06/13 21:08:59 momjian Exp $ * * NOTES * The script catalog/genbki.sh reads this file and generates .bki @@ -2308,6 +2308,12 @@ DATA(insert OID = 699 ( host PGUID 12 f t t t 1 f 25 "869" 100 0 0 100 netw DESCR("show address octets only"); DATA(insert OID = 730 ( text PGUID 12 f t t t 1 f 25 "869" 100 0 0 100 network_show - )); DESCR("show all parts of inet/cidr value"); +DATA(insert OID = 1910 ( inet PGUID 12 f t t t 1 f 869 "25" 100 0 0 100 text_inet - )); +DESCR("text to inet"); +DATA(insert OID = 1911 ( cidr PGUID 12 f t t t 1 f 650 "25" 100 0 0 100 text_cidr - )); +DESCR("text to cidr"); +DATA(insert OID = 1912 ( set_masklen PGUID 12 f t t t 2 f 869 "869 23" 100 0 0 100 inet_set_masklen - )); +DESCR("change the netmask of an inet"); DATA(insert OID = 1691 ( boolle PGUID 12 f t t t 2 f 16 "16 16" 100 0 0 100 boolle - )); DESCR("less-than-or-equal"); diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 2db51eb8a8..d739fd83d8 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: builtins.h,v 1.152 2001/06/12 16:34:27 momjian Exp $ + * $Id: builtins.h,v 1.153 2001/06/13 21:08:59 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -515,6 +515,9 @@ extern Datum network_host(PG_FUNCTION_ARGS); extern Datum network_show(PG_FUNCTION_ARGS); extern Datum network_abbrev(PG_FUNCTION_ARGS); extern double convert_network_to_scalar(Datum value, Oid typid); +extern Datum text_cidr(PG_FUNCTION_ARGS); +extern Datum text_inet(PG_FUNCTION_ARGS); +extern Datum inet_set_masklen(PG_FUNCTION_ARGS); /* mac.c */ extern Datum macaddr_in(PG_FUNCTION_ARGS); diff --git a/src/test/regress/expected/inet.out b/src/test/regress/expected/inet.out index 9c0beef363..27f4e4e85a 100644 --- a/src/test/regress/expected/inet.out +++ b/src/test/regress/expected/inet.out @@ -18,6 +18,9 @@ INSERT INTO INET_TBL (c, i) VALUES ('10', '9.1.2.3/8'); -- check that CIDR rejects invalid input: INSERT INTO INET_TBL (c, i) VALUES ('192.168.1.2/24', '192.168.1.226'); ERROR: invalid CIDR value '192.168.1.2/24': has bits set to right of mask +-- check that CIDR rejects invalid input when converting from text: +INSERT INTO INET_TBL (c, i) VALUES (cidr('192.168.1.2/24'), '192.168.1.226'); +ERROR: invalid CIDR value '192.168.1.2/24': has bits set to right of mask SELECT '' AS ten, c AS cidr, i AS inet FROM INET_TBL; ten | cidr | inet -----+----------------+------------------ @@ -135,3 +138,19 @@ SELECT '' AS ten, i, c, | 9.1.2.3/8 | 10.0.0.0/8 | t | t | f | f | f | t | f | f | f | f (10 rows) +-- check the conversion to/from text and set_netmask +select '' AS ten, set_masklen(inet(text(i)), 24) FROM INET_TBL; + ten | set_masklen +-----+------------------ + | 192.168.1.226/24 + | 192.168.1.226/24 + | 10.1.2.3/24 + | 10.1.2.3/24 + | 10.1.2.3/24 + | 10.1.2.3/24 + | 10.1.2.3/24 + | 10.1.2.3/24 + | 11.1.2.3/24 + | 9.1.2.3/24 +(10 rows) + diff --git a/src/test/regress/sql/inet.sql b/src/test/regress/sql/inet.sql index d91c3a0bbf..6e59714fd9 100644 --- a/src/test/regress/sql/inet.sql +++ b/src/test/regress/sql/inet.sql @@ -18,6 +18,8 @@ INSERT INTO INET_TBL (c, i) VALUES ('10', '11.1.2.3/8'); INSERT INTO INET_TBL (c, i) VALUES ('10', '9.1.2.3/8'); -- check that CIDR rejects invalid input: INSERT INTO INET_TBL (c, i) VALUES ('192.168.1.2/24', '192.168.1.226'); +-- check that CIDR rejects invalid input when converting from text: +INSERT INTO INET_TBL (c, i) VALUES (cidr('192.168.1.2/24'), '192.168.1.226'); SELECT '' AS ten, c AS cidr, i AS inet FROM INET_TBL; @@ -45,3 +47,5 @@ SELECT '' AS ten, i, c, i >> c AS sup, i >>= c AS spe FROM INET_TBL; +-- check the conversion to/from text and set_netmask +select '' AS ten, set_masklen(inet(text(i)), 24) FROM INET_TBL; -- 2.11.0