From ed9ca687582caa88f31c4b273b9fd4eb5743cf41 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 3 Aug 2000 23:07:51 +0000 Subject: [PATCH] Convert inet-related functions to new fmgr style. I have also taken it on myself to do something about the non-self-consistency of the inet comparison functions. The results are probably still semantically wrong (inet and cidr should have different comparison semantics, I think) but at least the boolean operators now agree with each other and with the sort order of indexes on inet/cidr. --- src/backend/utils/adt/mac.c | 160 +++++++------- src/backend/utils/adt/network.c | 332 ++++++++++++++--------------- src/include/catalog/pg_proc.h | 52 ++--- src/include/utils/builtins.h | 66 +++--- src/include/utils/inet.h | 35 ++- src/test/regress/expected/inet.out | 2 +- 6 files changed, 329 insertions(+), 318 deletions(-) diff --git a/src/backend/utils/adt/mac.c b/src/backend/utils/adt/mac.c index 5b54250464..e8d502b87d 100644 --- a/src/backend/utils/adt/mac.c +++ b/src/backend/utils/adt/mac.c @@ -1,20 +1,18 @@ /* * PostgreSQL type definitions for MAC addresses. * - * $Header: /cvsroot/pgsql/src/backend/utils/adt/mac.c,v 1.16 2000/07/06 05:48:11 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/mac.c,v 1.17 2000/08/03 23:07:46 tgl Exp $ */ #include "postgres.h" #include "utils/builtins.h" - +#include "utils/inet.h" /* - * macaddr is a pass-by-reference datatype. + * XXX this table of manufacturers is long out of date, and should never + * have been wired into the code in the first place. */ -#define PG_GETARG_MACADDR_P(n) ((macaddr *) PG_GETARG_POINTER(n)) -#define PG_RETURN_MACADDR_P(x) return PointerGetDatum(x) - typedef struct manufacturer { @@ -145,18 +143,18 @@ static manufacturer manufacturers[] = { */ #define hibits(addr) \ - ((unsigned long)((addr->a<<16)|(addr->b<<8)|(addr->c))) + ((unsigned long)(((addr)->a<<16)|((addr)->b<<8)|((addr)->c))) #define lobits(addr) \ - ((unsigned long)((addr->d<<16)|(addr->e<<8)|(addr->f))) + ((unsigned long)(((addr)->d<<16)|((addr)->e<<8)|((addr)->f))) /* * MAC address reader. Accepts several common notations. */ - -macaddr * -macaddr_in(char *str) +Datum +macaddr_in(PG_FUNCTION_ARGS) { + char *str = PG_GETARG_CSTRING(0); int a, b, c, @@ -201,21 +199,18 @@ macaddr_in(char *str) result->e = e; result->f = f; - return (result); + PG_RETURN_MACADDR_P(result); } /* * MAC address output function. Fixed format. */ - -char * -macaddr_out(macaddr *addr) +Datum +macaddr_out(PG_FUNCTION_ARGS) { + macaddr *addr = PG_GETARG_MACADDR_P(0); char *result; - if (addr == NULL) - return (NULL); - result = (char *) palloc(32); if ((hibits(addr) > 0) || (lobits(addr) > 0)) @@ -225,73 +220,18 @@ macaddr_out(macaddr *addr) } else { - result[0] = 0; /* special case for missing address */ + result[0] = '\0'; /* special case for missing address */ } - return (result); -} -/* - * Boolean tests. - */ - -bool -macaddr_lt(macaddr *a1, macaddr *a2) -{ - if (!PointerIsValid(a1) || !PointerIsValid(a2)) - return FALSE; - return ((hibits(a1) < hibits(a2)) || - ((hibits(a1) == hibits(a2)) && lobits(a1) < lobits(a2))); -} - -bool -macaddr_le(macaddr *a1, macaddr *a2) -{ - if (!PointerIsValid(a1) || !PointerIsValid(a2)) - return FALSE; - return ((hibits(a1) < hibits(a2)) || - ((hibits(a1) == hibits(a2)) && lobits(a1) <= lobits(a2))); -} - -bool -macaddr_eq(macaddr *a1, macaddr *a2) -{ - if (!PointerIsValid(a1) || !PointerIsValid(a2)) - return FALSE; - return ((hibits(a1) == hibits(a2)) && (lobits(a1) == lobits(a2))); -} - -bool -macaddr_ge(macaddr *a1, macaddr *a2) -{ - if (!PointerIsValid(a1) || !PointerIsValid(a2)) - return FALSE; - return ((hibits(a1) > hibits(a2)) || - ((hibits(a1) == hibits(a2)) && lobits(a1) >= lobits(a2))); -} - -bool -macaddr_gt(macaddr *a1, macaddr *a2) -{ - if (!PointerIsValid(a1) || !PointerIsValid(a2)) - return FALSE; - return ((hibits(a1) > hibits(a2)) || - ((hibits(a1) == hibits(a2)) && lobits(a1) > lobits(a2))); -} - -bool -macaddr_ne(macaddr *a1, macaddr *a2) -{ - if (!PointerIsValid(a1) || !PointerIsValid(a2)) - return FALSE; - return ((hibits(a1) != hibits(a2)) || (lobits(a1) != lobits(a2))); + PG_RETURN_CSTRING(result); } /* * Comparison function for sorting: */ -int4 -macaddr_cmp(macaddr *a1, macaddr *a2) +static int32 +macaddr_cmp_internal(macaddr *a1, macaddr *a2) { if (hibits(a1) < hibits(a2)) return -1; @@ -305,6 +245,72 @@ macaddr_cmp(macaddr *a1, macaddr *a2) return 0; } +Datum +macaddr_cmp(PG_FUNCTION_ARGS) +{ + macaddr *a1 = PG_GETARG_MACADDR_P(0); + macaddr *a2 = PG_GETARG_MACADDR_P(1); + + PG_RETURN_INT32(macaddr_cmp_internal(a1, a2)); +} + +/* + * Boolean comparisons. + */ +Datum +macaddr_lt(PG_FUNCTION_ARGS) +{ + macaddr *a1 = PG_GETARG_MACADDR_P(0); + macaddr *a2 = PG_GETARG_MACADDR_P(1); + + PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) < 0); +} + +Datum +macaddr_le(PG_FUNCTION_ARGS) +{ + macaddr *a1 = PG_GETARG_MACADDR_P(0); + macaddr *a2 = PG_GETARG_MACADDR_P(1); + + PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) <= 0); +} + +Datum +macaddr_eq(PG_FUNCTION_ARGS) +{ + macaddr *a1 = PG_GETARG_MACADDR_P(0); + macaddr *a2 = PG_GETARG_MACADDR_P(1); + + PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) == 0); +} + +Datum +macaddr_ge(PG_FUNCTION_ARGS) +{ + macaddr *a1 = PG_GETARG_MACADDR_P(0); + macaddr *a2 = PG_GETARG_MACADDR_P(1); + + PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) >= 0); +} + +Datum +macaddr_gt(PG_FUNCTION_ARGS) +{ + macaddr *a1 = PG_GETARG_MACADDR_P(0); + macaddr *a2 = PG_GETARG_MACADDR_P(1); + + PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) > 0); +} + +Datum +macaddr_ne(PG_FUNCTION_ARGS) +{ + macaddr *a1 = PG_GETARG_MACADDR_P(0); + macaddr *a2 = PG_GETARG_MACADDR_P(1); + + PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) != 0); +} + /* * The special manufacturer fetching function. */ diff --git a/src/backend/utils/adt/network.c b/src/backend/utils/adt/network.c index eb489d9cd7..9765444eac 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.23 2000/07/06 05:48:11 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/network.c,v 1.24 2000/08/03 23:07:46 tgl Exp $ * * Jon Postel RIP 16 Oct 1998 */ @@ -17,16 +17,11 @@ #include #include "utils/builtins.h" - -/* - * inet is a pass-by-reference datatype. It's not toastable, and we - * don't try to hide the pass-by-refness, so these macros are simple. - */ -#define PG_GETARG_INET_P(n) ((inet *) PG_GETARG_POINTER(n)) -#define PG_RETURN_INET_P(x) return PointerGetDatum(x) +#include "utils/inet.h" static int v4bitncmp(unsigned int a1, unsigned int a2, int bits); +static int32 network_cmp_internal(inet *a1, inet *a2); /* * Access macros. Add IPV6 support. @@ -54,12 +49,7 @@ network_in(char *src, int type) int bits; inet *dst; - if (!src) - return NULL; - - dst = palloc(VARHDRSZ + sizeof(inet_struct)); - if (dst == NULL) - elog(ERROR, "unable to allocate memory in network_in()"); + dst = (inet *) palloc(VARHDRSZ + sizeof(inet_struct)); /* First, try for an IP V4 address: */ ip_family(dst) = AF_INET; @@ -74,32 +64,37 @@ network_in(char *src, int type) + ip_addrsize(dst); ip_bits(dst) = bits; ip_type(dst) = type; + return dst; } /* INET address reader. */ -inet * -inet_in(char *src) +Datum +inet_in(PG_FUNCTION_ARGS) { - return network_in(src, 0); + char *src = PG_GETARG_CSTRING(0); + + PG_RETURN_INET_P(network_in(src, 0)); } /* CIDR address reader. */ -inet * -cidr_in(char *src) +Datum +cidr_in(PG_FUNCTION_ARGS) { - return network_in(src, 1); + char *src = PG_GETARG_CSTRING(0); + + PG_RETURN_INET_P(network_in(src, 1)); } /* * INET address output function. */ - -char * -inet_out(inet *src) +Datum +inet_out(PG_FUNCTION_ARGS) { - char *dst, - tmp[sizeof("255.255.255.255/32")]; + inet *src = PG_GETARG_INET_P(0); + char tmp[sizeof("255.255.255.255/32")]; + char *dst; if (ip_family(src) == AF_INET) { @@ -118,211 +113,201 @@ inet_out(inet *src) /* Go for an IPV6 address here, before faulting out: */ elog(ERROR, "unknown address family (%d)", ip_family(src)); - dst = palloc(strlen(tmp) + 1); - if (dst == NULL) - elog(ERROR, "unable to allocate memory in inet_out()"); - - strcpy(dst, tmp); - return dst; + PG_RETURN_CSTRING(pstrdup(tmp)); } -/* just a stub */ -char * -cidr_out(inet *src) +/* share code with INET case */ +Datum +cidr_out(PG_FUNCTION_ARGS) { - return inet_out(src); + return inet_out(fcinfo); +} + + +/* + * Basic comparison function for sorting and inet/cidr comparisons. + * + * XXX this ignores bits to the right of the mask. That's probably + * correct for CIDR, almost certainly wrong for INET. We need to have + * two sets of comparator routines, not just one. Note that suggests + * that CIDR and INET should not be considered binary-equivalent by + * the parser? + */ + +static int32 +network_cmp_internal(inet *a1, inet *a2) +{ + if (ip_family(a1) == AF_INET && ip_family(a2) == AF_INET) + { + int order = v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), + Min(ip_bits(a1), ip_bits(a2))); + + if (order != 0) + return order; + return ((int32) ip_bits(a1)) - ((int32) ip_bits(a2)); + } + else + { + /* Go for an IPV6 address here, before faulting out: */ + elog(ERROR, "cannot compare address families %d and %d", + ip_family(a1), ip_family(a2)); + return 0; /* keep compiler quiet */ + } +} + +Datum +network_cmp(PG_FUNCTION_ARGS) +{ + inet *a1 = PG_GETARG_INET_P(0); + inet *a2 = PG_GETARG_INET_P(1); + + PG_RETURN_INT32(network_cmp_internal(a1, a2)); } /* - * Boolean tests for magnitude. Add V4/V6 testing! + * Boolean ordering tests. */ - -bool -network_lt(inet *a1, inet *a2) +Datum +network_lt(PG_FUNCTION_ARGS) { - if (!PointerIsValid(a1) || !PointerIsValid(a2)) - return FALSE; + inet *a1 = PG_GETARG_INET_P(0); + inet *a2 = PG_GETARG_INET_P(1); + + PG_RETURN_BOOL(network_cmp_internal(a1, a2) < 0); +} + +Datum +network_le(PG_FUNCTION_ARGS) +{ + inet *a1 = PG_GETARG_INET_P(0); + inet *a2 = PG_GETARG_INET_P(1); + + PG_RETURN_BOOL(network_cmp_internal(a1, a2) <= 0); +} + +Datum +network_eq(PG_FUNCTION_ARGS) +{ + inet *a1 = PG_GETARG_INET_P(0); + inet *a2 = PG_GETARG_INET_P(1); + + PG_RETURN_BOOL(network_cmp_internal(a1, a2) == 0); +} + +Datum +network_ge(PG_FUNCTION_ARGS) +{ + inet *a1 = PG_GETARG_INET_P(0); + inet *a2 = PG_GETARG_INET_P(1); + + PG_RETURN_BOOL(network_cmp_internal(a1, a2) >= 0); +} + +Datum +network_gt(PG_FUNCTION_ARGS) +{ + inet *a1 = PG_GETARG_INET_P(0); + inet *a2 = PG_GETARG_INET_P(1); + + PG_RETURN_BOOL(network_cmp_internal(a1, a2) > 0); +} + +Datum +network_ne(PG_FUNCTION_ARGS) +{ + inet *a1 = PG_GETARG_INET_P(0); + inet *a2 = PG_GETARG_INET_P(1); + + PG_RETURN_BOOL(network_cmp_internal(a1, a2) != 0); +} + +/* + * Boolean network-inclusion tests. + */ +Datum +network_sub(PG_FUNCTION_ARGS) +{ + inet *a1 = PG_GETARG_INET_P(0); + inet *a2 = PG_GETARG_INET_P(1); + if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET)) { - int order = v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)); - - return ((order < 0) || ((order == 0) && (ip_bits(a1) < ip_bits(a2)))); + PG_RETURN_BOOL(ip_bits(a1) > ip_bits(a2) + && v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)) == 0); } else { /* Go for an IPV6 address here, before faulting out: */ elog(ERROR, "cannot compare address families %d and %d", ip_family(a1), ip_family(a2)); - return FALSE; + PG_RETURN_BOOL(false); } } -bool -network_le(inet *a1, inet *a2) +Datum +network_subeq(PG_FUNCTION_ARGS) { - if (!PointerIsValid(a1) || !PointerIsValid(a2)) - return FALSE; - return (network_lt(a1, a2) || network_eq(a1, a2)); -} + inet *a1 = PG_GETARG_INET_P(0); + inet *a2 = PG_GETARG_INET_P(1); -bool -network_eq(inet *a1, inet *a2) -{ - if (!PointerIsValid(a1) || !PointerIsValid(a2)) - return FALSE; if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET)) { - return ((ip_bits(a1) == ip_bits(a2)) - && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0)); + PG_RETURN_BOOL(ip_bits(a1) >= ip_bits(a2) + && v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)) == 0); } else { /* Go for an IPV6 address here, before faulting out: */ elog(ERROR, "cannot compare address families %d and %d", ip_family(a1), ip_family(a2)); - return FALSE; + PG_RETURN_BOOL(false); } } -bool -network_ge(inet *a1, inet *a2) +Datum +network_sup(PG_FUNCTION_ARGS) { - if (!PointerIsValid(a1) || !PointerIsValid(a2)) - return FALSE; - return (network_gt(a1, a2) || network_eq(a1, a2)); -} + inet *a1 = PG_GETARG_INET_P(0); + inet *a2 = PG_GETARG_INET_P(1); -bool -network_gt(inet *a1, inet *a2) -{ - if (!PointerIsValid(a1) || !PointerIsValid(a2)) - return FALSE; if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET)) { - int order = v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)); - - return ((order > 0) || ((order == 0) && (ip_bits(a1) > ip_bits(a2)))); + PG_RETURN_BOOL(ip_bits(a1) < ip_bits(a2) + && v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0); } else { /* Go for an IPV6 address here, before faulting out: */ elog(ERROR, "cannot compare address families %d and %d", ip_family(a1), ip_family(a2)); - return FALSE; + PG_RETURN_BOOL(false); } } -bool -network_ne(inet *a1, inet *a2) +Datum +network_supeq(PG_FUNCTION_ARGS) { - if (!PointerIsValid(a1) || !PointerIsValid(a2)) - return FALSE; - return (!network_eq(a1, a2)); -} - -bool -network_sub(inet *a1, inet *a2) -{ - if (!PointerIsValid(a1) || !PointerIsValid(a2)) - return FALSE; + inet *a1 = PG_GETARG_INET_P(0); + inet *a2 = PG_GETARG_INET_P(1); if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET)) { - return ((ip_bits(a1) > ip_bits(a2)) - && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)) == 0)); + PG_RETURN_BOOL(ip_bits(a1) <= ip_bits(a2) + && v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0); } else { /* Go for an IPV6 address here, before faulting out: */ elog(ERROR, "cannot compare address families %d and %d", ip_family(a1), ip_family(a2)); - return FALSE; - } -} - -bool -network_subeq(inet *a1, inet *a2) -{ - if (!PointerIsValid(a1) || !PointerIsValid(a2)) - return FALSE; - - if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET)) - { - return ((ip_bits(a1) >= ip_bits(a2)) - && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a2)) == 0)); - } - else - { - /* Go for an IPV6 address here, before faulting out: */ - elog(ERROR, "cannot compare address families %d and %d", - ip_family(a1), ip_family(a2)); - return FALSE; - } -} - -bool -network_sup(inet *a1, inet *a2) -{ - if (!PointerIsValid(a1) || !PointerIsValid(a2)) - return FALSE; - - if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET)) - { - return ((ip_bits(a1) < ip_bits(a2)) - && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0)); - } - else - { - /* Go for an IPV6 address here, before faulting out: */ - elog(ERROR, "cannot compare address families %d and %d", - ip_family(a1), ip_family(a2)); - return FALSE; - } -} - -bool -network_supeq(inet *a1, inet *a2) -{ - if (!PointerIsValid(a1) || !PointerIsValid(a2)) - return FALSE; - - if ((ip_family(a1) == AF_INET) && (ip_family(a2) == AF_INET)) - { - return ((ip_bits(a1) <= ip_bits(a2)) - && (v4bitncmp(ip_v4addr(a1), ip_v4addr(a2), ip_bits(a1)) == 0)); - } - else - { - /* Go for an IPV6 address here, before faulting out: */ - elog(ERROR, "cannot compare address families %d and %d", - ip_family(a1), ip_family(a2)); - return FALSE; + PG_RETURN_BOOL(false); } } /* - * Comparison function for sorting. Add V4/V6 testing! + * Extract data from a network datatype. */ - -int4 -network_cmp(inet *a1, inet *a2) -{ - if (ntohl(ip_v4addr(a1)) < ntohl(ip_v4addr(a2))) - return (-1); - - if (ntohl(ip_v4addr(a1)) > ntohl(ip_v4addr(a2))) - return (1); - - if (ip_bits(a1) < ip_bits(a2)) - return (-1); - - if (ip_bits(a1) > ip_bits(a2)) - return (1); - - return 0; -} - Datum network_host(PG_FUNCTION_ARGS) { @@ -357,13 +342,12 @@ network_host(PG_FUNCTION_ARGS) PG_RETURN_TEXT_P(ret); } -int4 -network_masklen(inet *ip) +Datum +network_masklen(PG_FUNCTION_ARGS) { - if (!PointerIsValid(ip)) - return 0; + inet *ip = PG_GETARG_INET_P(0); - return ip_bits(ip); + PG_RETURN_INT32(ip_bits(ip)); } Datum diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 8556c83f53..9919f1509b 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: pg_proc.h,v 1.156 2000/08/03 16:34:31 tgl Exp $ + * $Id: pg_proc.h,v 1.157 2000/08/03 23:07:46 tgl Exp $ * * NOTES * The script catalog/genbki.sh reads this file and generates .bki @@ -2174,68 +2174,68 @@ DATA(insert OID = 1688 ( varbitsubstr PGUID 11 f t t t 2 f 1562 "1562 1562" 10 DESCR("bitwise field"); /* for mac type support */ -DATA(insert OID = 436 ( macaddr_in PGUID 11 f t t t 1 f 829 "0" 100 0 0 100 macaddr_in - )); +DATA(insert OID = 436 ( macaddr_in PGUID 12 f t t t 1 f 829 "0" 100 0 0 100 macaddr_in - )); DESCR("(internal)"); -DATA(insert OID = 437 ( macaddr_out PGUID 11 f t t t 1 f 23 "0" 100 0 0 100 macaddr_out - )); +DATA(insert OID = 437 ( macaddr_out PGUID 12 f t t t 1 f 23 "0" 100 0 0 100 macaddr_out - )); DESCR("(internal)"); -DATA(insert OID = 830 ( macaddr_eq PGUID 11 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_eq - )); +DATA(insert OID = 830 ( macaddr_eq PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_eq - )); DESCR("equal"); -DATA(insert OID = 831 ( macaddr_lt PGUID 11 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_lt - )); +DATA(insert OID = 831 ( macaddr_lt PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_lt - )); DESCR("less-than"); -DATA(insert OID = 832 ( macaddr_le PGUID 11 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_le - )); +DATA(insert OID = 832 ( macaddr_le PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_le - )); DESCR("less-than-or-equal"); -DATA(insert OID = 833 ( macaddr_gt PGUID 11 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_gt - )); +DATA(insert OID = 833 ( macaddr_gt PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_gt - )); DESCR("greater-than"); -DATA(insert OID = 834 ( macaddr_ge PGUID 11 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_ge - )); +DATA(insert OID = 834 ( macaddr_ge PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_ge - )); DESCR("greater-than-or-equal"); -DATA(insert OID = 835 ( macaddr_ne PGUID 11 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_ne - )); +DATA(insert OID = 835 ( macaddr_ne PGUID 12 f t t t 2 f 16 "829 829" 100 0 0 100 macaddr_ne - )); DESCR("not equal"); -DATA(insert OID = 836 ( macaddr_cmp PGUID 11 f t t t 2 f 23 "829 829" 100 0 0 100 macaddr_cmp - )); +DATA(insert OID = 836 ( macaddr_cmp PGUID 12 f t t t 2 f 23 "829 829" 100 0 0 100 macaddr_cmp - )); DESCR("less-equal-greater"); DATA(insert OID = 837 ( macaddr_manuf PGUID 12 f t t t 1 f 25 "829" 100 0 0 100 macaddr_manuf - )); DESCR("MAC manufacturer"); /* for inet type support */ -DATA(insert OID = 910 ( inet_in PGUID 11 f t t t 1 f 869 "0" 100 0 0 100 inet_in - )); +DATA(insert OID = 910 ( inet_in PGUID 12 f t t t 1 f 869 "0" 100 0 0 100 inet_in - )); DESCR("(internal)"); -DATA(insert OID = 911 ( inet_out PGUID 11 f t t t 1 f 23 "0" 100 0 0 100 inet_out - )); +DATA(insert OID = 911 ( inet_out PGUID 12 f t t t 1 f 23 "0" 100 0 0 100 inet_out - )); DESCR("(internal)"); /* for cidr type support */ -DATA(insert OID = 1267 ( cidr_in PGUID 11 f t t t 1 f 650 "0" 100 0 0 100 cidr_in - )); +DATA(insert OID = 1267 ( cidr_in PGUID 12 f t t t 1 f 650 "0" 100 0 0 100 cidr_in - )); DESCR("(internal)"); -DATA(insert OID = 1427 ( cidr_out PGUID 11 f t t t 1 f 23 "0" 100 0 0 100 cidr_out - )); +DATA(insert OID = 1427 ( cidr_out PGUID 12 f t t t 1 f 23 "0" 100 0 0 100 cidr_out - )); DESCR("(internal)"); /* these are used for both inet and cidr */ -DATA(insert OID = 920 ( network_eq PGUID 11 f t t t 2 f 16 "869 869" 100 0 0 100 network_eq - )); +DATA(insert OID = 920 ( network_eq PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_eq - )); DESCR("equal"); -DATA(insert OID = 921 ( network_lt PGUID 11 f t t t 2 f 16 "869 869" 100 0 0 100 network_lt - )); +DATA(insert OID = 921 ( network_lt PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_lt - )); DESCR("less-than"); -DATA(insert OID = 922 ( network_le PGUID 11 f t t t 2 f 16 "869 869" 100 0 0 100 network_le - )); +DATA(insert OID = 922 ( network_le PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_le - )); DESCR("less-than-or-equal"); -DATA(insert OID = 923 ( network_gt PGUID 11 f t t t 2 f 16 "869 869" 100 0 0 100 network_gt - )); +DATA(insert OID = 923 ( network_gt PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_gt - )); DESCR("greater-than"); -DATA(insert OID = 924 ( network_ge PGUID 11 f t t t 2 f 16 "869 869" 100 0 0 100 network_ge - )); +DATA(insert OID = 924 ( network_ge PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_ge - )); DESCR("greater-than-or-equal"); -DATA(insert OID = 925 ( network_ne PGUID 11 f t t t 2 f 16 "869 869" 100 0 0 100 network_ne - )); +DATA(insert OID = 925 ( network_ne PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_ne - )); DESCR("not equal"); -DATA(insert OID = 926 ( network_cmp PGUID 11 f t t t 2 f 23 "869 869" 100 0 0 100 network_cmp - )); +DATA(insert OID = 926 ( network_cmp PGUID 12 f t t t 2 f 23 "869 869" 100 0 0 100 network_cmp - )); DESCR("less-equal-greater"); -DATA(insert OID = 927 ( network_sub PGUID 11 f t t t 2 f 16 "869 869" 100 0 0 100 network_sub - )); +DATA(insert OID = 927 ( network_sub PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_sub - )); DESCR("is-subnet"); -DATA(insert OID = 928 ( network_subeq PGUID 11 f t t t 2 f 16 "869 869" 100 0 0 100 network_subeq - )); +DATA(insert OID = 928 ( network_subeq PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_subeq - )); DESCR("is-subnet-or-equal"); -DATA(insert OID = 929 ( network_sup PGUID 11 f t t t 2 f 16 "869 869" 100 0 0 100 network_sup - )); +DATA(insert OID = 929 ( network_sup PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_sup - )); DESCR("is-supernet"); -DATA(insert OID = 930 ( network_supeq PGUID 11 f t t t 2 f 16 "869 869" 100 0 0 100 network_supeq - )); +DATA(insert OID = 930 ( network_supeq PGUID 12 f t t t 2 f 16 "869 869" 100 0 0 100 network_supeq - )); DESCR("is-supernet-or-equal"); /* inet/cidr versions */ DATA(insert OID = 696 ( netmask PGUID 12 f t t t 1 f 25 "869" 100 0 0 100 network_netmask - )); DESCR("netmask of address"); -DATA(insert OID = 697 ( masklen PGUID 11 f t t t 1 f 23 "869" 100 0 0 100 network_masklen - )); +DATA(insert OID = 697 ( masklen PGUID 12 f t t t 1 f 23 "869" 100 0 0 100 network_masklen - )); DESCR("netmask length"); DATA(insert OID = 698 ( broadcast PGUID 12 f t t t 1 f 25 "869" 100 0 0 100 network_broadcast - )); DESCR("broadcast address"); diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index bb48316413..4fa7481f04 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: builtins.h,v 1.129 2000/08/03 16:34:50 tgl Exp $ + * $Id: builtins.h,v 1.130 2000/08/03 23:07:51 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -16,7 +16,6 @@ #include "nodes/relation.h" /* for amcostestimate parameters */ #include "storage/itemptr.h" -#include "utils/inet.h" #include "utils/numeric.h" /* @@ -436,7 +435,6 @@ extern Datum textlike(PG_FUNCTION_ARGS); extern Datum textnlike(PG_FUNCTION_ARGS); /* oracle_compat.c */ - extern Datum lower(PG_FUNCTION_ARGS); extern Datum upper(PG_FUNCTION_ARGS); extern Datum initcap(PG_FUNCTION_ARGS); @@ -450,48 +448,48 @@ extern Datum ichar(PG_FUNCTION_ARGS); extern Datum repeat(PG_FUNCTION_ARGS); extern Datum ascii(PG_FUNCTION_ARGS); -/* acl.c */ - /* inet_net_ntop.c */ -extern char *inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size); -extern char *inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size); +extern char *inet_net_ntop(int af, const void *src, int bits, + char *dst, size_t size); +extern char *inet_cidr_ntop(int af, const void *src, int bits, + char *dst, size_t size); /* inet_net_pton.c */ -extern int inet_net_pton(int af, const char *src, void *dst, size_t size); +extern int inet_net_pton(int af, const char *src, + void *dst, size_t size); /* network.c */ -extern inet *inet_in(char *str); -extern char *inet_out(inet *addr); -extern inet *cidr_in(char *str); -extern char *cidr_out(inet *addr); -extern bool network_lt(inet *a1, inet *a2); -extern bool network_le(inet *a1, inet *a2); -extern bool network_eq(inet *a1, inet *a2); -extern bool network_ge(inet *a1, inet *a2); -extern bool network_gt(inet *a1, inet *a2); -extern bool network_ne(inet *a1, inet *a2); -extern bool network_sub(inet *a1, inet *a2); -extern bool network_subeq(inet *a1, inet *a2); -extern bool network_sup(inet *a1, inet *a2); -extern bool network_supeq(inet *a1, inet *a2); -extern int4 network_cmp(inet *a1, inet *a2); - +extern Datum inet_in(PG_FUNCTION_ARGS); +extern Datum inet_out(PG_FUNCTION_ARGS); +extern Datum cidr_in(PG_FUNCTION_ARGS); +extern Datum cidr_out(PG_FUNCTION_ARGS); +extern Datum network_cmp(PG_FUNCTION_ARGS); +extern Datum network_lt(PG_FUNCTION_ARGS); +extern Datum network_le(PG_FUNCTION_ARGS); +extern Datum network_eq(PG_FUNCTION_ARGS); +extern Datum network_ge(PG_FUNCTION_ARGS); +extern Datum network_gt(PG_FUNCTION_ARGS); +extern Datum network_ne(PG_FUNCTION_ARGS); +extern Datum network_sub(PG_FUNCTION_ARGS); +extern Datum network_subeq(PG_FUNCTION_ARGS); +extern Datum network_sup(PG_FUNCTION_ARGS); +extern Datum network_supeq(PG_FUNCTION_ARGS); extern Datum network_network(PG_FUNCTION_ARGS); extern Datum network_netmask(PG_FUNCTION_ARGS); -extern int4 network_masklen(inet *addr); +extern Datum network_masklen(PG_FUNCTION_ARGS); extern Datum network_broadcast(PG_FUNCTION_ARGS); extern Datum network_host(PG_FUNCTION_ARGS); /* mac.c */ -extern macaddr *macaddr_in(char *str); -extern char *macaddr_out(macaddr *addr); -extern bool macaddr_lt(macaddr *a1, macaddr *a2); -extern bool macaddr_le(macaddr *a1, macaddr *a2); -extern bool macaddr_eq(macaddr *a1, macaddr *a2); -extern bool macaddr_ge(macaddr *a1, macaddr *a2); -extern bool macaddr_gt(macaddr *a1, macaddr *a2); -extern bool macaddr_ne(macaddr *a1, macaddr *a2); -extern int4 macaddr_cmp(macaddr *a1, macaddr *a2); +extern Datum macaddr_in(PG_FUNCTION_ARGS); +extern Datum macaddr_out(PG_FUNCTION_ARGS); +extern Datum macaddr_cmp(PG_FUNCTION_ARGS); +extern Datum macaddr_lt(PG_FUNCTION_ARGS); +extern Datum macaddr_le(PG_FUNCTION_ARGS); +extern Datum macaddr_eq(PG_FUNCTION_ARGS); +extern Datum macaddr_ge(PG_FUNCTION_ARGS); +extern Datum macaddr_gt(PG_FUNCTION_ARGS); +extern Datum macaddr_ne(PG_FUNCTION_ARGS); extern Datum macaddr_manuf(PG_FUNCTION_ARGS); /* numeric.c */ diff --git a/src/include/utils/inet.h b/src/include/utils/inet.h index 075d66aa6b..5b39801f9c 100644 --- a/src/include/utils/inet.h +++ b/src/include/utils/inet.h @@ -7,17 +7,17 @@ * Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: inet.h,v 1.7 2000/07/06 05:48:31 tgl Exp $ + * $Id: inet.h,v 1.8 2000/08/03 23:07:51 tgl Exp $ * *------------------------------------------------------------------------- */ -#ifndef MAC_H -#define MAC_H +#ifndef INET_H +#define INET_H /* - * This is the internal storage format for IP addresses: + * This is the internal storage format for IP addresses + * (both INET and CIDR datatypes): */ - typedef struct { unsigned char family; @@ -30,8 +30,17 @@ typedef struct } addr; } inet_struct; +/* + * Both INET and CIDR addresses are represented within Postgres as varlena + * objects, ie, there is a varlena header (basically a length word) in front + * of the struct type depicted above. + * + * Although these types are variable-length, the maximum length + * is pretty short, so we make no provision for TOASTing them. + */ typedef struct varlena inet; + /* * This is the internal storage format for MAC addresses: */ @@ -45,4 +54,18 @@ typedef struct macaddr unsigned char f; } macaddr; -#endif /* MAC_H */ +/* + * fmgr interface macros + */ +#define DatumGetInetP(X) ((inet *) DatumGetPointer(X)) +#define InetPGetDatum(X) PointerGetDatum(X) +#define PG_GETARG_INET_P(n) DatumGetInetP(PG_GETARG_DATUM(n)) +#define PG_RETURN_INET_P(x) return InetPGetDatum(x) +/* macaddr is a fixed-length pass-by-reference datatype */ +#define DatumGetMacaddrP(X) ((macaddr *) DatumGetPointer(X)) +#define MacaddrPGetDatum(X) PointerGetDatum(X) +#define PG_GETARG_MACADDR_P(n) DatumGetMacaddrP(PG_GETARG_DATUM(n)) +#define PG_RETURN_MACADDR_P(x) return MacaddrPGetDatum(x) + + +#endif /* INET_H */ diff --git a/src/test/regress/expected/inet.out b/src/test/regress/expected/inet.out index 35bfd77809..6822ae3895 100644 --- a/src/test/regress/expected/inet.out +++ b/src/test/regress/expected/inet.out @@ -128,7 +128,7 @@ SELECT '' AS ten, i, c, | 192.168.1.226/24 | 192.168.1/24 | f | t | t | t | f | f | f | t | f | t | 192.168.1.226 | 192.168.1/24 | f | f | f | t | t | t | t | t | f | f | 10.1.2.3/8 | 10/8 | f | t | t | t | f | f | f | t | f | t - | 10.1.2.3/8 | 10.0.0.0/32 | f | f | f | t | t | t | f | f | t | t + | 10.1.2.3/8 | 10.0.0.0/32 | t | t | f | f | f | t | f | f | t | t | 10.1.2.3 | 10.1.2.3/32 | f | t | t | t | f | f | f | t | f | t | 10.1.2.3/24 | 10.1.2/24 | f | t | t | t | f | f | f | t | f | t | 10.1.2.3/16 | 10.1/16 | f | t | t | t | f | f | f | t | f | t