diff --git a/contrib/btree_gin/btree_gin.c b/contrib/btree_gin/btree_gin.c index 030b610..a76060f 100644 --- a/contrib/btree_gin/btree_gin.c +++ b/contrib/btree_gin/btree_gin.c @@ -313,14 +313,22 @@ leftmostvalue_interval(void) GIN_SUPPORT(interval, false, leftmostvalue_interval, interval_cmp) static Datum -leftmostvalue_macaddr(void) +leftmostvalue_macaddr6(void) { - macaddr *v = palloc0(sizeof(macaddr)); + macaddr6 *v = palloc0(sizeof(macaddr6)); + + return Macaddr6PGetDatum(v); +} + +GIN_SUPPORT(macaddr6, false, leftmostvalue_macaddr6, macaddr6_cmp) - return MacaddrPGetDatum(v); +static Datum +leftmostvalue_macaddr(void) +{ + return DirectFunctionCall1(macaddr_in, CStringGetDatum("00-00-00-00-00-00")); } -GIN_SUPPORT(macaddr, false, leftmostvalue_macaddr, macaddr_cmp) +GIN_SUPPORT(macaddr, true, leftmostvalue_macaddr, macaddr_cmp) static Datum leftmostvalue_inet(void) diff --git a/contrib/btree_gist/btree_macaddr.c b/contrib/btree_gist/btree_macaddr.c index 87d96c0..c074e95 100644 --- a/contrib/btree_gist/btree_macaddr.c +++ b/contrib/btree_gist/btree_macaddr.c @@ -10,8 +10,8 @@ typedef struct { - macaddr lower; - macaddr upper; + macaddr6 lower; + macaddr6 upper; char pad[4]; /* make struct size = sizeof(gbtreekey16) */ } macKEY; @@ -30,30 +30,30 @@ PG_FUNCTION_INFO_V1(gbt_macad_same); static bool gbt_macadgt(const void *a, const void *b) { - return DatumGetBool(DirectFunctionCall2(macaddr_gt, PointerGetDatum(a), PointerGetDatum(b))); + return DatumGetBool(DirectFunctionCall2(macaddr6_gt, PointerGetDatum(a), PointerGetDatum(b))); } static bool gbt_macadge(const void *a, const void *b) { - return DatumGetBool(DirectFunctionCall2(macaddr_ge, PointerGetDatum(a), PointerGetDatum(b))); + return DatumGetBool(DirectFunctionCall2(macaddr6_ge, PointerGetDatum(a), PointerGetDatum(b))); } static bool gbt_macadeq(const void *a, const void *b) { - return DatumGetBool(DirectFunctionCall2(macaddr_eq, PointerGetDatum(a), PointerGetDatum(b))); + return DatumGetBool(DirectFunctionCall2(macaddr6_eq, PointerGetDatum(a), PointerGetDatum(b))); } static bool gbt_macadle(const void *a, const void *b) { - return DatumGetBool(DirectFunctionCall2(macaddr_le, PointerGetDatum(a), PointerGetDatum(b))); + return DatumGetBool(DirectFunctionCall2(macaddr6_le, PointerGetDatum(a), PointerGetDatum(b))); } static bool gbt_macadlt(const void *a, const void *b) { - return DatumGetBool(DirectFunctionCall2(macaddr_lt, PointerGetDatum(a), PointerGetDatum(b))); + return DatumGetBool(DirectFunctionCall2(macaddr6_lt, PointerGetDatum(a), PointerGetDatum(b))); } @@ -64,9 +64,9 @@ gbt_macadkey_cmp(const void *a, const void *b) macKEY *ib = (macKEY *) (((const Nsrt *) b)->t); int res; - res = DatumGetInt32(DirectFunctionCall2(macaddr_cmp, MacaddrPGetDatum(&ia->lower), MacaddrPGetDatum(&ib->lower))); + res = DatumGetInt32(DirectFunctionCall2(macaddr6_cmp, Macaddr6PGetDatum(&ia->lower), Macaddr6PGetDatum(&ib->lower))); if (res == 0) - return DatumGetInt32(DirectFunctionCall2(macaddr_cmp, MacaddrPGetDatum(&ia->upper), MacaddrPGetDatum(&ib->upper))); + return DatumGetInt32(DirectFunctionCall2(macaddr6_cmp, Macaddr6PGetDatum(&ia->upper), Macaddr6PGetDatum(&ib->upper))); return res; } @@ -75,7 +75,7 @@ gbt_macadkey_cmp(const void *a, const void *b) static const gbtree_ninfo tinfo = { gbt_t_macad, - sizeof(macaddr), + sizeof(macaddr6), 16, /* sizeof(gbtreekey16) */ gbt_macadgt, gbt_macadge, @@ -94,7 +94,7 @@ static const gbtree_ninfo tinfo = static uint64 -mac_2_uint64(macaddr *m) +mac_2_uint64(macaddr6 *m) { unsigned char *mi = (unsigned char *) m; uint64 res = 0; @@ -127,7 +127,7 @@ Datum gbt_macad_consistent(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); - macaddr *query = (macaddr *) PG_GETARG_POINTER(1); + macaddr6 *query = (macaddr6 *) PG_GETARG_POINTER(1); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); /* Oid subtype = PG_GETARG_OID(3); */ diff --git a/src/backend/utils/adt/Makefile b/src/backend/utils/adt/Makefile index 0f51275..840a1ee 100644 --- a/src/backend/utils/adt/Makefile +++ b/src/backend/utils/adt/Makefile @@ -16,7 +16,7 @@ OBJS = acl.o amutils.o arrayfuncs.o array_expanded.o array_selfuncs.o \ float.o format_type.o formatting.o genfile.o \ geo_ops.o geo_selfuncs.o geo_spgist.o inet_cidr_ntop.o inet_net_pton.o \ int.o int8.o json.o jsonb.o jsonb_gin.o jsonb_op.o jsonb_util.o \ - jsonfuncs.o like.o lockfuncs.o mac.o misc.o nabstime.o name.o \ + jsonfuncs.o like.o lockfuncs.o mac6.o mac.o misc.o nabstime.o name.o \ network.o network_gist.o network_selfuncs.o network_spgist.o \ numeric.o numutils.o oid.o oracle_compat.o \ orderedsetaggs.o pg_locale.o pg_lsn.o pg_upgrade_support.o \ diff --git a/src/backend/utils/adt/mac.c b/src/backend/utils/adt/mac.c index 509315a..b1ffa1a 100644 --- a/src/backend/utils/adt/mac.c +++ b/src/backend/utils/adt/mac.c @@ -1,5 +1,8 @@ /* - * PostgreSQL type definitions for MAC addresses. + * PostgreSQL type definitions for MAC addresses + * Support both EUI-48 and EUI-64. + * + * The entire code is written as treating OUI field size as 24 bits * * src/backend/utils/adt/mac.c */ @@ -11,19 +14,21 @@ #include "utils/builtins.h" #include "utils/inet.h" - /* * Utility macros used for sorting and comparing: */ #define hibits(addr) \ - ((unsigned long)(((addr)->a<<16)|((addr)->b<<8)|((addr)->c))) + ((unsigned long)(((addr)->data[0]<<24)|((addr)->data[1]<<16)|((addr)->data[2]<<8))) #define lobits(addr) \ - ((unsigned long)(((addr)->d<<16)|((addr)->e<<8)|((addr)->f))) + ((unsigned long)(((addr)->data[3]<<16)|((addr)->data[4]<<8)|((addr)->data[5]))) + +#define lobits_extra(addr) \ + ((unsigned long)((addr)->data[6]<<8)|((addr)->data[7])) /* - * MAC address reader. Accepts several common notations. + * MAC address (EUI-48 and EUI-64) reader. Accepts several common notations. */ Datum @@ -31,58 +36,114 @@ macaddr_in(PG_FUNCTION_ARGS) { char *str = PG_GETARG_CSTRING(0); macaddr *result; + mac_struct *addr; int a, b, c, d, e, - f; + f, + g = 0, + h = 0; char junk[2]; int count; + bool eight_byte_address = false; - /* %1s matches iff there is trailing non-whitespace garbage */ + /* %1s matches iff there is trailing non-whitespace garbage */ count = sscanf(str, "%x:%x:%x:%x:%x:%x%1s", &a, &b, &c, &d, &e, &f, junk); if (count != 6) count = sscanf(str, "%x-%x-%x-%x-%x-%x%1s", - &a, &b, &c, &d, &e, &f, junk); + &a, &b, &c, &d, &e, &f, junk); if (count != 6) count = sscanf(str, "%2x%2x%2x:%2x%2x%2x%1s", - &a, &b, &c, &d, &e, &f, junk); + &a, &b, &c, &d, &e, &f, junk); if (count != 6) count = sscanf(str, "%2x%2x%2x-%2x%2x%2x%1s", - &a, &b, &c, &d, &e, &f, junk); + &a, &b, &c, &d, &e, &f, junk); if (count != 6) count = sscanf(str, "%2x%2x.%2x%2x.%2x%2x%1s", - &a, &b, &c, &d, &e, &f, junk); + &a, &b, &c, &d, &e, &f, junk); if (count != 6) count = sscanf(str, "%2x%2x-%2x%2x-%2x%2x%1s", - &a, &b, &c, &d, &e, &f, junk); + &a, &b, &c, &d, &e, &f, junk); if (count != 6) count = sscanf(str, "%2x%2x%2x%2x%2x%2x%1s", - &a, &b, &c, &d, &e, &f, junk); + &a, &b, &c, &d, &e, &f, junk); + if (count != 6) - ereport(ERROR, - (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), - errmsg("invalid input syntax for type macaddr: \"%s\"", str))); + { + /* May be a 8-byte MAC address */ + eight_byte_address = true; + + count = sscanf(str, "%x:%x:%x:%x:%x:%x:%x:%x%1s", + &a, &b, &c, &d, &e, &f, &g, &h, junk); + if (count != 8) + count = sscanf(str, "%x-%x-%x-%x-%x-%x-%x-%x%1s", + &a, &b, &c, &d, &e, &f, &g, &h, junk); + if (count != 8) + count = sscanf(str, "%2x%2x%2x:%2x%2x%2x%2x%2x%1s", + &a, &b, &c, &d, &e, &f, &g, &h, junk); + if (count != 8) + count = sscanf(str, "%2x%2x%2x-%2x%2x%2x%2x%2x%1s", + &a, &b, &c, &d, &e, &f, &g, &h, junk); + if (count != 8) + count = sscanf(str, "%2x%2x.%2x%2x.%2x%2x.%2x%2x%1s", + &a, &b, &c, &d, &e, &f, &g, &h, junk); + if (count != 8) + count = sscanf(str, "%2x%2x-%2x%2x-%2x%2x-%2x%2x%1s", + &a, &b, &c, &d, &e, &f, &g, &h, junk); + if (count != 8) + count = sscanf(str, "%2x%2x%2x%2x%2x%2x%2x%2x%1s", + &a, &b, &c, &d, &e, &f, &g, &h, junk); + if (count != 8) + { + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type macaddr: \"%s\"", str))); + } + } if ((a < 0) || (a > 255) || (b < 0) || (b > 255) || (c < 0) || (c > 255) || (d < 0) || (d > 255) || - (e < 0) || (e > 255) || (f < 0) || (f > 255)) + (e < 0) || (e > 255) || (f < 0) || (f > 255) || + (g < 0) || (g > 255) || (h < 0) || (h > 255)) ereport(ERROR, (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), - errmsg("invalid octet value in \"macaddr\" value: \"%s\"", str))); - - result = (macaddr *) palloc(sizeof(macaddr)); + errmsg("invalid octet value in \"macaddr\" value: \"%s\"", str))); - result->a = a; - result->b = b; - result->c = c; - result->d = d; - result->e = e; - result->f = f; + if ((a == 0) && (b == 0) && (c == 0) && (d == 0) + && (e == 0) && (f == 0) && (g == 0) && (h == 0)) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("invalid \"macaddr\" Address: \"%s\"", str), + errhint ("00-00-00-00-00-00-00-00 address is a reserved address"))); + if ((a == 255) && (b == 255) && (c == 255) && (d == 255) + && (e == 255) && (f == 255) && (g == 255) && (h == 255)) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("invalid \"macaddr\" Address: \"%s\"", str), + errhint ("FF-FF-FF-FF-FF-FF-FF-FF address is a reserved address"))); + + result = (macaddr *) palloc0(sizeof(macaddr)); + addr = MACADDR(result); + + addr->data[0] = a; + addr->data[1] = b; + addr->data[2] = c; + addr->data[3] = d; + addr->data[4] = e; + addr->data[5] = f; + + if (eight_byte_address) + { + addr->data[6] = g; + addr->data[7] = h; + } + + SET_MACADDR_VARSIZE(result, count); PG_RETURN_MACADDR_P(result); } @@ -93,19 +154,26 @@ macaddr_in(PG_FUNCTION_ARGS) Datum macaddr_out(PG_FUNCTION_ARGS) { - macaddr *addr = PG_GETARG_MACADDR_P(0); + macaddr *addr = PG_GETARG_MACADDR_PP(0); char *result; result = (char *) palloc(32); - snprintf(result, 32, "%02x:%02x:%02x:%02x:%02x:%02x", - addr->a, addr->b, addr->c, addr->d, addr->e, addr->f); + if (MACADDR_SIZE(addr) == 8) + snprintf(result, 32, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + MACADDR(addr)->data[0], MACADDR(addr)->data[1], MACADDR(addr)->data[2], + MACADDR(addr)->data[3], MACADDR(addr)->data[4], MACADDR(addr)->data[5], + MACADDR(addr)->data[6], MACADDR(addr)->data[7]); + else + snprintf(result, 32, "%02x:%02x:%02x:%02x:%02x:%02x", + MACADDR(addr)->data[0], MACADDR(addr)->data[1], MACADDR(addr)->data[2], + MACADDR(addr)->data[3], MACADDR(addr)->data[4], MACADDR(addr)->data[5]); PG_RETURN_CSTRING(result); } /* - * macaddr_recv - converts external binary format to macaddr + * macaddr_recv - converts external binary format(EUI-48 and EUI-64) to macaddr * * The external representation is just the six bytes, MSB first. */ @@ -115,34 +183,48 @@ macaddr_recv(PG_FUNCTION_ARGS) StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); macaddr *addr; - addr = (macaddr *) palloc(sizeof(macaddr)); + addr = (macaddr *) palloc0(sizeof(macaddr)); + + MACADDR(addr)->data[0] = pq_getmsgbyte(buf); + MACADDR(addr)->data[1] = pq_getmsgbyte(buf); + MACADDR(addr)->data[2] = pq_getmsgbyte(buf); + MACADDR(addr)->data[3] = pq_getmsgbyte(buf); + MACADDR(addr)->data[4] = pq_getmsgbyte(buf); + MACADDR(addr)->data[5] = pq_getmsgbyte(buf); - addr->a = pq_getmsgbyte(buf); - addr->b = pq_getmsgbyte(buf); - addr->c = pq_getmsgbyte(buf); - addr->d = pq_getmsgbyte(buf); - addr->e = pq_getmsgbyte(buf); - addr->f = pq_getmsgbyte(buf); + if (buf->len == 8) + { + MACADDR(addr)->data[6] = pq_getmsgbyte(buf); + MACADDR(addr)->data[7] = pq_getmsgbyte(buf); + } + SET_MACADDR_VARSIZE(addr, buf->len); PG_RETURN_MACADDR_P(addr); } /* - * macaddr_send - converts macaddr to binary format + * macaddr_send - converts macaddr(EUI-48 and EUI-64) to binary format */ Datum macaddr_send(PG_FUNCTION_ARGS) { - macaddr *addr = PG_GETARG_MACADDR_P(0); + macaddr *addr = PG_GETARG_MACADDR_PP(0); StringInfoData buf; pq_begintypsend(&buf); - pq_sendbyte(&buf, addr->a); - pq_sendbyte(&buf, addr->b); - pq_sendbyte(&buf, addr->c); - pq_sendbyte(&buf, addr->d); - pq_sendbyte(&buf, addr->e); - pq_sendbyte(&buf, addr->f); + pq_sendbyte(&buf, MACADDR(addr)->data[0]); + pq_sendbyte(&buf, MACADDR(addr)->data[1]); + pq_sendbyte(&buf, MACADDR(addr)->data[2]); + pq_sendbyte(&buf, MACADDR(addr)->data[3]); + pq_sendbyte(&buf, MACADDR(addr)->data[4]); + pq_sendbyte(&buf, MACADDR(addr)->data[5]); + + if (MACADDR_SIZE(addr) == 8) + { + pq_sendbyte(&buf, MACADDR(addr)->data[6]); + pq_sendbyte(&buf, MACADDR(addr)->data[7]); + } + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); } @@ -154,23 +236,40 @@ macaddr_send(PG_FUNCTION_ARGS) static int32 macaddr_cmp_internal(macaddr *a1, macaddr *a2) { - if (hibits(a1) < hibits(a2)) + int size1 = MACADDR_SIZE(a1); + int size2 = MACADDR_SIZE(a2); + + if (hibits(MACADDR(a1)) < hibits(MACADDR(a2))) return -1; - else if (hibits(a1) > hibits(a2)) + else if (hibits(MACADDR(a1)) > hibits(MACADDR(a2))) return 1; - else if (lobits(a1) < lobits(a2)) + else if (lobits(MACADDR(a1)) < lobits(MACADDR(a2))) return -1; - else if (lobits(a1) > lobits(a2)) + else if (lobits(MACADDR(a1)) > lobits(MACADDR(a2))) return 1; else + { + if (size1 == 8 && size2 == 8) + { + if (lobits_extra(MACADDR(a1)) < lobits_extra(MACADDR(a2))) + return -1; + else if (lobits_extra(MACADDR(a1)) > lobits_extra(MACADDR(a2))) + return 1; + } + else if (size1 == 8) + return 1; + else if (size2 == 8) + return -1; + return 0; + } } Datum macaddr_cmp(PG_FUNCTION_ARGS) { - macaddr *a1 = PG_GETARG_MACADDR_P(0); - macaddr *a2 = PG_GETARG_MACADDR_P(1); + macaddr *a1 = PG_GETARG_MACADDR_PP(0); + macaddr *a2 = PG_GETARG_MACADDR_PP(1); PG_RETURN_INT32(macaddr_cmp_internal(a1, a2)); } @@ -182,8 +281,8 @@ macaddr_cmp(PG_FUNCTION_ARGS) Datum macaddr_lt(PG_FUNCTION_ARGS) { - macaddr *a1 = PG_GETARG_MACADDR_P(0); - macaddr *a2 = PG_GETARG_MACADDR_P(1); + macaddr *a1 = PG_GETARG_MACADDR_PP(0); + macaddr *a2 = PG_GETARG_MACADDR_PP(1); PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) < 0); } @@ -191,8 +290,8 @@ macaddr_lt(PG_FUNCTION_ARGS) Datum macaddr_le(PG_FUNCTION_ARGS) { - macaddr *a1 = PG_GETARG_MACADDR_P(0); - macaddr *a2 = PG_GETARG_MACADDR_P(1); + macaddr *a1 = PG_GETARG_MACADDR_PP(0); + macaddr *a2 = PG_GETARG_MACADDR_PP(1); PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) <= 0); } @@ -200,8 +299,8 @@ macaddr_le(PG_FUNCTION_ARGS) Datum macaddr_eq(PG_FUNCTION_ARGS) { - macaddr *a1 = PG_GETARG_MACADDR_P(0); - macaddr *a2 = PG_GETARG_MACADDR_P(1); + macaddr *a1 = PG_GETARG_MACADDR_PP(0); + macaddr *a2 = PG_GETARG_MACADDR_PP(1); PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) == 0); } @@ -209,8 +308,8 @@ macaddr_eq(PG_FUNCTION_ARGS) Datum macaddr_ge(PG_FUNCTION_ARGS) { - macaddr *a1 = PG_GETARG_MACADDR_P(0); - macaddr *a2 = PG_GETARG_MACADDR_P(1); + macaddr *a1 = PG_GETARG_MACADDR_PP(0); + macaddr *a2 = PG_GETARG_MACADDR_PP(1); PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) >= 0); } @@ -218,8 +317,8 @@ macaddr_ge(PG_FUNCTION_ARGS) Datum macaddr_gt(PG_FUNCTION_ARGS) { - macaddr *a1 = PG_GETARG_MACADDR_P(0); - macaddr *a2 = PG_GETARG_MACADDR_P(1); + macaddr *a1 = PG_GETARG_MACADDR_PP(0); + macaddr *a2 = PG_GETARG_MACADDR_PP(1); PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) > 0); } @@ -227,8 +326,8 @@ macaddr_gt(PG_FUNCTION_ARGS) Datum macaddr_ne(PG_FUNCTION_ARGS) { - macaddr *a1 = PG_GETARG_MACADDR_P(0); - macaddr *a2 = PG_GETARG_MACADDR_P(1); + macaddr *a1 = PG_GETARG_MACADDR_PP(0); + macaddr *a2 = PG_GETARG_MACADDR_PP(1); PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) != 0); } @@ -239,9 +338,9 @@ macaddr_ne(PG_FUNCTION_ARGS) Datum hashmacaddr(PG_FUNCTION_ARGS) { - macaddr *key = PG_GETARG_MACADDR_P(0); + macaddr *key = PG_GETARG_MACADDR_PP(0); - return hash_any((unsigned char *) key, sizeof(macaddr)); + return hash_any((unsigned char *) MACADDR(key), MACADDR_SIZE(key)); } /* @@ -250,50 +349,95 @@ hashmacaddr(PG_FUNCTION_ARGS) Datum macaddr_not(PG_FUNCTION_ARGS) { - macaddr *addr = PG_GETARG_MACADDR_P(0); + macaddr *addr = PG_GETARG_MACADDR_PP(0); macaddr *result; + int size1 = MACADDR_SIZE(addr); + int size2 = MACADDR_SIZE(addr); - result = (macaddr *) palloc(sizeof(macaddr)); - result->a = ~addr->a; - result->b = ~addr->b; - result->c = ~addr->c; - result->d = ~addr->d; - result->e = ~addr->e; - result->f = ~addr->f; + if (size1 != size2) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("Different length input addresses"))); + + result = (macaddr *) palloc0(sizeof(macaddr)); + MACADDR(result)->data[0] = ~MACADDR(addr)->data[0]; + MACADDR(result)->data[1] = ~MACADDR(addr)->data[1]; + MACADDR(result)->data[2] = ~MACADDR(addr)->data[2]; + MACADDR(result)->data[3] = ~MACADDR(addr)->data[3]; + MACADDR(result)->data[4] = ~MACADDR(addr)->data[4]; + MACADDR(result)->data[5] = ~MACADDR(addr)->data[5]; + + if (size1 == 8) + { + MACADDR(result)->data[6] = ~MACADDR(addr)->data[6]; + MACADDR(result)->data[7] = ~MACADDR(addr)->data[7]; + } + + SET_MACADDR_VARSIZE(result, size1); PG_RETURN_MACADDR_P(result); } Datum macaddr_and(PG_FUNCTION_ARGS) { - macaddr *addr1 = PG_GETARG_MACADDR_P(0); - macaddr *addr2 = PG_GETARG_MACADDR_P(1); + macaddr *addr1 = PG_GETARG_MACADDR_PP(0); + macaddr *addr2 = PG_GETARG_MACADDR_PP(1); macaddr *result; + int size1 = MACADDR_SIZE(addr1); + int size2 = MACADDR_SIZE(addr1); - result = (macaddr *) palloc(sizeof(macaddr)); - result->a = addr1->a & addr2->a; - result->b = addr1->b & addr2->b; - result->c = addr1->c & addr2->c; - result->d = addr1->d & addr2->d; - result->e = addr1->e & addr2->e; - result->f = addr1->f & addr2->f; + if (size1 != size2) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("Different length input addresses"))); + + result = (macaddr *) palloc0(sizeof(macaddr)); + MACADDR(result)->data[0] = MACADDR(addr1)->data[0] & MACADDR(addr2)->data[0]; + MACADDR(result)->data[1] = MACADDR(addr1)->data[1] & MACADDR(addr2)->data[1]; + MACADDR(result)->data[2] = MACADDR(addr1)->data[2] & MACADDR(addr2)->data[2]; + MACADDR(result)->data[3] = MACADDR(addr1)->data[3] & MACADDR(addr2)->data[3]; + MACADDR(result)->data[4] = MACADDR(addr1)->data[4] & MACADDR(addr2)->data[4]; + MACADDR(result)->data[5] = MACADDR(addr1)->data[5] & MACADDR(addr2)->data[5]; + + if (size1 == 8) + { + MACADDR(result)->data[6] = MACADDR(addr1)->data[6] & MACADDR(addr2)->data[6]; + MACADDR(result)->data[7] = MACADDR(addr1)->data[7] & MACADDR(addr2)->data[7]; + } + + SET_MACADDR_VARSIZE(result, size1); PG_RETURN_MACADDR_P(result); } Datum macaddr_or(PG_FUNCTION_ARGS) { - macaddr *addr1 = PG_GETARG_MACADDR_P(0); - macaddr *addr2 = PG_GETARG_MACADDR_P(1); + macaddr *addr1 = PG_GETARG_MACADDR_PP(0); + macaddr *addr2 = PG_GETARG_MACADDR_PP(1); macaddr *result; + int size1 = MACADDR_SIZE(addr1); + int size2 = MACADDR_SIZE(addr1); - result = (macaddr *) palloc(sizeof(macaddr)); - result->a = addr1->a | addr2->a; - result->b = addr1->b | addr2->b; - result->c = addr1->c | addr2->c; - result->d = addr1->d | addr2->d; - result->e = addr1->e | addr2->e; - result->f = addr1->f | addr2->f; + if (size1 != size2) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("Different length input addresses"))); + + result = (macaddr *) palloc0(sizeof(macaddr)); + MACADDR(result)->data[0] = MACADDR(addr1)->data[0] | MACADDR(addr2)->data[0]; + MACADDR(result)->data[1] = MACADDR(addr1)->data[1] | MACADDR(addr2)->data[1]; + MACADDR(result)->data[2] = MACADDR(addr1)->data[2] | MACADDR(addr2)->data[2]; + MACADDR(result)->data[3] = MACADDR(addr1)->data[3] | MACADDR(addr2)->data[3]; + MACADDR(result)->data[4] = MACADDR(addr1)->data[4] | MACADDR(addr2)->data[4]; + MACADDR(result)->data[5] = MACADDR(addr1)->data[5] | MACADDR(addr2)->data[5]; + + if (size1 == 8) + { + MACADDR(result)->data[6] = MACADDR(addr1)->data[6] | MACADDR(addr2)->data[6]; + MACADDR(result)->data[7] = MACADDR(addr1)->data[7] | MACADDR(addr2)->data[7]; + } + + SET_MACADDR_VARSIZE(result, size1); PG_RETURN_MACADDR_P(result); } @@ -304,17 +448,43 @@ macaddr_or(PG_FUNCTION_ARGS) Datum macaddr_trunc(PG_FUNCTION_ARGS) { - macaddr *addr = PG_GETARG_MACADDR_P(0); + macaddr *addr = PG_GETARG_MACADDR_PP(0); macaddr *result; + int size = MACADDR_SIZE(addr); - result = (macaddr *) palloc(sizeof(macaddr)); + result = (macaddr *) palloc0(sizeof(macaddr)); - result->a = addr->a; - result->b = addr->b; - result->c = addr->c; - result->d = 0; - result->e = 0; - result->f = 0; + MACADDR(result)->data[0] = MACADDR(addr)->data[0]; + MACADDR(result)->data[1] = MACADDR(addr)->data[1]; + MACADDR(result)->data[2] = MACADDR(addr)->data[2]; + MACADDR(result)->data[3] = 0; + MACADDR(result)->data[4] = 0; + MACADDR(result)->data[5] = 0; + MACADDR(result)->data[6] = 0; + MACADDR(result)->data[7] = 0; + SET_MACADDR_VARSIZE(result, size); PG_RETURN_MACADDR_P(result); } + +Datum +mac6tomac(PG_FUNCTION_ARGS) +{ + macaddr6 *addr6 = PG_GETARG_MACADDR6_P(0); + macaddr *result; + + result = (macaddr *) palloc0(sizeof(macaddr)); + + MACADDR(result)->data[0] = addr6->a; + MACADDR(result)->data[1] = addr6->b; + MACADDR(result)->data[2] = addr6->c; + MACADDR(result)->data[3] = 0xFF; + MACADDR(result)->data[4] = 0xFE; + MACADDR(result)->data[5] = addr6->d; + MACADDR(result)->data[6] = addr6->e; + MACADDR(result)->data[7] = addr6->f; + + SET_MACADDR_VARSIZE(result, 8); + PG_RETURN_MACADDR_P(result); +} + diff --git a/src/backend/utils/adt/mac6.c b/src/backend/utils/adt/mac6.c new file mode 100644 index 0000000..670ca4b --- /dev/null +++ b/src/backend/utils/adt/mac6.c @@ -0,0 +1,321 @@ +/* + * PostgreSQL type definitions for MAC addresses. + * Supports only 6-byte MAC addresses + * + * src/backend/utils/adt/mac.c + */ + +#include "postgres.h" + +#include "access/hash.h" +#include "libpq/pqformat.h" +#include "utils/builtins.h" +#include "utils/inet.h" + + +/* + * Utility macros used for sorting and comparing: + */ + +#define hibits(addr) \ + ((unsigned long)(((addr)->a<<16)|((addr)->b<<8)|((addr)->c))) + +#define lobits(addr) \ + ((unsigned long)(((addr)->d<<16)|((addr)->e<<8)|((addr)->f))) + +/* + * MAC address reader. Accepts several common notations. + */ + +Datum +macaddr6_in(PG_FUNCTION_ARGS) +{ + char *str = PG_GETARG_CSTRING(0); + macaddr6 *result; + int a, + b, + c, + d, + e, + f; + char junk[2]; + int count; + + /* %1s matches iff there is trailing non-whitespace garbage */ + + count = sscanf(str, "%x:%x:%x:%x:%x:%x%1s", + &a, &b, &c, &d, &e, &f, junk); + if (count != 6) + count = sscanf(str, "%x-%x-%x-%x-%x-%x%1s", + &a, &b, &c, &d, &e, &f, junk); + if (count != 6) + count = sscanf(str, "%2x%2x%2x:%2x%2x%2x%1s", + &a, &b, &c, &d, &e, &f, junk); + if (count != 6) + count = sscanf(str, "%2x%2x%2x-%2x%2x%2x%1s", + &a, &b, &c, &d, &e, &f, junk); + if (count != 6) + count = sscanf(str, "%2x%2x.%2x%2x.%2x%2x%1s", + &a, &b, &c, &d, &e, &f, junk); + if (count != 6) + count = sscanf(str, "%2x%2x-%2x%2x-%2x%2x%1s", + &a, &b, &c, &d, &e, &f, junk); + if (count != 6) + count = sscanf(str, "%2x%2x%2x%2x%2x%2x%1s", + &a, &b, &c, &d, &e, &f, junk); + if (count != 6) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid input syntax for type macaddr6: \"%s\"", str))); + + if ((a < 0) || (a > 255) || (b < 0) || (b > 255) || + (c < 0) || (c > 255) || (d < 0) || (d > 255) || + (e < 0) || (e > 255) || (f < 0) || (f > 255)) + ereport(ERROR, + (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("invalid octet value in \"macaddr6\" value: \"%s\"", str))); + + result = (macaddr6 *) palloc(sizeof(macaddr6)); + + result->a = a; + result->b = b; + result->c = c; + result->d = d; + result->e = e; + result->f = f; + + PG_RETURN_MACADDR6_P(result); +} + +/* + * MAC address output function. Fixed format. + */ + +Datum +macaddr6_out(PG_FUNCTION_ARGS) +{ + macaddr6 *addr = PG_GETARG_MACADDR6_P(0); + char *result; + + result = (char *) palloc(32); + + snprintf(result, 32, "%02x:%02x:%02x:%02x:%02x:%02x", + addr->a, addr->b, addr->c, addr->d, addr->e, addr->f); + + PG_RETURN_CSTRING(result); +} + +/* + * macaddr6_recv - converts external binary format to macaddr6 + * + * The external representation is just the six bytes, MSB first. + */ +Datum +macaddr6_recv(PG_FUNCTION_ARGS) +{ + StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); + macaddr6 *addr; + + addr = (macaddr6 *) palloc(sizeof(macaddr6)); + + addr->a = pq_getmsgbyte(buf); + addr->b = pq_getmsgbyte(buf); + addr->c = pq_getmsgbyte(buf); + addr->d = pq_getmsgbyte(buf); + addr->e = pq_getmsgbyte(buf); + addr->f = pq_getmsgbyte(buf); + + PG_RETURN_MACADDR6_P(addr); +} + +/* + * macaddr6_send - converts macaddr6 to binary format + */ +Datum +macaddr6_send(PG_FUNCTION_ARGS) +{ + macaddr6 *addr = PG_GETARG_MACADDR6_P(0); + StringInfoData buf; + + pq_begintypsend(&buf); + pq_sendbyte(&buf, addr->a); + pq_sendbyte(&buf, addr->b); + pq_sendbyte(&buf, addr->c); + pq_sendbyte(&buf, addr->d); + pq_sendbyte(&buf, addr->e); + pq_sendbyte(&buf, addr->f); + PG_RETURN_BYTEA_P(pq_endtypsend(&buf)); +} + + +/* + * Comparison function for sorting: + */ + +static int32 +macaddr6_cmp_internal(macaddr6 *a1, macaddr6 *a2) +{ + if (hibits(a1) < hibits(a2)) + return -1; + else if (hibits(a1) > hibits(a2)) + return 1; + else if (lobits(a1) < lobits(a2)) + return -1; + else if (lobits(a1) > lobits(a2)) + return 1; + else + return 0; +} + +Datum +macaddr6_cmp(PG_FUNCTION_ARGS) +{ + macaddr6 *a1 = PG_GETARG_MACADDR6_P(0); + macaddr6 *a2 = PG_GETARG_MACADDR6_P(1); + + PG_RETURN_INT32(macaddr6_cmp_internal(a1, a2)); +} + +/* + * Boolean comparisons. + */ + +Datum +macaddr6_lt(PG_FUNCTION_ARGS) +{ + macaddr6 *a1 = PG_GETARG_MACADDR6_P(0); + macaddr6 *a2 = PG_GETARG_MACADDR6_P(1); + + PG_RETURN_BOOL(macaddr6_cmp_internal(a1, a2) < 0); +} + +Datum +macaddr6_le(PG_FUNCTION_ARGS) +{ + macaddr6 *a1 = PG_GETARG_MACADDR6_P(0); + macaddr6 *a2 = PG_GETARG_MACADDR6_P(1); + + PG_RETURN_BOOL(macaddr6_cmp_internal(a1, a2) <= 0); +} + +Datum +macaddr6_eq(PG_FUNCTION_ARGS) +{ + macaddr6 *a1 = PG_GETARG_MACADDR6_P(0); + macaddr6 *a2 = PG_GETARG_MACADDR6_P(1); + + PG_RETURN_BOOL(macaddr6_cmp_internal(a1, a2) == 0); +} + +Datum +macaddr6_ge(PG_FUNCTION_ARGS) +{ + macaddr6 *a1 = PG_GETARG_MACADDR6_P(0); + macaddr6 *a2 = PG_GETARG_MACADDR6_P(1); + + PG_RETURN_BOOL(macaddr6_cmp_internal(a1, a2) >= 0); +} + +Datum +macaddr6_gt(PG_FUNCTION_ARGS) +{ + macaddr6 *a1 = PG_GETARG_MACADDR6_P(0); + macaddr6 *a2 = PG_GETARG_MACADDR6_P(1); + + PG_RETURN_BOOL(macaddr6_cmp_internal(a1, a2) > 0); +} + +Datum +macaddr6_ne(PG_FUNCTION_ARGS) +{ + macaddr6 *a1 = PG_GETARG_MACADDR6_P(0); + macaddr6 *a2 = PG_GETARG_MACADDR6_P(1); + + PG_RETURN_BOOL(macaddr6_cmp_internal(a1, a2) != 0); +} + +/* + * Support function for hash indexes on macaddr6. + */ +Datum +hashmacaddr6(PG_FUNCTION_ARGS) +{ + macaddr6 *key = PG_GETARG_MACADDR6_P(0); + + return hash_any((unsigned char *) key, sizeof(macaddr6)); +} + +/* + * Arithmetic functions: bitwise NOT, AND, OR. + */ +Datum +macaddr6_not(PG_FUNCTION_ARGS) +{ + macaddr6 *addr = PG_GETARG_MACADDR6_P(0); + macaddr6 *result; + + result = (macaddr6 *) palloc(sizeof(macaddr6)); + result->a = ~addr->a; + result->b = ~addr->b; + result->c = ~addr->c; + result->d = ~addr->d; + result->e = ~addr->e; + result->f = ~addr->f; + PG_RETURN_MACADDR6_P(result); +} + +Datum +macaddr6_and(PG_FUNCTION_ARGS) +{ + macaddr6 *addr1 = PG_GETARG_MACADDR6_P(0); + macaddr6 *addr2 = PG_GETARG_MACADDR6_P(1); + macaddr6 *result; + + result = (macaddr6 *) palloc(sizeof(macaddr6)); + result->a = addr1->a & addr2->a; + result->b = addr1->b & addr2->b; + result->c = addr1->c & addr2->c; + result->d = addr1->d & addr2->d; + result->e = addr1->e & addr2->e; + result->f = addr1->f & addr2->f; + PG_RETURN_MACADDR6_P(result); +} + +Datum +macaddr6_or(PG_FUNCTION_ARGS) +{ + macaddr6 *addr1 = PG_GETARG_MACADDR6_P(0); + macaddr6 *addr2 = PG_GETARG_MACADDR6_P(1); + macaddr6 *result; + + result = (macaddr6 *) palloc(sizeof(macaddr6)); + result->a = addr1->a | addr2->a; + result->b = addr1->b | addr2->b; + result->c = addr1->c | addr2->c; + result->d = addr1->d | addr2->d; + result->e = addr1->e | addr2->e; + result->f = addr1->f | addr2->f; + PG_RETURN_MACADDR6_P(result); +} + +/* + * Truncation function to allow comparing mac manufacturers. + * From suggestion by Alex Pilosov + */ +Datum +macaddr6_trunc(PG_FUNCTION_ARGS) +{ + macaddr6 *addr = PG_GETARG_MACADDR6_P(0); + macaddr6 *result; + + result = (macaddr6 *) palloc(sizeof(macaddr6)); + + result->a = addr->a; + result->b = addr->b; + result->c = addr->c; + result->d = 0; + result->e = 0; + result->f = 0; + + PG_RETURN_MACADDR6_P(result); +} diff --git a/src/backend/utils/adt/network.c b/src/backend/utils/adt/network.c index dbc557e..bde433b 100644 --- a/src/backend/utils/adt/network.c +++ b/src/backend/utils/adt/network.c @@ -924,9 +924,9 @@ convert_network_to_scalar(Datum value, Oid typid) break; } - case MACADDROID: + case MACADDR6OID: { - macaddr *mac = DatumGetMacaddrP(value); + macaddr6 *mac = DatumGetMacaddr6P(value); double res; res = (mac->a << 16) | (mac->b << 8) | (mac->c); @@ -934,6 +934,24 @@ convert_network_to_scalar(Datum value, Oid typid) res += (mac->d << 16) | (mac->e << 8) | (mac->f); return res; } + case MACADDROID: + { + macaddr *mac = DatumGetMacaddrPP(value); + double res; + int size = MACADDR_SIZE(mac); + + res = (MACADDR(mac)->data[0] << 16) | (MACADDR(mac)->data[1] << 8) | (MACADDR(mac)->data[2]); + res *= 256 * 256 * 256; + res += (MACADDR(mac)->data[3] << 16) | (MACADDR(mac)->data[4] << 8) | (MACADDR(mac)->data[5]); + + if (size == 8) + { + res *= 256 * 256; + res += (MACADDR(mac)->data[6] << 8) | (MACADDR(mac)->data[7]); + } + + return res; + } } /* diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index 56943f2..46aa41e 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -3783,6 +3783,7 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue, */ case INETOID: case CIDROID: + case MACADDR6OID: case MACADDROID: *scaledvalue = convert_network_to_scalar(value, valuetypid); *scaledlobound = convert_network_to_scalar(lobound, boundstypid); diff --git a/src/include/catalog/pg_amop.h b/src/include/catalog/pg_amop.h index e4c3515..8b37dca 100644 --- a/src/include/catalog/pg_amop.h +++ b/src/include/catalog/pg_amop.h @@ -363,7 +363,7 @@ DATA(insert ( 1982 1186 1186 4 s 1335 403 0 )); DATA(insert ( 1982 1186 1186 5 s 1334 403 0 )); /* - * btree macaddr + * btree macaddr6 */ DATA(insert ( 1984 829 829 1 s 1222 403 0 )); @@ -373,6 +373,16 @@ DATA(insert ( 1984 829 829 4 s 1225 403 0 )); DATA(insert ( 1984 829 829 5 s 1224 403 0 )); /* + * btree macaddr + */ + +DATA(insert ( 3371 774 774 1 s 3364 403 0 )); +DATA(insert ( 3371 774 774 2 s 3365 403 0 )); +DATA(insert ( 3371 774 774 3 s 3362 403 0 )); +DATA(insert ( 3371 774 774 4 s 3367 403 0 )); +DATA(insert ( 3371 774 774 5 s 3366 403 0 )); + +/* * btree network */ @@ -551,8 +561,10 @@ DATA(insert ( 1977 20 21 1 s 1868 405 0 )); DATA(insert ( 1977 20 23 1 s 416 405 0 )); /* interval_ops */ DATA(insert ( 1983 1186 1186 1 s 1330 405 0 )); -/* macaddr_ops */ +/* macaddr6_ops */ DATA(insert ( 1985 829 829 1 s 1220 405 0 )); +/* macaddr_ops */ +DATA(insert ( 3372 774 774 1 s 3362 405 0 )); /* name_ops */ DATA(insert ( 1987 19 19 1 s 93 405 0 )); /* oid_ops */ @@ -993,12 +1005,18 @@ DATA(insert ( 4073 703 703 2 s 570 3580 0 )); DATA(insert ( 4073 703 703 3 s 566 3580 0 )); DATA(insert ( 4073 703 703 4 s 571 3580 0 )); DATA(insert ( 4073 703 703 5 s 569 3580 0 )); -/* minmax macaddr */ +/* minmax macaddr6 */ DATA(insert ( 4074 829 829 1 s 1222 3580 0 )); DATA(insert ( 4074 829 829 2 s 1223 3580 0 )); DATA(insert ( 4074 829 829 3 s 1220 3580 0 )); DATA(insert ( 4074 829 829 4 s 1225 3580 0 )); DATA(insert ( 4074 829 829 5 s 1224 3580 0 )); +/* minmax macaddr */ +DATA(insert ( 5002 774 774 1 s 3364 3580 0 )); +DATA(insert ( 5002 774 774 2 s 3365 3580 0 )); +DATA(insert ( 5002 774 774 3 s 3362 3580 0 )); +DATA(insert ( 5002 774 774 4 s 3367 3580 0 )); +DATA(insert ( 5002 774 774 5 s 3366 3580 0 )); /* minmax inet */ DATA(insert ( 4075 869 869 1 s 1203 3580 0 )); DATA(insert ( 4075 869 869 2 s 1204 3580 0 )); diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h index f01a5b4..4bbe394 100644 --- a/src/include/catalog/pg_amproc.h +++ b/src/include/catalog/pg_amproc.h @@ -142,6 +142,7 @@ DATA(insert ( 2968 2950 2950 2 3300 )); DATA(insert ( 2994 2249 2249 1 2987 )); DATA(insert ( 3194 2249 2249 1 3187 )); DATA(insert ( 3253 3220 3220 1 3251 )); +DATA(insert ( 3371 774 774 1 3358 )); DATA(insert ( 3522 3500 3500 1 3514 )); DATA(insert ( 3626 3614 3614 1 3622 )); DATA(insert ( 3683 3615 3615 1 3668 )); @@ -182,6 +183,7 @@ DATA(insert ( 2231 1042 1042 1 1080 )); DATA(insert ( 2235 1033 1033 1 329 )); DATA(insert ( 2969 2950 2950 1 2963 )); DATA(insert ( 3254 3220 3220 1 3252 )); +DATA(insert ( 3372 774 774 1 328 )); DATA(insert ( 3523 3500 3500 1 3515 )); DATA(insert ( 3903 3831 3831 1 3902 )); DATA(insert ( 4034 3802 3802 1 4045 )); @@ -409,11 +411,16 @@ DATA(insert ( 4073 703 703 1 3383 )); DATA(insert ( 4073 703 703 2 3384 )); DATA(insert ( 4073 703 703 3 3385 )); DATA(insert ( 4073 703 703 4 3386 )); -/* minmax macaddr */ +/* minmax macaddr6 */ DATA(insert ( 4074 829 829 1 3383 )); DATA(insert ( 4074 829 829 2 3384 )); DATA(insert ( 4074 829 829 3 3385 )); DATA(insert ( 4074 829 829 4 3386 )); +/* minmax macaddr */ +DATA(insert ( 5002 774 774 1 3383 )); +DATA(insert ( 5002 774 774 2 3384 )); +DATA(insert ( 5002 774 774 3 3385 )); +DATA(insert ( 5002 774 774 4 3386 )); /* minmax inet */ DATA(insert ( 4075 869 869 1 3383 )); DATA(insert ( 4075 869 869 2 3384 )); diff --git a/src/include/catalog/pg_cast.h b/src/include/catalog/pg_cast.h index 04d11c0..74b4977 100644 --- a/src/include/catalog/pg_cast.h +++ b/src/include/catalog/pg_cast.h @@ -304,6 +304,11 @@ DATA(insert ( 718 603 1480 e f )); DATA(insert ( 718 604 1544 e f )); /* + * MAC address category + */ +DATA(insert ( 829 774 3373 i f )); + +/* * INET category */ DATA(insert ( 650 869 0 i b )); diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h index ade8da3..a454a41 100644 --- a/src/include/catalog/pg_opclass.h +++ b/src/include/catalog/pg_opclass.h @@ -125,8 +125,10 @@ DATA(insert OID = 3124 ( 403 int8_ops PGNSP PGUID 1976 20 t 0 )); DATA(insert ( 405 int8_ops PGNSP PGUID 1977 20 t 0 )); DATA(insert ( 403 interval_ops PGNSP PGUID 1982 1186 t 0 )); DATA(insert ( 405 interval_ops PGNSP PGUID 1983 1186 t 0 )); -DATA(insert ( 403 macaddr_ops PGNSP PGUID 1984 829 t 0 )); -DATA(insert ( 405 macaddr_ops PGNSP PGUID 1985 829 t 0 )); +DATA(insert ( 403 macaddr6_ops PGNSP PGUID 1984 829 t 0 )); +DATA(insert ( 405 macaddr6_ops PGNSP PGUID 1985 829 t 0 )); +DATA(insert ( 403 macaddr_ops PGNSP PGUID 3371 774 t 0 )); +DATA(insert ( 405 macaddr_ops PGNSP PGUID 3372 774 t 0 )); /* * Here's an ugly little hack to save space in the system catalog indexes. * btree doesn't ordinarily allow a storage type different from input type; @@ -223,7 +225,8 @@ DATA(insert ( 3580 float4_minmax_ops PGNSP PGUID 4070 700 t 700 )); DATA(insert ( 3580 float8_minmax_ops PGNSP PGUID 4070 701 t 701 )); DATA(insert ( 3580 abstime_minmax_ops PGNSP PGUID 4072 702 t 702 )); DATA(insert ( 3580 reltime_minmax_ops PGNSP PGUID 4073 703 t 703 )); -DATA(insert ( 3580 macaddr_minmax_ops PGNSP PGUID 4074 829 t 829 )); +DATA(insert ( 3580 macaddr6_minmax_ops PGNSP PGUID 4074 829 t 829 )); +DATA(insert ( 3580 macaddr_minmax_ops PGNSP PGUID 5002 774 t 774 )); DATA(insert ( 3580 inet_minmax_ops PGNSP PGUID 4075 869 f 869 )); DATA(insert ( 3580 inet_inclusion_ops PGNSP PGUID 4102 869 t 869 )); DATA(insert ( 3580 bpchar_minmax_ops PGNSP PGUID 4076 1042 t 1042 )); diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h index 26fa618..f551079 100644 --- a/src/include/catalog/pg_operator.h +++ b/src/include/catalog/pg_operator.h @@ -1113,25 +1113,46 @@ DESCR("equal"); DATA(insert OID = 1617 ( "#" PGNSP PGUID b f f 628 628 600 1617 0 line_interpt - - )); DESCR("intersection point"); +/* MAC6 type */ +DATA(insert OID = 1220 ( "=" PGNSP PGUID b t t 829 829 16 1220 1221 macaddr6_eq eqsel eqjoinsel )); +DESCR("equal"); +DATA(insert OID = 1221 ( "<>" PGNSP PGUID b f f 829 829 16 1221 1220 macaddr6_ne neqsel neqjoinsel )); +DESCR("not equal"); +DATA(insert OID = 1222 ( "<" PGNSP PGUID b f f 829 829 16 1224 1225 macaddr6_lt scalarltsel scalarltjoinsel )); +DESCR("less than"); +DATA(insert OID = 1223 ( "<=" PGNSP PGUID b f f 829 829 16 1225 1224 macaddr6_le scalarltsel scalarltjoinsel )); +DESCR("less than or equal"); +DATA(insert OID = 1224 ( ">" PGNSP PGUID b f f 829 829 16 1222 1223 macaddr6_gt scalargtsel scalargtjoinsel )); +DESCR("greater than"); +DATA(insert OID = 1225 ( ">=" PGNSP PGUID b f f 829 829 16 1223 1222 macaddr6_ge scalargtsel scalargtjoinsel )); +DESCR("greater than or equal"); + +DATA(insert OID = 3147 ( "~" PGNSP PGUID l f f 0 829 829 0 0 macaddr6_not - - )); +DESCR("bitwise not"); +DATA(insert OID = 3148 ( "&" PGNSP PGUID b f f 829 829 829 0 0 macaddr6_and - - )); +DESCR("bitwise and"); +DATA(insert OID = 3149 ( "|" PGNSP PGUID b f f 829 829 829 0 0 macaddr6_or - - )); +DESCR("bitwise or"); + /* MAC type */ -DATA(insert OID = 1220 ( "=" PGNSP PGUID b t t 829 829 16 1220 1221 macaddr_eq eqsel eqjoinsel )); +DATA(insert OID = 3362 ( "=" PGNSP PGUID b t t 774 774 16 3362 3363 macaddr_eq eqsel eqjoinsel )); DESCR("equal"); -DATA(insert OID = 1221 ( "<>" PGNSP PGUID b f f 829 829 16 1221 1220 macaddr_ne neqsel neqjoinsel )); +DATA(insert OID = 3363 ( "<>" PGNSP PGUID b f f 774 774 16 3363 3362 macaddr_ne neqsel neqjoinsel )); DESCR("not equal"); -DATA(insert OID = 1222 ( "<" PGNSP PGUID b f f 829 829 16 1224 1225 macaddr_lt scalarltsel scalarltjoinsel )); +DATA(insert OID = 3364 ( "<" PGNSP PGUID b f f 774 774 16 3366 3367 macaddr_lt scalarltsel scalarltjoinsel )); DESCR("less than"); -DATA(insert OID = 1223 ( "<=" PGNSP PGUID b f f 829 829 16 1225 1224 macaddr_le scalarltsel scalarltjoinsel )); +DATA(insert OID = 3365 ( "<=" PGNSP PGUID b f f 774 774 16 3367 3366 macaddr_le scalarltsel scalarltjoinsel )); DESCR("less than or equal"); -DATA(insert OID = 1224 ( ">" PGNSP PGUID b f f 829 829 16 1222 1223 macaddr_gt scalargtsel scalargtjoinsel )); +DATA(insert OID = 3366 ( ">" PGNSP PGUID b f f 774 774 16 3364 3365 macaddr_gt scalargtsel scalargtjoinsel )); DESCR("greater than"); -DATA(insert OID = 1225 ( ">=" PGNSP PGUID b f f 829 829 16 1223 1222 macaddr_ge scalargtsel scalargtjoinsel )); +DATA(insert OID = 3367 ( ">=" PGNSP PGUID b f f 774 774 16 3365 3364 macaddr_ge scalargtsel scalargtjoinsel )); DESCR("greater than or equal"); -DATA(insert OID = 3147 ( "~" PGNSP PGUID l f f 0 829 829 0 0 macaddr_not - - )); +DATA(insert OID = 3368 ( "~" PGNSP PGUID l f f 0 774 774 0 0 macaddr_not - - )); DESCR("bitwise not"); -DATA(insert OID = 3148 ( "&" PGNSP PGUID b f f 829 829 829 0 0 macaddr_and - - )); +DATA(insert OID = 3369 ( "&" PGNSP PGUID b f f 774 774 774 0 0 macaddr_and - - )); DESCR("bitwise and"); -DATA(insert OID = 3149 ( "|" PGNSP PGUID b f f 829 829 829 0 0 macaddr_or - - )); +DATA(insert OID = 3370 ( "|" PGNSP PGUID b f f 774 774 774 0 0 macaddr_or - - )); DESCR("bitwise or"); /* INET type (these also support CIDR via implicit cast) */ diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h index 7ba23e5..bc7df09 100644 --- a/src/include/catalog/pg_opfamily.h +++ b/src/include/catalog/pg_opfamily.h @@ -85,8 +85,10 @@ DATA(insert OID = 1976 ( 403 integer_ops PGNSP PGUID )); DATA(insert OID = 1977 ( 405 integer_ops PGNSP PGUID )); DATA(insert OID = 1982 ( 403 interval_ops PGNSP PGUID )); DATA(insert OID = 1983 ( 405 interval_ops PGNSP PGUID )); -DATA(insert OID = 1984 ( 403 macaddr_ops PGNSP PGUID )); -DATA(insert OID = 1985 ( 405 macaddr_ops PGNSP PGUID )); +DATA(insert OID = 1984 ( 403 macaddr6_ops PGNSP PGUID )); +DATA(insert OID = 1985 ( 405 macaddr6_ops PGNSP PGUID )); +DATA(insert OID = 3371 ( 403 macaddr_ops PGNSP PGUID )); +DATA(insert OID = 3372 ( 405 macaddr_ops PGNSP PGUID )); DATA(insert OID = 1986 ( 403 name_ops PGNSP PGUID )); #define NAME_BTREE_FAM_OID 1986 DATA(insert OID = 1987 ( 405 name_ops PGNSP PGUID )); @@ -170,7 +172,8 @@ DATA(insert OID = 4069 ( 3580 tid_minmax_ops PGNSP PGUID )); DATA(insert OID = 4070 ( 3580 float_minmax_ops PGNSP PGUID )); DATA(insert OID = 4072 ( 3580 abstime_minmax_ops PGNSP PGUID )); DATA(insert OID = 4073 ( 3580 reltime_minmax_ops PGNSP PGUID )); -DATA(insert OID = 4074 ( 3580 macaddr_minmax_ops PGNSP PGUID )); +DATA(insert OID = 4074 ( 3580 macaddr6_minmax_ops PGNSP PGUID )); +DATA(insert OID = 5002 ( 3580 macaddr_minmax_ops PGNSP PGUID )); DATA(insert OID = 4075 ( 3580 network_minmax_ops PGNSP PGUID )); DATA(insert OID = 4102 ( 3580 network_inclusion_ops PGNSP PGUID )); DATA(insert OID = 4076 ( 3580 bpchar_minmax_ops PGNSP PGUID )); diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h index 17ec71d..99e97f1 100644 --- a/src/include/catalog/pg_proc.h +++ b/src/include/catalog/pg_proc.h @@ -686,12 +686,14 @@ DATA(insert OID = 457 ( hashoidvector PGNSP PGUID 12 1 0 0 0 f f f f t f i s DESCR("hash"); DATA(insert OID = 329 ( hash_aclitem PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 23 "1033" _null_ _null_ _null_ _null_ _null_ hash_aclitem _null_ _null_ _null_ )); DESCR("hash"); -DATA(insert OID = 399 ( hashmacaddr PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 23 "829" _null_ _null_ _null_ _null_ _null_ hashmacaddr _null_ _null_ _null_ )); +DATA(insert OID = 399 ( hashmacaddr6 PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 23 "829" _null_ _null_ _null_ _null_ _null_ hashmacaddr6 _null_ _null_ _null_ )); DESCR("hash"); DATA(insert OID = 422 ( hashinet PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 23 "869" _null_ _null_ _null_ _null_ _null_ hashinet _null_ _null_ _null_ )); DESCR("hash"); DATA(insert OID = 432 ( hash_numeric PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 23 "1700" _null_ _null_ _null_ _null_ _null_ hash_numeric _null_ _null_ _null_ )); DESCR("hash"); +DATA(insert OID = 328 ( hashmacaddr PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 23 "774" _null_ _null_ _null_ _null_ _null_ hashmacaddr _null_ _null_ _null_ )); +DESCR("hash"); DATA(insert OID = 438 ( num_nulls PGNSP PGUID 12 1 0 2276 0 f f f f f f i s 1 0 23 "2276" "{2276}" "{v}" _null_ _null_ _null_ pg_num_nulls _null_ _null_ _null_ )); DESCR("count the number of NULL arguments"); @@ -2090,26 +2092,49 @@ DESCR("get bit"); DATA(insert OID = 3033 ( set_bit PGNSP PGUID 12 1 0 0 0 f f f f t f i s 3 0 1560 "1560 23 23" _null_ _null_ _null_ _null_ _null_ bitsetbit _null_ _null_ _null_ )); DESCR("set bit"); -/* for mac type support */ -DATA(insert OID = 436 ( macaddr_in PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 829 "2275" _null_ _null_ _null_ _null_ _null_ macaddr_in _null_ _null_ _null_ )); +/* for macaddr6 type support */ +DATA(insert OID = 436 ( macaddr6_in PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 829 "2275" _null_ _null_ _null_ _null_ _null_ macaddr6_in _null_ _null_ _null_ )); DESCR("I/O"); -DATA(insert OID = 437 ( macaddr_out PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 2275 "829" _null_ _null_ _null_ _null_ _null_ macaddr_out _null_ _null_ _null_ )); +DATA(insert OID = 437 ( macaddr6_out PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 2275 "829" _null_ _null_ _null_ _null_ _null_ macaddr6_out _null_ _null_ _null_ )); DESCR("I/O"); -DATA(insert OID = 753 ( trunc PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 829 "829" _null_ _null_ _null_ _null_ _null_ macaddr_trunc _null_ _null_ _null_ )); -DESCR("MAC manufacturer fields"); +DATA(insert OID = 753 ( trunc PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 829 "829" _null_ _null_ _null_ _null_ _null_ macaddr6_trunc _null_ _null_ _null_ )); +DESCR("MACADDR6 manufacturer fields"); -DATA(insert OID = 830 ( macaddr_eq PGNSP PGUID 12 1 0 0 0 f f f t t f i s 2 0 16 "829 829" _null_ _null_ _null_ _null_ _null_ macaddr_eq _null_ _null_ _null_ )); -DATA(insert OID = 831 ( macaddr_lt PGNSP PGUID 12 1 0 0 0 f f f t t f i s 2 0 16 "829 829" _null_ _null_ _null_ _null_ _null_ macaddr_lt _null_ _null_ _null_ )); -DATA(insert OID = 832 ( macaddr_le PGNSP PGUID 12 1 0 0 0 f f f t t f i s 2 0 16 "829 829" _null_ _null_ _null_ _null_ _null_ macaddr_le _null_ _null_ _null_ )); -DATA(insert OID = 833 ( macaddr_gt PGNSP PGUID 12 1 0 0 0 f f f t t f i s 2 0 16 "829 829" _null_ _null_ _null_ _null_ _null_ macaddr_gt _null_ _null_ _null_ )); -DATA(insert OID = 834 ( macaddr_ge PGNSP PGUID 12 1 0 0 0 f f f t t f i s 2 0 16 "829 829" _null_ _null_ _null_ _null_ _null_ macaddr_ge _null_ _null_ _null_ )); -DATA(insert OID = 835 ( macaddr_ne PGNSP PGUID 12 1 0 0 0 f f f t t f i s 2 0 16 "829 829" _null_ _null_ _null_ _null_ _null_ macaddr_ne _null_ _null_ _null_ )); -DATA(insert OID = 836 ( macaddr_cmp PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 23 "829 829" _null_ _null_ _null_ _null_ _null_ macaddr_cmp _null_ _null_ _null_ )); +DATA(insert OID = 830 ( macaddr6_eq PGNSP PGUID 12 1 0 0 0 f f f t t f i s 2 0 16 "829 829" _null_ _null_ _null_ _null_ _null_ macaddr6_eq _null_ _null_ _null_ )); +DATA(insert OID = 831 ( macaddr6_lt PGNSP PGUID 12 1 0 0 0 f f f t t f i s 2 0 16 "829 829" _null_ _null_ _null_ _null_ _null_ macaddr6_lt _null_ _null_ _null_ )); +DATA(insert OID = 832 ( macaddr6_le PGNSP PGUID 12 1 0 0 0 f f f t t f i s 2 0 16 "829 829" _null_ _null_ _null_ _null_ _null_ macaddr6_le _null_ _null_ _null_ )); +DATA(insert OID = 833 ( macaddr6_gt PGNSP PGUID 12 1 0 0 0 f f f t t f i s 2 0 16 "829 829" _null_ _null_ _null_ _null_ _null_ macaddr6_gt _null_ _null_ _null_ )); +DATA(insert OID = 834 ( macaddr6_ge PGNSP PGUID 12 1 0 0 0 f f f t t f i s 2 0 16 "829 829" _null_ _null_ _null_ _null_ _null_ macaddr6_ge _null_ _null_ _null_ )); +DATA(insert OID = 835 ( macaddr6_ne PGNSP PGUID 12 1 0 0 0 f f f t t f i s 2 0 16 "829 829" _null_ _null_ _null_ _null_ _null_ macaddr6_ne _null_ _null_ _null_ )); +DATA(insert OID = 836 ( macaddr6_cmp PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 23 "829 829" _null_ _null_ _null_ _null_ _null_ macaddr6_cmp _null_ _null_ _null_ )); DESCR("less-equal-greater"); -DATA(insert OID = 3144 ( macaddr_not PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 829 "829" _null_ _null_ _null_ _null_ _null_ macaddr_not _null_ _null_ _null_ )); -DATA(insert OID = 3145 ( macaddr_and PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 829 "829 829" _null_ _null_ _null_ _null_ _null_ macaddr_and _null_ _null_ _null_ )); -DATA(insert OID = 3146 ( macaddr_or PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 829 "829 829" _null_ _null_ _null_ _null_ _null_ macaddr_or _null_ _null_ _null_ )); +DATA(insert OID = 3144 ( macaddr6_not PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 829 "829" _null_ _null_ _null_ _null_ _null_ macaddr6_not _null_ _null_ _null_ )); +DATA(insert OID = 3145 ( macaddr6_and PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 829 "829 829" _null_ _null_ _null_ _null_ _null_ macaddr6_and _null_ _null_ _null_ )); +DATA(insert OID = 3146 ( macaddr6_or PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 829 "829 829" _null_ _null_ _null_ _null_ _null_ macaddr6_or _null_ _null_ _null_ )); + +/* for macaddr type support */ +DATA(insert OID = 3349 ( macaddr_in PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 774 "2275" _null_ _null_ _null_ _null_ _null_ macaddr_in _null_ _null_ _null_ )); +DESCR("I/O"); +DATA(insert OID = 3350 ( macaddr_out PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 2275 "774" _null_ _null_ _null_ _null_ _null_ macaddr_out _null_ _null_ _null_ )); +DESCR("I/O"); + +DATA(insert OID = 3351 ( trunc PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 774 "774" _null_ _null_ _null_ _null_ _null_ macaddr_trunc _null_ _null_ _null_ )); +DESCR("MACADDR manufacturer fields"); + +DATA(insert OID = 3352 ( macaddr_eq PGNSP PGUID 12 1 0 0 0 f f f t t f i s 2 0 16 "774 774" _null_ _null_ _null_ _null_ _null_ macaddr_eq _null_ _null_ _null_ )); +DATA(insert OID = 3353 ( macaddr_lt PGNSP PGUID 12 1 0 0 0 f f f t t f i s 2 0 16 "774 774" _null_ _null_ _null_ _null_ _null_ macaddr_lt _null_ _null_ _null_ )); +DATA(insert OID = 3354 ( macaddr_le PGNSP PGUID 12 1 0 0 0 f f f t t f i s 2 0 16 "774 774" _null_ _null_ _null_ _null_ _null_ macaddr_le _null_ _null_ _null_ )); +DATA(insert OID = 3355 ( macaddr_gt PGNSP PGUID 12 1 0 0 0 f f f t t f i s 2 0 16 "774 774" _null_ _null_ _null_ _null_ _null_ macaddr_gt _null_ _null_ _null_ )); +DATA(insert OID = 3356 ( macaddr_ge PGNSP PGUID 12 1 0 0 0 f f f t t f i s 2 0 16 "774 774" _null_ _null_ _null_ _null_ _null_ macaddr_ge _null_ _null_ _null_ )); +DATA(insert OID = 3357 ( macaddr_ne PGNSP PGUID 12 1 0 0 0 f f f t t f i s 2 0 16 "774 774" _null_ _null_ _null_ _null_ _null_ macaddr_ne _null_ _null_ _null_ )); +DATA(insert OID = 3358 ( macaddr_cmp PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 23 "774 774" _null_ _null_ _null_ _null_ _null_ macaddr_cmp _null_ _null_ _null_ )); +DESCR("less-equal-greater"); +DATA(insert OID = 3359 ( macaddr_not PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 774 "774" _null_ _null_ _null_ _null_ _null_ macaddr_not _null_ _null_ _null_ )); +DATA(insert OID = 3360 ( macaddr_and PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 774 "774 774" _null_ _null_ _null_ _null_ _null_ macaddr_and _null_ _null_ _null_ )); +DATA(insert OID = 3361 ( macaddr_or PGNSP PGUID 12 1 0 0 0 f f f f t f i s 2 0 774 "774 774" _null_ _null_ _null_ _null_ _null_ macaddr_or _null_ _null_ _null_ )); +DATA(insert OID = 3373 ( macaddr PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 774 "829" _null_ _null_ _null_ _null_ _null_ mac6tomac _null_ _null_ _null_ )); +DESCR("convert macaddr6 to macaddr"); /* for inet type support */ DATA(insert OID = 910 ( inet_in PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 869 "2275" _null_ _null_ _null_ _null_ _null_ inet_in _null_ _null_ _null_ )); @@ -4016,9 +4041,9 @@ DATA(insert OID = 2492 ( cash_recv PGNSP PGUID 12 1 0 0 0 f f f f t f i s DESCR("I/O"); DATA(insert OID = 2493 ( cash_send PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 17 "790" _null_ _null_ _null_ _null_ _null_ cash_send _null_ _null_ _null_ )); DESCR("I/O"); -DATA(insert OID = 2494 ( macaddr_recv PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 829 "2281" _null_ _null_ _null_ _null_ _null_ macaddr_recv _null_ _null_ _null_ )); +DATA(insert OID = 2494 ( macaddr6_recv PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 829 "2281" _null_ _null_ _null_ _null_ _null_ macaddr6_recv _null_ _null_ _null_ )); DESCR("I/O"); -DATA(insert OID = 2495 ( macaddr_send PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 17 "829" _null_ _null_ _null_ _null_ _null_ macaddr_send _null_ _null_ _null_ )); +DATA(insert OID = 2495 ( macaddr6_send PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 17 "829" _null_ _null_ _null_ _null_ _null_ macaddr6_send _null_ _null_ _null_ )); DESCR("I/O"); DATA(insert OID = 2496 ( inet_recv PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 869 "2281" _null_ _null_ _null_ _null_ _null_ inet_recv _null_ _null_ _null_ )); DESCR("I/O"); @@ -4040,6 +4065,10 @@ DATA(insert OID = 3120 ( void_recv PGNSP PGUID 12 1 0 0 0 f f f f t f i s DESCR("I/O"); DATA(insert OID = 3121 ( void_send PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 17 "2278" _null_ _null_ _null_ _null_ _null_ void_send _null_ _null_ _null_ )); DESCR("I/O"); +DATA(insert OID = 3344 ( macaddr_recv PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 774 "2281" _null_ _null_ _null_ _null_ _null_ macaddr_recv _null_ _null_ _null_ )); +DESCR("I/O"); +DATA(insert OID = 3345 ( macaddr_send PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 17 "774" _null_ _null_ _null_ _null_ _null_ macaddr_send _null_ _null_ _null_ )); +DESCR("I/O"); /* System-view support functions with pretty-print option */ DATA(insert OID = 2504 ( pg_get_ruledef PGNSP PGUID 12 1 0 0 0 f f f f t f s s 2 0 25 "26 16" _null_ _null_ _null_ _null_ _null_ pg_get_ruledef_ext _null_ _null_ _null_ )); diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h index 162239c..5faadaa 100644 --- a/src/include/catalog/pg_type.h +++ b/src/include/catalog/pg_type.h @@ -432,18 +432,22 @@ DESCR("monetary amounts, $d,ddd.cc"); DATA(insert OID = 791 ( _money PGNSP PGUID -1 f b A f t \054 0 790 0 array_in array_out array_recv array_send - - array_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ )); /* OIDS 800 - 899 */ -DATA(insert OID = 829 ( macaddr PGNSP PGUID 6 f b U f t \054 0 0 1040 macaddr_in macaddr_out macaddr_recv macaddr_send - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 829 ( macaddr6 PGNSP PGUID 6 f b U f t \054 0 0 1040 macaddr6_in macaddr6_out macaddr6_recv macaddr6_send - - - i p f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("XX:XX:XX:XX:XX:XX, MAC address"); -#define MACADDROID 829 +#define MACADDR6OID 829 DATA(insert OID = 869 ( inet PGNSP PGUID -1 f b I t t \054 0 0 1041 inet_in inet_out inet_recv inet_send - - - i m f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("IP address/netmask, host address, netmask optional"); #define INETOID 869 DATA(insert OID = 650 ( cidr PGNSP PGUID -1 f b I f t \054 0 0 651 cidr_in cidr_out cidr_recv cidr_send - - - i m f 0 -1 0 0 _null_ _null_ _null_ )); DESCR("network IP address/netmask, network address"); #define CIDROID 650 +DATA(insert OID = 774 ( macaddr PGNSP PGUID -1 f b U f t \054 0 0 775 macaddr_in macaddr_out macaddr_recv macaddr_send - - - i m f 0 -1 0 0 _null_ _null_ _null_ )); +DESCR("XX:XX:XX:XX:XX:XX:XX:XX, MAC address"); +#define MACADDROID 972 /* OIDS 900 - 999 */ + /* OIDS 1000 - 1099 */ DATA(insert OID = 1000 ( _bool PGNSP PGUID -1 f b A f t \054 0 16 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); DATA(insert OID = 1001 ( _bytea PGNSP PGUID -1 f b A f t \054 0 17 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); @@ -481,7 +485,8 @@ DATA(insert OID = 1033 ( aclitem PGNSP PGUID 12 f b U f t \054 0 0 1034 aclite DESCR("access control list"); #define ACLITEMOID 1033 DATA(insert OID = 1034 ( _aclitem PGNSP PGUID -1 f b A f t \054 0 1033 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); -DATA(insert OID = 1040 ( _macaddr PGNSP PGUID -1 f b A f t \054 0 829 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 1040 ( _macaddr6 PGNSP PGUID -1 f b A f t \054 0 829 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); +DATA(insert OID = 775 ( _macaddr PGNSP PGUID -1 f b A f t \054 0 774 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); DATA(insert OID = 1041 ( _inet PGNSP PGUID -1 f b A f t \054 0 869 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); DATA(insert OID = 651 ( _cidr PGNSP PGUID -1 f b A f t \054 0 650 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); DATA(insert OID = 1263 ( _cstring PGNSP PGUID -1 f b A f t \054 0 2275 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ )); diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h index 90f5132..39849c3 100644 --- a/src/include/utils/builtins.h +++ b/src/include/utils/builtins.h @@ -1020,6 +1020,25 @@ extern Datum macaddr_and(PG_FUNCTION_ARGS); extern Datum macaddr_or(PG_FUNCTION_ARGS); extern Datum macaddr_trunc(PG_FUNCTION_ARGS); extern Datum hashmacaddr(PG_FUNCTION_ARGS); +extern Datum mac6tomac(PG_FUNCTION_ARGS); + +/* mac6.c */ +extern Datum macaddr6_in(PG_FUNCTION_ARGS); +extern Datum macaddr6_out(PG_FUNCTION_ARGS); +extern Datum macaddr6_recv(PG_FUNCTION_ARGS); +extern Datum macaddr6_send(PG_FUNCTION_ARGS); +extern Datum macaddr6_cmp(PG_FUNCTION_ARGS); +extern Datum macaddr6_lt(PG_FUNCTION_ARGS); +extern Datum macaddr6_le(PG_FUNCTION_ARGS); +extern Datum macaddr6_eq(PG_FUNCTION_ARGS); +extern Datum macaddr6_ge(PG_FUNCTION_ARGS); +extern Datum macaddr6_gt(PG_FUNCTION_ARGS); +extern Datum macaddr6_ne(PG_FUNCTION_ARGS); +extern Datum macaddr6_not(PG_FUNCTION_ARGS); +extern Datum macaddr6_and(PG_FUNCTION_ARGS); +extern Datum macaddr6_or(PG_FUNCTION_ARGS); +extern Datum macaddr6_trunc(PG_FUNCTION_ARGS); +extern Datum hashmacaddr6(PG_FUNCTION_ARGS); /* numeric.c */ extern Datum numeric_in(PG_FUNCTION_ARGS); diff --git a/src/include/utils/inet.h b/src/include/utils/inet.h index 9fd954d..b203e51 100644 --- a/src/include/utils/inet.h +++ b/src/include/utils/inet.h @@ -91,7 +91,7 @@ typedef struct /* * This is the internal storage format for MAC addresses: */ -typedef struct macaddr +typedef struct macaddr6 { unsigned char a; unsigned char b; @@ -99,6 +99,20 @@ typedef struct macaddr unsigned char d; unsigned char e; unsigned char f; +} macaddr6; + +typedef struct mac_struct +{ + unsigned char data[8]; /* Max storage of 8 byte MAC address */ +}mac_struct; + +/* + * This is the internal storage format for MAC addresses (EUI-48 & EUI-64): + */ +typedef struct macaddr +{ + char vl_len_[4]; /* Do not touch this field directly! */ + mac_struct addr; } macaddr; /* @@ -110,12 +124,26 @@ typedef struct macaddr #define PG_GETARG_INET_P(n) DatumGetInetP(PG_GETARG_DATUM(n)) #define PG_GETARG_INET_PP(n) DatumGetInetPP(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)) + +/* macaddr6 is a fixed-length pass-by-reference datatype */ +#define DatumGetMacaddr6P(X) ((macaddr6 *) DatumGetPointer(X)) +#define Macaddr6PGetDatum(X) PointerGetDatum(X) +#define PG_GETARG_MACADDR6_P(n) DatumGetMacaddr6P(PG_GETARG_DATUM(n)) +#define PG_RETURN_MACADDR6_P(x) return Macaddr6PGetDatum(x) + +/* macaddr is a variable length datatype */ +#define DatumGetMacaddrP(X) ((macaddr *) PG_DETOAST_DATUM(X)) +#define DatumGetMacaddrPP(X) ((macaddr *) PG_DETOAST_DATUM_PACKED(X)) #define MacaddrPGetDatum(X) PointerGetDatum(X) #define PG_GETARG_MACADDR_P(n) DatumGetMacaddrP(PG_GETARG_DATUM(n)) +#define PG_GETARG_MACADDR_PP(n) DatumGetMacaddrPP(PG_GETARG_DATUM(n)) #define PG_RETURN_MACADDR_P(x) return MacaddrPGetDatum(x) +/* macaddr supported macros */ +#define SET_MACADDR_VARSIZE(dst, size) SET_VARSIZE((dst), VARHDRSZ + (size)) +#define MACADDR(ptr) ((mac_struct *)VARDATA_ANY(ptr)) +#define MACADDR_SIZE(ptr) (VARSIZE_ANY_EXHDR(ptr)) + /* * Support functions in network.c */ diff --git a/src/test/regress/expected/macaddr.out b/src/test/regress/expected/macaddr.out index e84ff5f..63ad959 100644 --- a/src/test/regress/expected/macaddr.out +++ b/src/test/regress/expected/macaddr.out @@ -22,9 +22,15 @@ INSERT INTO macaddr_data VALUES (11, '08:00:2b:01:02:02'); INSERT INTO macaddr_data VALUES (12, '08:00:2a:01:02:03'); INSERT INTO macaddr_data VALUES (13, '08:00:2c:01:02:03'); INSERT INTO macaddr_data VALUES (14, '08:00:2a:01:02:04'); +INSERT INTO macaddr_data VALUES (15, '08:00:2b:01:02:03:04:05'); +INSERT INTO macaddr_data VALUES (16, '08-00-2b-01-02-03-04-05'); +INSERT INTO macaddr_data VALUES (17, '08002b:0102030405'); +INSERT INTO macaddr_data VALUES (18, '08002b-0102030405'); +INSERT INTO macaddr_data VALUES (19, '0800.2b01.0203.0405'); +INSERT INTO macaddr_data VALUES (20, '08002b0102030405'); SELECT * FROM macaddr_data; - a | b -----+------------------- + a | b +----+------------------------- 1 | 08:00:2b:01:02:03 2 | 08:00:2b:01:02:03 3 | 08:00:2b:01:02:03 @@ -37,27 +43,39 @@ SELECT * FROM macaddr_data; 12 | 08:00:2a:01:02:03 13 | 08:00:2c:01:02:03 14 | 08:00:2a:01:02:04 -(12 rows) + 15 | 08:00:2b:01:02:03:04:05 + 16 | 08:00:2b:01:02:03:04:05 + 17 | 08:00:2b:01:02:03:04:05 + 18 | 08:00:2b:01:02:03:04:05 + 19 | 08:00:2b:01:02:03:04:05 + 20 | 08:00:2b:01:02:03:04:05 +(18 rows) CREATE INDEX macaddr_data_btree ON macaddr_data USING btree (b); CREATE INDEX macaddr_data_hash ON macaddr_data USING hash (b); WARNING: hash indexes are not WAL-logged and their use is discouraged SELECT a, b, trunc(b) FROM macaddr_data ORDER BY 2, 1; - a | b | trunc -----+-------------------+------------------- - 12 | 08:00:2a:01:02:03 | 08:00:2a:00:00:00 - 14 | 08:00:2a:01:02:04 | 08:00:2a:00:00:00 - 11 | 08:00:2b:01:02:02 | 08:00:2b:00:00:00 - 1 | 08:00:2b:01:02:03 | 08:00:2b:00:00:00 - 2 | 08:00:2b:01:02:03 | 08:00:2b:00:00:00 - 3 | 08:00:2b:01:02:03 | 08:00:2b:00:00:00 - 4 | 08:00:2b:01:02:03 | 08:00:2b:00:00:00 - 5 | 08:00:2b:01:02:03 | 08:00:2b:00:00:00 - 6 | 08:00:2b:01:02:03 | 08:00:2b:00:00:00 - 7 | 08:00:2b:01:02:03 | 08:00:2b:00:00:00 - 10 | 08:00:2b:01:02:04 | 08:00:2b:00:00:00 - 13 | 08:00:2c:01:02:03 | 08:00:2c:00:00:00 -(12 rows) + a | b | trunc +----+-------------------------+------------------------- + 12 | 08:00:2a:01:02:03 | 08:00:2a:00:00:00 + 14 | 08:00:2a:01:02:04 | 08:00:2a:00:00:00 + 11 | 08:00:2b:01:02:02 | 08:00:2b:00:00:00 + 1 | 08:00:2b:01:02:03 | 08:00:2b:00:00:00 + 2 | 08:00:2b:01:02:03 | 08:00:2b:00:00:00 + 3 | 08:00:2b:01:02:03 | 08:00:2b:00:00:00 + 4 | 08:00:2b:01:02:03 | 08:00:2b:00:00:00 + 5 | 08:00:2b:01:02:03 | 08:00:2b:00:00:00 + 6 | 08:00:2b:01:02:03 | 08:00:2b:00:00:00 + 7 | 08:00:2b:01:02:03 | 08:00:2b:00:00:00 + 15 | 08:00:2b:01:02:03:04:05 | 08:00:2b:00:00:00:00:00 + 16 | 08:00:2b:01:02:03:04:05 | 08:00:2b:00:00:00:00:00 + 17 | 08:00:2b:01:02:03:04:05 | 08:00:2b:00:00:00:00:00 + 18 | 08:00:2b:01:02:03:04:05 | 08:00:2b:00:00:00:00:00 + 19 | 08:00:2b:01:02:03:04:05 | 08:00:2b:00:00:00:00:00 + 20 | 08:00:2b:01:02:03:04:05 | 08:00:2b:00:00:00:00:00 + 10 | 08:00:2b:01:02:04 | 08:00:2b:00:00:00 + 13 | 08:00:2c:01:02:03 | 08:00:2c:00:00:00 +(18 rows) SELECT b < '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1; -- true ?column? @@ -107,9 +125,57 @@ SELECT b <> '08:00:2b:01:02:03' FROM macaddr_data WHERE a = 1; -- false f (1 row) +SELECT b < '08:00:2b:01:02:03:04:06' FROM macaddr_data WHERE a = 15; -- true + ?column? +---------- + t +(1 row) + +SELECT b > '08:00:2b:01:02:03:04:06' FROM macaddr_data WHERE a = 15; -- false + ?column? +---------- + f +(1 row) + +SELECT b > '08:00:2b:01:02:03:04:05' FROM macaddr_data WHERE a = 15; -- false + ?column? +---------- + f +(1 row) + +SELECT b <= '08:00:2b:01:02:03:04:06' FROM macaddr_data WHERE a = 15; -- true + ?column? +---------- + t +(1 row) + +SELECT b >= '08:00:2b:01:02:03:04:06' FROM macaddr_data WHERE a = 15; -- false + ?column? +---------- + f +(1 row) + +SELECT b = '08:00:2b:01:02:03:04:05' FROM macaddr_data WHERE a = 15; -- true + ?column? +---------- + t +(1 row) + +SELECT b <> '08:00:2b:01:02:03:04:06' FROM macaddr_data WHERE a = 15; -- true + ?column? +---------- + t +(1 row) + +SELECT b <> '08:00:2b:01:02:03:04:05' FROM macaddr_data WHERE a = 15; -- false + ?column? +---------- + f +(1 row) + SELECT ~b FROM macaddr_data; - ?column? -------------------- + ?column? +------------------------- f7:ff:d4:fe:fd:fc f7:ff:d4:fe:fd:fc f7:ff:d4:fe:fd:fc @@ -122,11 +188,17 @@ SELECT ~b FROM macaddr_data; f7:ff:d5:fe:fd:fc f7:ff:d3:fe:fd:fc f7:ff:d5:fe:fd:fb -(12 rows) + f7:ff:d4:fe:fd:fc:fb:fa + f7:ff:d4:fe:fd:fc:fb:fa + f7:ff:d4:fe:fd:fc:fb:fa + f7:ff:d4:fe:fd:fc:fb:fa + f7:ff:d4:fe:fd:fc:fb:fa + f7:ff:d4:fe:fd:fc:fb:fa +(18 rows) SELECT b & '00:00:00:ff:ff:ff' FROM macaddr_data; - ?column? -------------------- + ?column? +------------------------- 00:00:00:01:02:03 00:00:00:01:02:03 00:00:00:01:02:03 @@ -139,11 +211,17 @@ SELECT b & '00:00:00:ff:ff:ff' FROM macaddr_data; 00:00:00:01:02:03 00:00:00:01:02:03 00:00:00:01:02:04 -(12 rows) + 00:00:00:01:02:03:00:00 + 00:00:00:01:02:03:00:00 + 00:00:00:01:02:03:00:00 + 00:00:00:01:02:03:00:00 + 00:00:00:01:02:03:00:00 + 00:00:00:01:02:03:00:00 +(18 rows) SELECT b | '01:02:03:04:05:06' FROM macaddr_data; - ?column? -------------------- + ?column? +------------------------- 09:02:2b:05:07:07 09:02:2b:05:07:07 09:02:2b:05:07:07 @@ -156,6 +234,12 @@ SELECT b | '01:02:03:04:05:06' FROM macaddr_data; 09:02:2b:05:07:07 09:02:2f:05:07:07 09:02:2b:05:07:06 -(12 rows) + 09:02:2b:05:07:07:04:05 + 09:02:2b:05:07:07:04:05 + 09:02:2b:05:07:07:04:05 + 09:02:2b:05:07:07:04:05 + 09:02:2b:05:07:07:04:05 + 09:02:2b:05:07:07:04:05 +(18 rows) DROP TABLE macaddr_data; diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out index 0bcec13..16e79a8 100644 --- a/src/test/regress/expected/opr_sanity.out +++ b/src/test/regress/expected/opr_sanity.out @@ -561,12 +561,12 @@ tintervallt(tinterval,tinterval) tintervalgt(tinterval,tinterval) tintervalle(tinterval,tinterval) tintervalge(tinterval,tinterval) -macaddr_eq(macaddr,macaddr) -macaddr_lt(macaddr,macaddr) -macaddr_le(macaddr,macaddr) -macaddr_gt(macaddr,macaddr) -macaddr_ge(macaddr,macaddr) -macaddr_ne(macaddr,macaddr) +macaddr6_eq(macaddr6,macaddr6) +macaddr6_lt(macaddr6,macaddr6) +macaddr6_le(macaddr6,macaddr6) +macaddr6_gt(macaddr6,macaddr6) +macaddr6_ge(macaddr6,macaddr6) +macaddr6_ne(macaddr6,macaddr6) int48eq(integer,bigint) int48ne(integer,bigint) int48lt(integer,bigint) @@ -685,6 +685,12 @@ uuid_gt(uuid,uuid) uuid_ne(uuid,uuid) xidneq(xid,xid) xidneqint4(xid,integer) +macaddr_eq(macaddr,macaddr) +macaddr_lt(macaddr,macaddr) +macaddr_le(macaddr,macaddr) +macaddr_gt(macaddr,macaddr) +macaddr_ge(macaddr,macaddr) +macaddr_ne(macaddr,macaddr) -- restore normal output mode \a\t -- List of functions used by libpq's fe-lobj.c diff --git a/src/test/regress/sql/macaddr.sql b/src/test/regress/sql/macaddr.sql index 7bad8f5..173c978 100644 --- a/src/test/regress/sql/macaddr.sql +++ b/src/test/regress/sql/macaddr.sql @@ -20,6 +20,14 @@ INSERT INTO macaddr_data VALUES (12, '08:00:2a:01:02:03'); INSERT INTO macaddr_data VALUES (13, '08:00:2c:01:02:03'); INSERT INTO macaddr_data VALUES (14, '08:00:2a:01:02:04'); +INSERT INTO macaddr_data VALUES (15, '08:00:2b:01:02:03:04:05'); +INSERT INTO macaddr_data VALUES (16, '08-00-2b-01-02-03-04-05'); +INSERT INTO macaddr_data VALUES (17, '08002b:0102030405'); +INSERT INTO macaddr_data VALUES (18, '08002b-0102030405'); +INSERT INTO macaddr_data VALUES (19, '0800.2b01.0203.0405'); +INSERT INTO macaddr_data VALUES (20, '08002b0102030405'); + + SELECT * FROM macaddr_data; CREATE INDEX macaddr_data_btree ON macaddr_data USING btree (b); @@ -36,6 +44,15 @@ SELECT b = '08:00:2b:01:02:03' FROM macaddr_data WHERE a = 1; -- true SELECT b <> '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1; -- true SELECT b <> '08:00:2b:01:02:03' FROM macaddr_data WHERE a = 1; -- false +SELECT b < '08:00:2b:01:02:03:04:06' FROM macaddr_data WHERE a = 15; -- true +SELECT b > '08:00:2b:01:02:03:04:06' FROM macaddr_data WHERE a = 15; -- false +SELECT b > '08:00:2b:01:02:03:04:05' FROM macaddr_data WHERE a = 15; -- false +SELECT b <= '08:00:2b:01:02:03:04:06' FROM macaddr_data WHERE a = 15; -- true +SELECT b >= '08:00:2b:01:02:03:04:06' FROM macaddr_data WHERE a = 15; -- false +SELECT b = '08:00:2b:01:02:03:04:05' FROM macaddr_data WHERE a = 15; -- true +SELECT b <> '08:00:2b:01:02:03:04:06' FROM macaddr_data WHERE a = 15; -- true +SELECT b <> '08:00:2b:01:02:03:04:05' FROM macaddr_data WHERE a = 15; -- false + SELECT ~b FROM macaddr_data; SELECT b & '00:00:00:ff:ff:ff' FROM macaddr_data; SELECT b | '01:02:03:04:05:06' FROM macaddr_data;