macaddr64_poc.patch
application/octet-stream
Filename: macaddr64_poc.patch
Type: application/octet-stream
Part: 0
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/utils/adt/mac64.c | 353 | 0 |
| src/backend/utils/adt/Makefile | 1 | 1 |
| src/include/catalog/pg_proc.h | 28 | 0 |
| src/include/catalog/pg_type.h | 5 | 0 |
| src/include/utils/builtins.h | 18 | 0 |
| src/include/utils/inet.h | 20 | 0 |
diff --git a/src/backend/utils/adt/Makefile b/src/backend/utils/adt/Makefile
index 0f51275..70f7368 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 mac.o mac64.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/mac64.c b/src/backend/utils/adt/mac64.c
new file mode 100644
index 0000000..b11b6eb
--- /dev/null
+++ b/src/backend/utils/adt/mac64.c
@@ -0,0 +1,353 @@
+/*
+ * PostgreSQL type definitions for 64 bit MAC addresses (EUI-64).
+ *
+ * src/backend/utils/adt/mac64.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<<24)|((addr)->b<<16)|((addr)->c<<8)|((addr)->d)))
+
+#define lobits(addr) \
+ ((unsigned long)(((addr)->e<<24)|((addr)->f<<16)|((addr)->g<<8)|((addr)->h)))
+
+/*
+ * MAC address (EUI-64) reader. Accepts several common notations.
+ */
+
+Datum
+macaddr64_in(PG_FUNCTION_ARGS)
+{
+ char *str = PG_GETARG_CSTRING(0);
+ macaddr64 *result;
+ int a,
+ b,
+ c,
+ d,
+ e,
+ f,
+ g,
+ h;
+ char junk[2];
+ int count;
+
+
+ /* %1s matches iff there is trailing non-whitespace garbage */
+
+ 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 macaddr64: \"%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) ||
+ (g < 0) || (g > 255) || (h < 0) || (h > 255))
+ ereport(ERROR,
+ (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+ errmsg("invalid octet value in \"macaddr64\" value: \"%s\"", str)));
+
+ 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 \"macaddr64\" 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 \"macaddr64\" Address: \"%s\"", str),
+ errhint ("FF-FF-FF-FF-FF-FF-FF-FF address is a reserved address")));
+
+ result = (macaddr64 *) palloc(sizeof(macaddr64));
+
+ result->a = a;
+ result->b = b;
+ result->c = c;
+ result->d = d;
+ result->e = e;
+ result->f = f;
+ result->g = g;
+ result->h = h;
+
+ PG_RETURN_MACADDR64_P(result);
+}
+
+/*
+ * MAC address output function. Fixed format.
+ */
+
+Datum
+macaddr64_out(PG_FUNCTION_ARGS)
+{
+ macaddr64 *addr = PG_GETARG_MACADDR64_P(0);
+ char *result;
+
+ result = (char *) palloc(32);
+
+ snprintf(result, 32, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
+ addr->a, addr->b, addr->c, addr->d, addr->e, addr->f, addr->g, addr->h);
+
+ PG_RETURN_CSTRING(result);
+}
+
+/*
+ * macaddr64_recv - converts external binary format to macaddr(EUI-64)
+ *
+ * The external representation is just the six bytes, MSB first.
+ */
+Datum
+macaddr64_recv(PG_FUNCTION_ARGS)
+{
+ StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
+ macaddr64 *addr;
+
+ addr = (macaddr64 *) palloc(sizeof(macaddr64));
+
+ 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);
+ addr->g = pq_getmsgbyte(buf);
+ addr->h = pq_getmsgbyte(buf);
+
+ PG_RETURN_MACADDR64_P(addr);
+}
+
+/*
+ * macaddr64_send - converts macaddr(EUI-64) to binary format
+ */
+Datum
+macaddr64_send(PG_FUNCTION_ARGS)
+{
+ macaddr64 *addr = PG_GETARG_MACADDR64_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);
+ pq_sendbyte(&buf, addr->g);
+ pq_sendbyte(&buf, addr->h);
+ PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
+}
+
+
+/*
+ * Comparison function for sorting:
+ */
+
+static int32
+macaddr64_cmp_internal(macaddr64 *a1, macaddr64 *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
+macaddr64_cmp(PG_FUNCTION_ARGS)
+{
+ macaddr64 *a1 = PG_GETARG_MACADDR64_P(0);
+ macaddr64 *a2 = PG_GETARG_MACADDR64_P(1);
+
+ PG_RETURN_INT32(macaddr64_cmp_internal(a1, a2));
+}
+
+/*
+ * Boolean comparisons.
+ */
+
+Datum
+macaddr64_lt(PG_FUNCTION_ARGS)
+{
+ macaddr64 *a1 = PG_GETARG_MACADDR64_P(0);
+ macaddr64 *a2 = PG_GETARG_MACADDR64_P(1);
+
+ PG_RETURN_BOOL(macaddr64_cmp_internal(a1, a2) < 0);
+}
+
+Datum
+macaddr64_le(PG_FUNCTION_ARGS)
+{
+ macaddr64 *a1 = PG_GETARG_MACADDR64_P(0);
+ macaddr64 *a2 = PG_GETARG_MACADDR64_P(1);
+
+ PG_RETURN_BOOL(macaddr64_cmp_internal(a1, a2) <= 0);
+}
+
+Datum
+macaddr64_eq(PG_FUNCTION_ARGS)
+{
+ macaddr64 *a1 = PG_GETARG_MACADDR64_P(0);
+ macaddr64 *a2 = PG_GETARG_MACADDR64_P(1);
+
+ PG_RETURN_BOOL(macaddr64_cmp_internal(a1, a2) == 0);
+}
+
+Datum
+macaddr64_ge(PG_FUNCTION_ARGS)
+{
+ macaddr64 *a1 = PG_GETARG_MACADDR64_P(0);
+ macaddr64 *a2 = PG_GETARG_MACADDR64_P(1);
+
+ PG_RETURN_BOOL(macaddr64_cmp_internal(a1, a2) >= 0);
+}
+
+Datum
+macaddr64_gt(PG_FUNCTION_ARGS)
+{
+ macaddr64 *a1 = PG_GETARG_MACADDR64_P(0);
+ macaddr64 *a2 = PG_GETARG_MACADDR64_P(1);
+
+ PG_RETURN_BOOL(macaddr64_cmp_internal(a1, a2) > 0);
+}
+
+Datum
+macaddr64_ne(PG_FUNCTION_ARGS)
+{
+ macaddr64 *a1 = PG_GETARG_MACADDR64_P(0);
+ macaddr64 *a2 = PG_GETARG_MACADDR64_P(1);
+
+ PG_RETURN_BOOL(macaddr64_cmp_internal(a1, a2) != 0);
+}
+
+/*
+ * Support function for hash indexes on macaddr64.
+ */
+Datum
+hashmacaddr64(PG_FUNCTION_ARGS)
+{
+ macaddr64 *key = PG_GETARG_MACADDR64_P(0);
+
+ return hash_any((unsigned char *) key, sizeof(macaddr64));
+}
+
+/*
+ * Arithmetic functions: bitwise NOT, AND, OR.
+ */
+Datum
+macaddr64_not(PG_FUNCTION_ARGS)
+{
+ macaddr64 *addr = PG_GETARG_MACADDR64_P(0);
+ macaddr64 *result;
+
+ result = (macaddr64 *) palloc(sizeof(macaddr64));
+ result->a = ~addr->a;
+ result->b = ~addr->b;
+ result->c = ~addr->c;
+ result->d = ~addr->d;
+ result->e = ~addr->e;
+ result->f = ~addr->f;
+ result->g = ~addr->g;
+ result->h = ~addr->h;
+ PG_RETURN_MACADDR64_P(result);
+}
+
+Datum
+macaddr64_and(PG_FUNCTION_ARGS)
+{
+ macaddr64 *addr1 = PG_GETARG_MACADDR64_P(0);
+ macaddr64 *addr2 = PG_GETARG_MACADDR64_P(1);
+ macaddr64 *result;
+
+ result = (macaddr64 *) palloc(sizeof(macaddr64));
+ 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;
+ result->g = addr1->g & addr2->g;
+ result->h = addr1->h & addr2->h;
+ PG_RETURN_MACADDR64_P(result);
+}
+
+Datum
+macaddr64_or(PG_FUNCTION_ARGS)
+{
+ macaddr64 *addr1 = PG_GETARG_MACADDR64_P(0);
+ macaddr64 *addr2 = PG_GETARG_MACADDR64_P(1);
+ macaddr64 *result;
+
+ result = (macaddr64 *) palloc(sizeof(macaddr64));
+ 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;
+ result->g = addr1->g | addr2->g;
+ result->h = addr1->h | addr2->h;
+ PG_RETURN_MACADDR64_P(result);
+}
+
+/*
+ * Truncation function to allow comparing mac manufacturers.
+ * From suggestion by Alex Pilosov <alex@pilosoft.com>
+ */
+Datum
+macaddr64_trunc(PG_FUNCTION_ARGS)
+{
+ macaddr64 *addr = PG_GETARG_MACADDR64_P(0);
+ macaddr64 *result;
+
+ result = (macaddr64 *) palloc(sizeof(macaddr64));
+
+ result->a = addr->a;
+ result->b = addr->b;
+ result->c = addr->c;
+ result->d = addr->d;
+ result->e = 0;
+ result->f = 0;
+ result->g = 0;
+ result->g = 0;
+
+ PG_RETURN_MACADDR64_P(result);
+}
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 6b52222..21372af 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -695,6 +695,8 @@ DATA(insert OID = 422 ( hashinet PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0
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 ( hashmacaddr64 PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 23 "774" _null_ _null_ _null_ _null_ _null_ hashmacaddr64 _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");
@@ -2114,6 +2116,28 @@ DATA(insert OID = 3144 ( macaddr_not PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1
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_ ));
+/* for macaddr64 type support */
+DATA(insert OID = 3349 ( macaddr64_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_ macaddr64_in _null_ _null_ _null_ ));
+DESCR("I/O");
+DATA(insert OID = 3350 ( macaddr64_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_ macaddr64_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_ macaddr64_trunc _null_ _null_ _null_ ));
+DESCR("MACADDR64 manufacturer fields");
+
+DATA(insert OID = 3352 ( macaddr64_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_ macaddr64_eq _null_ _null_ _null_ ));
+DATA(insert OID = 3353 ( macaddr64_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_ macaddr64_lt _null_ _null_ _null_ ));
+DATA(insert OID = 3354 ( macaddr64_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_ macaddr64_le _null_ _null_ _null_ ));
+DATA(insert OID = 3355 ( macaddr64_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_ macaddr64_gt _null_ _null_ _null_ ));
+DATA(insert OID = 3356 ( macaddr64_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_ macaddr64_ge _null_ _null_ _null_ ));
+DATA(insert OID = 3357 ( macaddr64_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_ macaddr64_ne _null_ _null_ _null_ ));
+DATA(insert OID = 3358 ( macaddr64_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_ macaddr64_cmp _null_ _null_ _null_ ));
+DESCR("less-equal-greater");
+DATA(insert OID = 3359 ( macaddr64_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_ macaddr64_not _null_ _null_ _null_ ));
+DATA(insert OID = 3360 ( macaddr64_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_ macaddr64_and _null_ _null_ _null_ ));
+DATA(insert OID = 3361 ( macaddr64_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_ macaddr64_or _null_ _null_ _null_ ));
+
+
/* 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_ ));
DESCR("I/O");
@@ -4046,6 +4070,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 ( macaddr64_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_ macaddr64_recv _null_ _null_ _null_ ));
+DESCR("I/O");
+DATA(insert OID = 3345 ( macaddr64_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_ macaddr64_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..4c957fe 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -441,9 +441,13 @@ DESCR("IP address/netmask, host address, netmask optional");
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 ( macaddr64 PGNSP PGUID 8 f b U f t \054 0 0 775 macaddr64_in macaddr64_out macaddr64_recv macaddr64_send - - - i p f 0 -1 0 0 _null_ _null_ _null_ ));
+DESCR("XX:XX:XX:XX:XX:XX:XX:XX, MAC address");
+#define MACADDR64OID 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_ ));
@@ -482,6 +486,7 @@ 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 = 775 ( _macaddr64 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 2ae212a..4e85fbd 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -1022,6 +1022,24 @@ extern Datum macaddr_or(PG_FUNCTION_ARGS);
extern Datum macaddr_trunc(PG_FUNCTION_ARGS);
extern Datum hashmacaddr(PG_FUNCTION_ARGS);
+/* mac64.c */
+extern Datum macaddr64_in(PG_FUNCTION_ARGS);
+extern Datum macaddr64_out(PG_FUNCTION_ARGS);
+extern Datum macaddr64_recv(PG_FUNCTION_ARGS);
+extern Datum macaddr64_send(PG_FUNCTION_ARGS);
+extern Datum macaddr64_cmp(PG_FUNCTION_ARGS);
+extern Datum macaddr64_lt(PG_FUNCTION_ARGS);
+extern Datum macaddr64_le(PG_FUNCTION_ARGS);
+extern Datum macaddr64_eq(PG_FUNCTION_ARGS);
+extern Datum macaddr64_ge(PG_FUNCTION_ARGS);
+extern Datum macaddr64_gt(PG_FUNCTION_ARGS);
+extern Datum macaddr64_ne(PG_FUNCTION_ARGS);
+extern Datum macaddr64_not(PG_FUNCTION_ARGS);
+extern Datum macaddr64_and(PG_FUNCTION_ARGS);
+extern Datum macaddr64_or(PG_FUNCTION_ARGS);
+extern Datum macaddr64_trunc(PG_FUNCTION_ARGS);
+extern Datum hashmacaddr64(PG_FUNCTION_ARGS);
+
/* numeric.c */
extern Datum numeric_in(PG_FUNCTION_ARGS);
extern Datum numeric_out(PG_FUNCTION_ARGS);
diff --git a/src/include/utils/inet.h b/src/include/utils/inet.h
index 9fd954d..5342d19 100644
--- a/src/include/utils/inet.h
+++ b/src/include/utils/inet.h
@@ -102,6 +102,21 @@ typedef struct macaddr
} macaddr;
/*
+ * This is the internal storage format for MAC addresses (EUI-64):
+ */
+typedef struct macaddr64
+{
+ unsigned char a;
+ unsigned char b;
+ unsigned char c;
+ unsigned char d;
+ unsigned char e;
+ unsigned char f;
+ unsigned char g;
+ unsigned char h;
+} macaddr64;
+
+/*
* fmgr interface macros
*/
#define DatumGetInetP(X) ((inet *) PG_DETOAST_DATUM(X))
@@ -115,6 +130,11 @@ typedef struct macaddr
#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)
+/* macaddr64 is a fixed-length pass-by-reference datatype */
+#define DatumGetMacaddr64P(X) ((macaddr64 *) DatumGetPointer(X))
+#define Macaddr64PGetDatum(X) PointerGetDatum(X)
+#define PG_GETARG_MACADDR64_P(n) DatumGetMacaddr64P(PG_GETARG_DATUM(n))
+#define PG_RETURN_MACADDR64_P(x) return Macaddr64PGetDatum(x)
/*
* Support functions in network.c