diff --git a/contrib/btree_gin/btree_gin.c b/contrib/btree_gin/btree_gin.c
index 030b610..d5c0e49 100644
--- a/contrib/btree_gin/btree_gin.c
+++ b/contrib/btree_gin/btree_gin.c
@@ -323,6 +323,16 @@ leftmostvalue_macaddr(void)
GIN_SUPPORT(macaddr, false, leftmostvalue_macaddr, macaddr_cmp)
static Datum
+leftmostvalue_macaddr8(void)
+{
+ macaddr8 *v = palloc0(sizeof(macaddr8));
+
+ return Macaddr8PGetDatum(v);
+}
+
+GIN_SUPPORT(macaddr8, false, leftmostvalue_macaddr8, macaddr8_cmp)
+
+static Datum
leftmostvalue_inet(void)
{
return DirectFunctionCall1(inet_in, CStringGetDatum("0.0.0.0/0"));
diff --git a/doc/src/sgml/brin.sgml b/doc/src/sgml/brin.sgml
index f519285..7c603e2 100644
--- a/doc/src/sgml/brin.sgml
+++ b/doc/src/sgml/brin.sgml
@@ -282,6 +282,17 @@
+ macaddr8_minmax_ops
+ macaddr8
+
+ <
+ <=
+ =
+ >=
+ >
+
+
+
name_minmax_ops
name
diff --git a/doc/src/sgml/btree-gin.sgml b/doc/src/sgml/btree-gin.sgml
index 2b081db..0de8eb5 100644
--- a/doc/src/sgml/btree-gin.sgml
+++ b/doc/src/sgml/btree-gin.sgml
@@ -16,7 +16,8 @@
time without time zone>, date>, interval>,
oid>, money>, "char">,
varchar>, text>, bytea>, bit>,
- varbit>, macaddr>, inet>, and cidr>.
+ varbit>, macaddr>, macaddr8>, inet>,
+ and cidr>.
diff --git a/doc/src/sgml/btree-gist.sgml b/doc/src/sgml/btree-gist.sgml
index d08647c..cfdd5be 100644
--- a/doc/src/sgml/btree-gist.sgml
+++ b/doc/src/sgml/btree-gist.sgml
@@ -16,8 +16,8 @@
time without time zone>, date>, interval>,
oid>, money>, char>,
varchar>, text>, bytea>, bit>,
- varbit>, macaddr>, inet>, cidr>,
- and uuid>.
+ varbit>, macaddr>, macaddr8>, inet>,
+ cidr> and uuid>.
diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index 3bc6854..c86e5fd 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -165,6 +165,12 @@
MAC (Media Access Control) address
+
+
+ macaddr8
+
+ MAC (Media Access Control) address (EUI-64 format)
+
money
@@ -3460,6 +3466,12 @@ SELECT person.name, holidays.num_weeks FROM person, holidays
6 bytes
MAC addresses
+
+
+ macaddr8
+ 8 bytes
+ MAC addresses (EUI-64 format)
+
@@ -3701,6 +3713,53 @@ SELECT person.name, holidays.num_weeks FROM person, holidays
+
+ macaddr8
+
+
+ macaddr8 (data type)
+
+
+
+ MAC address (EUI-64 format)
+ macaddr
+
+
+
+ The macaddr8> type stores MAC addresses in EUI-64
+ format, known for example from Ethernet card hardware addresses
+ (although MAC addresses are used for other purposes as well).
+ This type can accept both 6 and 8 bytes length MAC addresses.
+ Input is accepted in the following formats:
+
+
+ '08:00:2b:01:02:03:04:05'>
+ '08-00-2b-01-02-03-04-05'>
+ '08002b:0102030405'>
+ '08002b-0102030405'>
+ '0800.2b01.0203.0405'>
+ '0800-2b01-0203-0405'>
+ '08002b01:02030405'>
+ '08002b0102030405'>
+
+
+ These examples would all specify the same address. Upper and
+ lower case is accepted for the digits
+ a> through f>. Output is always in the
+ first of the forms shown.
+
+
+
+ The last six input formats that are mentioned above are not part
+ of any standard.
+
+
+
+ Refer macaddr> type for the list of input types that
+ are supported in 6 bytes length format.
+
+
+
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 10e3186..0b74d40 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -9225,6 +9225,50 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
for NOT, AND and OR.
+
+ shows the functions
+ available for use with the macaddr8 type. The function
+ trunc(macaddr8) returns a MAC
+ address with the last 5 bytes set to zero. This can be used to
+ associate the remaining prefix with a manufacturer.
+
+
+
+ macaddr8 Functions
+
+
+
+ Function
+ Return Type
+ Description
+ Example
+ Result
+
+
+
+
+
+
+ trunc
+
+ trunc(macaddr8)
+
+ macaddr8
+ set last 5 bytes to zero
+ trunc(macaddr8 '12:34:56:78:90:ab:cd:ef')
+ 12:34:56:00:00:00:00:00
+
+
+
+
+
+
+ The macaddr8 type also supports the standard relational
+ operators (>, <=, etc.) for
+ ordering, and the bitwise arithmetic operators (~,
+ & and |) for NOT, AND and OR.
+
+
diff --git a/src/backend/utils/adt/Makefile b/src/backend/utils/adt/Makefile
index 0f51275..1fb0184 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 mac8.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..ef0810e 100644
--- a/src/backend/utils/adt/mac.c
+++ b/src/backend/utils/adt/mac.c
@@ -1,5 +1,6 @@
/*
* PostgreSQL type definitions for MAC addresses.
+ * Supports only 6-byte MAC addresses
*
* src/backend/utils/adt/mac.c
*/
diff --git a/src/backend/utils/adt/mac8.c b/src/backend/utils/adt/mac8.c
new file mode 100644
index 0000000..682ce07
--- /dev/null
+++ b/src/backend/utils/adt/mac8.c
@@ -0,0 +1,441 @@
+/*
+ * PostgreSQL type definitions for MAC addresses
+ * Support both EUI-48 and EUI-64.
+ *
+ * The following code is written with the assumption of
+ * OUI field size as 24 bits
+ *
+ * src/backend/utils/adt/mac8.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-48 and EUI-64) reader. Accepts several common notations.
+ */
+
+Datum
+macaddr8_in(PG_FUNCTION_ARGS)
+{
+ char *str = PG_GETARG_CSTRING(0);
+ macaddr8 *result;
+ int a,
+ b,
+ c,
+ d = 0,
+ e = 0,
+ f,
+ g,
+ h;
+ char junk[2];
+ int count;
+ bool eight_byte_address = false;
+
+
+ /* %1s matches iff there is trailing non-whitespace garbage */
+ count = sscanf(str, "%x:%x:%x:%x:%x:%x%1s",
+ &a, &b, &c, &f, &g, &h, junk);
+ if (count != 6)
+ count = sscanf(str, "%x-%x-%x-%x-%x-%x%1s",
+ &a, &b, &c, &f, &g, &h, junk);
+ if (count != 6)
+ count = sscanf(str, "%2x%2x%2x:%2x%2x%2x%1s",
+ &a, &b, &c, &f, &g, &h, junk);
+ if (count != 6)
+ count = sscanf(str, "%2x%2x%2x-%2x%2x%2x%1s",
+ &a, &b, &c, &f, &g, &h, junk);
+ if (count != 6)
+ count = sscanf(str, "%2x%2x.%2x%2x.%2x%2x%1s",
+ &a, &b, &c, &f, &g, &h, junk);
+ if (count != 6)
+ count = sscanf(str, "%2x%2x-%2x%2x-%2x%2x%1s",
+ &a, &b, &c, &f, &g, &h, junk);
+ if (count != 6)
+ count = sscanf(str, "%2x%2x%2x%2x%2x%2x%1s",
+ &a, &b, &c, &f, &g, &h, junk);
+
+ if (count != 6)
+ {
+ /* 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)
+ 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 macaddr8: \"%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 \"macaddr8\" value: \"%s\"", str)));
+
+ result = (macaddr8 *) palloc0(sizeof(macaddr8));
+
+ if (!eight_byte_address)
+ {
+ d = 0xFF;
+ e = 0xFE;
+ }
+
+ 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_MACADDR8_P(result);
+}
+
+/*
+ * MAC8 address (EUI-64) output function. Fixed format.
+ */
+
+Datum
+macaddr8_out(PG_FUNCTION_ARGS)
+{
+ macaddr8 *addr = PG_GETARG_MACADDR8_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);
+}
+
+/*
+ * macaddr8_recv - converts external binary format(EUI-48 and EUI-64) to macaddr8
+ *
+ * The external representation is just the six bytes, MSB first.
+ */
+Datum
+macaddr8_recv(PG_FUNCTION_ARGS)
+{
+ StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
+ macaddr8 *addr;
+
+ addr = (macaddr8 *) palloc0(sizeof(macaddr8));
+
+ addr->a = pq_getmsgbyte(buf);
+ addr->b = pq_getmsgbyte(buf);
+ addr->c = pq_getmsgbyte(buf);
+
+ if (buf->len == 6)
+ {
+ addr->d = 0xFF;
+ addr->e = 0xFE;
+ }
+ else
+ {
+ 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_MACADDR8_P(addr);
+}
+
+/*
+ * macaddr8_send - converts macaddr8(EUI-64) to binary format
+ */
+Datum
+macaddr8_send(PG_FUNCTION_ARGS)
+{
+ macaddr8 *addr = PG_GETARG_MACADDR8_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
+macaddr8_cmp_internal(macaddr8 * a1, macaddr8 * 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
+macaddr8_cmp(PG_FUNCTION_ARGS)
+{
+ macaddr8 *a1 = PG_GETARG_MACADDR8_P(0);
+ macaddr8 *a2 = PG_GETARG_MACADDR8_P(1);
+
+ PG_RETURN_INT32(macaddr8_cmp_internal(a1, a2));
+}
+
+/*
+ * Boolean comparisons.
+ */
+
+Datum
+macaddr8_lt(PG_FUNCTION_ARGS)
+{
+ macaddr8 *a1 = PG_GETARG_MACADDR8_P(0);
+ macaddr8 *a2 = PG_GETARG_MACADDR8_P(1);
+
+ PG_RETURN_BOOL(macaddr8_cmp_internal(a1, a2) < 0);
+}
+
+Datum
+macaddr8_le(PG_FUNCTION_ARGS)
+{
+ macaddr8 *a1 = PG_GETARG_MACADDR8_P(0);
+ macaddr8 *a2 = PG_GETARG_MACADDR8_P(1);
+
+ PG_RETURN_BOOL(macaddr8_cmp_internal(a1, a2) <= 0);
+}
+
+Datum
+macaddr8_eq(PG_FUNCTION_ARGS)
+{
+ macaddr8 *a1 = PG_GETARG_MACADDR8_P(0);
+ macaddr8 *a2 = PG_GETARG_MACADDR8_P(1);
+
+ PG_RETURN_BOOL(macaddr8_cmp_internal(a1, a2) == 0);
+}
+
+Datum
+macaddr8_ge(PG_FUNCTION_ARGS)
+{
+ macaddr8 *a1 = PG_GETARG_MACADDR8_P(0);
+ macaddr8 *a2 = PG_GETARG_MACADDR8_P(1);
+
+ PG_RETURN_BOOL(macaddr8_cmp_internal(a1, a2) >= 0);
+}
+
+Datum
+macaddr8_gt(PG_FUNCTION_ARGS)
+{
+ macaddr8 *a1 = PG_GETARG_MACADDR8_P(0);
+ macaddr8 *a2 = PG_GETARG_MACADDR8_P(1);
+
+ PG_RETURN_BOOL(macaddr8_cmp_internal(a1, a2) > 0);
+}
+
+Datum
+macaddr8_ne(PG_FUNCTION_ARGS)
+{
+ macaddr8 *a1 = PG_GETARG_MACADDR8_P(0);
+ macaddr8 *a2 = PG_GETARG_MACADDR8_P(1);
+
+ PG_RETURN_BOOL(macaddr8_cmp_internal(a1, a2) != 0);
+}
+
+/*
+ * Support function for hash indexes on macaddr8.
+ */
+Datum
+hashmacaddr8(PG_FUNCTION_ARGS)
+{
+ macaddr8 *key = PG_GETARG_MACADDR8_P(0);
+
+ return hash_any((unsigned char *) key, sizeof(macaddr8));
+}
+
+/*
+ * Arithmetic functions: bitwise NOT, AND, OR.
+ */
+Datum
+macaddr8_not(PG_FUNCTION_ARGS)
+{
+ macaddr8 *addr = PG_GETARG_MACADDR8_P(0);
+ macaddr8 *result;
+
+ result = (macaddr8 *) palloc0(sizeof(macaddr8));
+ 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_MACADDR8_P(result);
+}
+
+Datum
+macaddr8_and(PG_FUNCTION_ARGS)
+{
+ macaddr8 *addr1 = PG_GETARG_MACADDR8_P(0);
+ macaddr8 *addr2 = PG_GETARG_MACADDR8_P(1);
+ macaddr8 *result;
+
+ result = (macaddr8 *) palloc0(sizeof(macaddr8));
+ 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_MACADDR8_P(result);
+}
+
+Datum
+macaddr8_or(PG_FUNCTION_ARGS)
+{
+ macaddr8 *addr1 = PG_GETARG_MACADDR8_P(0);
+ macaddr8 *addr2 = PG_GETARG_MACADDR8_P(1);
+ macaddr8 *result;
+
+ result = (macaddr8 *) palloc0(sizeof(macaddr8));
+ 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_MACADDR8_P(result);
+}
+
+/*
+ * Truncation function to allow comparing macaddr8 manufacturers.
+ */
+Datum
+macaddr8_trunc(PG_FUNCTION_ARGS)
+{
+ macaddr8 *addr = PG_GETARG_MACADDR8_P(0);
+ macaddr8 *result;
+
+ result = (macaddr8 *) palloc0(sizeof(macaddr8));
+
+ result->a = addr->a;
+ result->b = addr->b;
+ result->c = addr->c;
+ result->d = 0;
+ result->e = 0;
+ result->f = 0;
+ result->g = 0;
+ result->h = 0;
+
+ PG_RETURN_MACADDR8_P(result);
+}
+
+Datum
+macaddrtomacaddr8(PG_FUNCTION_ARGS)
+{
+ macaddr *addr6 = PG_GETARG_MACADDR_P(0);
+ macaddr8 *result;
+
+ result = (macaddr8 *) palloc0(sizeof(macaddr8));
+
+ result->a = addr6->a;
+ result->b = addr6->b;
+ result->c = addr6->c;
+ result->d = 0xFF;
+ result->e = 0xFE;
+ result->f = addr6->d;
+ result->g = addr6->e;
+ result->h = addr6->f;
+
+
+ PG_RETURN_MACADDR8_P(result);
+}
+
+Datum
+macaddr8tomacaddr(PG_FUNCTION_ARGS)
+{
+ macaddr8 *addr = PG_GETARG_MACADDR8_P(0);
+ macaddr *result;
+
+ result = (macaddr *) palloc0(sizeof(macaddr));
+
+ if ((addr->d != 0xFF) || (addr->e != 0xFE))
+ ereport(ERROR,
+ (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+ errmsg("macaddr8 data out of range to convert to macaddr"),
+ errhint("The addresses that comes with FF and FE as values in "
+ "3rd and 4th bytes starts from left, for example: "
+ "XX-XX-XX-FF-FE-XX-XX-XX are eligible to convert from "
+ "macaddr8 to macaddr datatype")));
+
+ result->a = addr->a;
+ result->b = addr->b;
+ result->c = addr->c;
+ result->d = addr->f;
+ result->e = addr->g;
+ result->f = addr->h;
+
+ PG_RETURN_MACADDR_P(result);
+}
diff --git a/src/backend/utils/adt/network.c b/src/backend/utils/adt/network.c
index dbc557e..1719f01 100644
--- a/src/backend/utils/adt/network.c
+++ b/src/backend/utils/adt/network.c
@@ -934,6 +934,17 @@ convert_network_to_scalar(Datum value, Oid typid)
res += (mac->d << 16) | (mac->e << 8) | (mac->f);
return res;
}
+ case MACADDR8OID:
+ {
+ macaddr8 *mac = DatumGetMacaddr8P(value);
+ double res;
+
+ res = (mac->a << 24) | (mac->b << 16) | (mac->c << 8) | (mac->d);
+ res *= 256 * 256;
+ res *= 256 * 256;
+ res += (mac->e << 24) | (mac->f << 16) | (mac->g << 8) | (mac->h);
+ return res;
+ }
}
/*
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 301dffa..e482b3d 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -3798,6 +3798,7 @@ convert_to_scalar(Datum value, Oid valuetypid, double *scaledvalue,
case INETOID:
case CIDROID:
case MACADDROID:
+ case MACADDR8OID:
*scaledvalue = convert_network_to_scalar(value, valuetypid);
*scaledlobound = convert_network_to_scalar(lobound, boundstypid);
*scaledhibound = convert_network_to_scalar(hibound, boundstypid);
diff --git a/src/include/catalog/pg_amop.h b/src/include/catalog/pg_amop.h
index 0251664..da0228d 100644
--- a/src/include/catalog/pg_amop.h
+++ b/src/include/catalog/pg_amop.h
@@ -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 macaddr8
+ */
+
+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
*/
@@ -553,6 +563,8 @@ DATA(insert ( 1977 20 23 1 s 416 405 0 ));
DATA(insert ( 1983 1186 1186 1 s 1330 405 0 ));
/* macaddr_ops */
DATA(insert ( 1985 829 829 1 s 1220 405 0 ));
+/* macaddr8_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 */
@@ -999,6 +1011,12 @@ 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 macaddr8 */
+DATA(insert ( 4109 774 774 1 s 3364 3580 0 ));
+DATA(insert ( 4109 774 774 2 s 3365 3580 0 ));
+DATA(insert ( 4109 774 774 3 s 3362 3580 0 ));
+DATA(insert ( 4109 774 774 4 s 3367 3580 0 ));
+DATA(insert ( 4109 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 f1a52ce..a87ec42 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 4119 ));
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 ));
@@ -414,6 +416,11 @@ 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 macaddr8 */
+DATA(insert ( 4109 774 774 1 3383 ));
+DATA(insert ( 4109 774 774 2 3384 ));
+DATA(insert ( 4109 774 774 3 3385 ));
+DATA(insert ( 4109 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 80a40ab..ce8dc59 100644
--- a/src/include/catalog/pg_cast.h
+++ b/src/include/catalog/pg_cast.h
@@ -304,6 +304,12 @@ DATA(insert ( 718 603 1480 e f ));
DATA(insert ( 718 604 1544 e f ));
/*
+ * MAC address category
+ */
+DATA(insert ( 829 774 4123 i f ));
+DATA(insert ( 774 829 4124 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 0cde14c..5d22c87 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 macaddr_ops PGNSP PGUID 1984 829 t 0 ));
+DATA(insert ( 405 macaddr_ops PGNSP PGUID 1985 829 t 0 ));
+DATA(insert ( 403 macaddr8_ops PGNSP PGUID 3371 774 t 0 ));
+DATA(insert ( 405 macaddr8_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;
@@ -224,6 +226,7 @@ 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 macaddr8_minmax_ops PGNSP PGUID 4109 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 aeb7927..c5c1e5e 100644
--- a/src/include/catalog/pg_operator.h
+++ b/src/include/catalog/pg_operator.h
@@ -1113,7 +1113,7 @@ DESCR("equal");
DATA(insert OID = 1617 ( "#" PGNSP PGUID b f f 628 628 600 1617 0 line_interpt - - ));
DESCR("intersection point");
-/* MAC type */
+/* MACADDR type */
DATA(insert OID = 1220 ( "=" PGNSP PGUID b t t 829 829 16 1220 1221 macaddr_eq eqsel eqjoinsel ));
DESCR("equal");
DATA(insert OID = 1221 ( "<>" PGNSP PGUID b f f 829 829 16 1221 1220 macaddr_ne neqsel neqjoinsel ));
@@ -1134,6 +1134,27 @@ DESCR("bitwise and");
DATA(insert OID = 3149 ( "|" PGNSP PGUID b f f 829 829 829 0 0 macaddr_or - - ));
DESCR("bitwise or");
+/* MACADDR8 type */
+DATA(insert OID = 3362 ( "=" PGNSP PGUID b t t 774 774 16 3362 3363 macaddr8_eq eqsel eqjoinsel ));
+DESCR("equal");
+DATA(insert OID = 3363 ( "<>" PGNSP PGUID b f f 774 774 16 3363 3362 macaddr8_ne neqsel neqjoinsel ));
+DESCR("not equal");
+DATA(insert OID = 3364 ( "<" PGNSP PGUID b f f 774 774 16 3366 3367 macaddr8_lt scalarltsel scalarltjoinsel ));
+DESCR("less than");
+DATA(insert OID = 3365 ( "<=" PGNSP PGUID b f f 774 774 16 3367 3366 macaddr8_le scalarltsel scalarltjoinsel ));
+DESCR("less than or equal");
+DATA(insert OID = 3366 ( ">" PGNSP PGUID b f f 774 774 16 3364 3365 macaddr8_gt scalargtsel scalargtjoinsel ));
+DESCR("greater than");
+DATA(insert OID = 3367 ( ">=" PGNSP PGUID b f f 774 774 16 3365 3364 macaddr8_ge scalargtsel scalargtjoinsel ));
+DESCR("greater than or equal");
+
+DATA(insert OID = 3368 ( "~" PGNSP PGUID l f f 0 774 774 0 0 macaddr8_not - - ));
+DESCR("bitwise not");
+DATA(insert OID = 3369 ( "&" PGNSP PGUID b f f 774 774 774 0 0 macaddr8_and - - ));
+DESCR("bitwise and");
+DATA(insert OID = 3370 ( "|" PGNSP PGUID b f f 774 774 774 0 0 macaddr8_or - - ));
+DESCR("bitwise or");
+
/* INET type (these also support CIDR via implicit cast) */
DATA(insert OID = 1201 ( "=" PGNSP PGUID b t t 869 869 16 1201 1202 network_eq eqsel eqjoinsel ));
DESCR("equal");
diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h
index bd673fe..6d73d98 100644
--- a/src/include/catalog/pg_opfamily.h
+++ b/src/include/catalog/pg_opfamily.h
@@ -87,6 +87,8 @@ 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 = 3371 ( 403 macaddr8_ops PGNSP PGUID ));
+DATA(insert OID = 3372 ( 405 macaddr8_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 ));
@@ -171,6 +173,7 @@ 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 = 4109 ( 3580 macaddr8_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 37e022d..8ec5bc7 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -1,5 +1,4 @@
-/*-------------------------------------------------------------------------
- *
+/*
* pg_proc.h
* definition of the system "procedure" relation (pg_proc)
* along with the relation's initial contents.
@@ -692,6 +691,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 ( hashmacaddr8 PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 23 "774" _null_ _null_ _null_ _null_ _null_ hashmacaddr8 _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");
@@ -1765,7 +1766,7 @@ DATA(insert OID = 1765 ( setval PGNSP PGUID 12 1 0 0 0 f f f f t f v u 3 0 20
DESCR("set sequence value and is_called status");
DATA(insert OID = 3078 ( pg_sequence_parameters PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 2249 "26" "{26,20,20,20,20,16,20}" "{i,o,o,o,o,o,o}" "{sequence_oid,start_value,minimum_value,maximum_value,increment,cycle_option,cache_size}" _null_ _null_ pg_sequence_parameters _null_ _null_ _null_));
DESCR("sequence parameters, for use by information schema");
-DATA(insert OID = 4032 ( pg_sequence_last_value PGNSP PGUID 12 1 0 0 0 f f f f t f v u 1 0 20 "2205" _null_ _null_ _null_ _null_ _null_ pg_sequence_last_value _null_ _null_ _null_ ));
+DATA(insert OID = 4032 ( pg_sequence_last_value PGNSP PGUID 12 1 0 0 0 f f f f t f v u 1 0 20 "2205" _null_ _null_ _null_ _null_ _null_ pg_sequence_last_value _null_ _null_ _null_ ));
DESCR("sequence last value");
DATA(insert OID = 1579 ( varbit_in PGNSP PGUID 12 1 0 0 0 f f f f t f i s 3 0 1562 "2275 26 23" _null_ _null_ _null_ _null_ _null_ varbit_in _null_ _null_ _null_ ));
@@ -1979,7 +1980,7 @@ DATA(insert OID = 1642 ( pg_get_userbyid PGNSP PGUID 12 1 0 0 0 f f f f t f
DESCR("role name by OID (with fallback)");
DATA(insert OID = 1643 ( pg_get_indexdef PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 25 "26" _null_ _null_ _null_ _null_ _null_ pg_get_indexdef _null_ _null_ _null_ ));
DESCR("index description");
-DATA(insert OID = 3352 ( pg_get_partkeydef PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 25 "26" _null_ _null_ _null_ _null_ _null_ pg_get_partkeydef _null_ _null_ _null_ ));
+DATA(insert OID = 3352 ( pg_get_partkeydef PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 25 "26" _null_ _null_ _null_ _null_ _null_ pg_get_partkeydef _null_ _null_ _null_ ));
DESCR("partition key description");
DATA(insert OID = 1662 ( pg_get_triggerdef PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 25 "26" _null_ _null_ _null_ _null_ _null_ pg_get_triggerdef _null_ _null_ _null_ ));
DESCR("trigger description");
@@ -2094,14 +2095,14 @@ 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 */
+/* for macaddr 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_ ));
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_ ));
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");
+DESCR("MACADDR 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_ ));
@@ -2115,6 +2116,31 @@ 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 macaddr8 type support */
+DATA(insert OID = 4110 ( macaddr8_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_ macaddr8_in _null_ _null_ _null_ ));
+DESCR("I/O");
+DATA(insert OID = 4111 ( macaddr8_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_ macaddr8_out _null_ _null_ _null_ ));
+DESCR("I/O");
+
+DATA(insert OID = 4112 ( 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_ macaddr8_trunc _null_ _null_ _null_ ));
+DESCR("MACADDR8 manufacturer fields");
+
+DATA(insert OID = 4113 ( macaddr8_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_ macaddr8_eq _null_ _null_ _null_ ));
+DATA(insert OID = 4114 ( macaddr8_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_ macaddr8_lt _null_ _null_ _null_ ));
+DATA(insert OID = 4115 ( macaddr8_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_ macaddr8_le _null_ _null_ _null_ ));
+DATA(insert OID = 4116 ( macaddr8_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_ macaddr8_gt _null_ _null_ _null_ ));
+DATA(insert OID = 4117 ( macaddr8_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_ macaddr8_ge _null_ _null_ _null_ ));
+DATA(insert OID = 4118 ( macaddr8_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_ macaddr8_ne _null_ _null_ _null_ ));
+DATA(insert OID = 4119 ( macaddr8_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_ macaddr8_cmp _null_ _null_ _null_ ));
+DESCR("less-equal-greater");
+DATA(insert OID = 4120 ( macaddr8_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_ macaddr8_not _null_ _null_ _null_ ));
+DATA(insert OID = 4121 ( macaddr8_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_ macaddr8_and _null_ _null_ _null_ ));
+DATA(insert OID = 4122 ( macaddr8_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_ macaddr8_or _null_ _null_ _null_ ));
+DATA(insert OID = 4123 ( macaddr8 PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 774 "829" _null_ _null_ _null_ _null_ _null_ macaddrtomacaddr8 _null_ _null_ _null_ ));
+DESCR("convert macaddr to macaddr8");
+DATA(insert OID = 4124 ( macaddr PGNSP PGUID 12 1 0 0 0 f f f f t f i s 1 0 829 "774" _null_ _null_ _null_ _null_ _null_ macaddr8tomacaddr _null_ _null_ _null_ ));
+DESCR("convert macaddr8 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_ ));
DESCR("I/O");
@@ -4044,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 ( macaddr8_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_ macaddr8_recv _null_ _null_ _null_ ));
+DESCR("I/O");
+DATA(insert OID = 3345 ( macaddr8_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_ macaddr8_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 c2350f3..b3fc4ec 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 ( macaddr8 PGNSP PGUID 8 f b U f t \054 0 0 775 macaddr8_in macaddr8_out macaddr8_recv macaddr8_send - - - i p f 0 -1 0 0 _null_ _null_ _null_ ));
+DESCR("XX:XX:XX:XX:XX:XX:XX:XX, MAC address");
+#define MACADDR8OID 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 ( _macaddr8 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 e1bb344..f8c7faa 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -1022,6 +1022,26 @@ extern Datum macaddr_or(PG_FUNCTION_ARGS);
extern Datum macaddr_trunc(PG_FUNCTION_ARGS);
extern Datum hashmacaddr(PG_FUNCTION_ARGS);
+/* mac8.c */
+extern Datum macaddr8_in(PG_FUNCTION_ARGS);
+extern Datum macaddr8_out(PG_FUNCTION_ARGS);
+extern Datum macaddr8_recv(PG_FUNCTION_ARGS);
+extern Datum macaddr8_send(PG_FUNCTION_ARGS);
+extern Datum macaddr8_cmp(PG_FUNCTION_ARGS);
+extern Datum macaddr8_lt(PG_FUNCTION_ARGS);
+extern Datum macaddr8_le(PG_FUNCTION_ARGS);
+extern Datum macaddr8_eq(PG_FUNCTION_ARGS);
+extern Datum macaddr8_ge(PG_FUNCTION_ARGS);
+extern Datum macaddr8_gt(PG_FUNCTION_ARGS);
+extern Datum macaddr8_ne(PG_FUNCTION_ARGS);
+extern Datum macaddr8_not(PG_FUNCTION_ARGS);
+extern Datum macaddr8_and(PG_FUNCTION_ARGS);
+extern Datum macaddr8_or(PG_FUNCTION_ARGS);
+extern Datum macaddr8_trunc(PG_FUNCTION_ARGS);
+extern Datum hashmacaddr8(PG_FUNCTION_ARGS);
+extern Datum macaddrtomacaddr8(PG_FUNCTION_ARGS);
+extern Datum macaddr8tomacaddr(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 f6d4072..c9a8d66 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 MAC8 addresses:
+ */
+typedef struct macaddr8
+{
+ unsigned char a;
+ unsigned char b;
+ unsigned char c;
+ unsigned char d;
+ unsigned char e;
+ unsigned char f;
+ unsigned char g;
+ unsigned char h;
+} macaddr8;
+
+/*
* fmgr interface macros
*/
#define DatumGetInetP(X) ((inet *) PG_DETOAST_DATUM(X))
@@ -110,12 +125,19 @@ 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))
#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)
+/* macaddr8 is a fixed-length pass-by-reference datatype */
+#define DatumGetMacaddr8P(X) ((macaddr8 *) DatumGetPointer(X))
+#define Macaddr8PGetDatum(X) PointerGetDatum(X)
+#define PG_GETARG_MACADDR8_P(n) DatumGetMacaddr8P(PG_GETARG_DATUM(n))
+#define PG_RETURN_MACADDR8_P(x) return Macaddr8PGetDatum(x)
+
/*
* Support functions in network.c
*/
diff --git a/src/test/regress/expected/macaddr8.out b/src/test/regress/expected/macaddr8.out
new file mode 100644
index 0000000..b6ac9ef
--- /dev/null
+++ b/src/test/regress/expected/macaddr8.out
@@ -0,0 +1,251 @@
+--
+-- macaddr8
+--
+CREATE TABLE macaddr8_data (a int, b macaddr8);
+INSERT INTO macaddr8_data VALUES (1, '08:00:2b:01:02:03');
+INSERT INTO macaddr8_data VALUES (2, '08-00-2b-01-02-03');
+INSERT INTO macaddr8_data VALUES (3, '08002b:010203');
+INSERT INTO macaddr8_data VALUES (4, '08002b-010203');
+INSERT INTO macaddr8_data VALUES (5, '0800.2b01.0203');
+INSERT INTO macaddr8_data VALUES (6, '0800-2b01-0203');
+INSERT INTO macaddr8_data VALUES (7, '08002b010203');
+INSERT INTO macaddr8_data VALUES (8, '0800:2b01:0203'); -- invalid
+ERROR: invalid input syntax for type macaddr8: "0800:2b01:0203"
+LINE 1: INSERT INTO macaddr8_data VALUES (8, '0800:2b01:0203');
+ ^
+INSERT INTO macaddr8_data VALUES (9, 'not even close'); -- invalid
+ERROR: invalid input syntax for type macaddr8: "not even close"
+LINE 1: INSERT INTO macaddr8_data VALUES (9, 'not even close');
+ ^
+INSERT INTO macaddr8_data VALUES (10, '08:00:2b:01:02:04');
+INSERT INTO macaddr8_data VALUES (11, '08:00:2b:01:02:02');
+INSERT INTO macaddr8_data VALUES (12, '08:00:2a:01:02:03');
+INSERT INTO macaddr8_data VALUES (13, '08:00:2c:01:02:03');
+INSERT INTO macaddr8_data VALUES (14, '08:00:2a:01:02:04');
+INSERT INTO macaddr8_data VALUES (15, '08:00:2b:01:02:03:04:05');
+INSERT INTO macaddr8_data VALUES (16, '08-00-2b-01-02-03-04-05');
+INSERT INTO macaddr8_data VALUES (17, '08002b:0102030405');
+INSERT INTO macaddr8_data VALUES (18, '08002b-0102030405');
+INSERT INTO macaddr8_data VALUES (19, '0800.2b01.0203.0405');
+INSERT INTO macaddr8_data VALUES (20, '08002b01:02030405');
+INSERT INTO macaddr8_data VALUES (21, '08002b0102030405');
+SELECT * FROM macaddr8_data;
+ a | b
+----+-------------------------
+ 1 | 08:00:2b:ff:fe:01:02:03
+ 2 | 08:00:2b:ff:fe:01:02:03
+ 3 | 08:00:2b:ff:fe:01:02:03
+ 4 | 08:00:2b:ff:fe:01:02:03
+ 5 | 08:00:2b:ff:fe:01:02:03
+ 6 | 08:00:2b:ff:fe:01:02:03
+ 7 | 08:00:2b:ff:fe:01:02:03
+ 10 | 08:00:2b:ff:fe:01:02:04
+ 11 | 08:00:2b:ff:fe:01:02:02
+ 12 | 08:00:2a:ff:fe:01:02:03
+ 13 | 08:00:2c:ff:fe:01:02:03
+ 14 | 08:00:2a:ff:fe:01:02:04
+ 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
+ 21 | 08:00:2b:01:02:03:04:05
+(19 rows)
+
+CREATE INDEX macaddr8_data_btree ON macaddr8_data USING btree (b);
+CREATE INDEX macaddr8_data_hash ON macaddr8_data USING hash (b);
+WARNING: hash indexes are not WAL-logged and their use is discouraged
+SELECT a, b, trunc(b) FROM macaddr8_data ORDER BY 2, 1;
+ a | b | trunc
+----+-------------------------+-------------------------
+ 12 | 08:00:2a:ff:fe:01:02:03 | 08:00:2a:00:00:00:00:00
+ 14 | 08:00:2a:ff:fe:01:02:04 | 08:00:2a:00:00: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
+ 21 | 08:00:2b:01:02:03:04:05 | 08:00:2b:00:00:00:00:00
+ 11 | 08:00:2b:ff:fe:01:02:02 | 08:00:2b:00:00:00:00:00
+ 1 | 08:00:2b:ff:fe:01:02:03 | 08:00:2b:00:00:00:00:00
+ 2 | 08:00:2b:ff:fe:01:02:03 | 08:00:2b:00:00:00:00:00
+ 3 | 08:00:2b:ff:fe:01:02:03 | 08:00:2b:00:00:00:00:00
+ 4 | 08:00:2b:ff:fe:01:02:03 | 08:00:2b:00:00:00:00:00
+ 5 | 08:00:2b:ff:fe:01:02:03 | 08:00:2b:00:00:00:00:00
+ 6 | 08:00:2b:ff:fe:01:02:03 | 08:00:2b:00:00:00:00:00
+ 7 | 08:00:2b:ff:fe:01:02:03 | 08:00:2b:00:00:00:00:00
+ 10 | 08:00:2b:ff:fe:01:02:04 | 08:00:2b:00:00:00:00:00
+ 13 | 08:00:2c:ff:fe:01:02:03 | 08:00:2c:00:00:00:00:00
+(19 rows)
+
+SELECT b < '08:00:2b:01:02:04' FROM macaddr8_data WHERE a = 1; -- true
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT b > '08:00:2b:ff:fe:01:02:04' FROM macaddr8_data WHERE a = 1; -- false
+ ?column?
+----------
+ f
+(1 row)
+
+SELECT b > '08:00:2b:ff:fe:01:02:03' FROM macaddr8_data WHERE a = 1; -- false
+ ?column?
+----------
+ f
+(1 row)
+
+SELECT b::macaddr <= '08:00:2b:01:02:04' FROM macaddr8_data WHERE a = 1; -- true
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT b::macaddr >= '08:00:2b:01:02:04' FROM macaddr8_data WHERE a = 1; -- false
+ ?column?
+----------
+ f
+(1 row)
+
+SELECT b = '08:00:2b:ff:fe:01:02:03' FROM macaddr8_data WHERE a = 1; -- true
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT b::macaddr <> '08:00:2b:01:02:04'::macaddr FROM macaddr8_data WHERE a = 1; -- true
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT b::macaddr <> '08:00:2b:01:02:03'::macaddr FROM macaddr8_data WHERE a = 1; -- false
+ ?column?
+----------
+ f
+(1 row)
+
+SELECT b < '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15; -- true
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT b > '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15; -- false
+ ?column?
+----------
+ f
+(1 row)
+
+SELECT b > '08:00:2b:01:02:03:04:05' FROM macaddr8_data WHERE a = 15; -- false
+ ?column?
+----------
+ f
+(1 row)
+
+SELECT b <= '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15; -- true
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT b >= '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15; -- false
+ ?column?
+----------
+ f
+(1 row)
+
+SELECT b = '08:00:2b:01:02:03:04:05' FROM macaddr8_data WHERE a = 15; -- true
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT b <> '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15; -- true
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT b <> '08:00:2b:01:02:03:04:05' FROM macaddr8_data WHERE a = 15; -- false
+ ?column?
+----------
+ f
+(1 row)
+
+SELECT ~b FROM macaddr8_data;
+ ?column?
+-------------------------
+ f7:ff:d4:00:01:fe:fd:fc
+ f7:ff:d4:00:01:fe:fd:fc
+ f7:ff:d4:00:01:fe:fd:fc
+ f7:ff:d4:00:01:fe:fd:fc
+ f7:ff:d4:00:01:fe:fd:fc
+ f7:ff:d4:00:01:fe:fd:fc
+ f7:ff:d4:00:01:fe:fd:fc
+ f7:ff:d4:00:01:fe:fd:fb
+ f7:ff:d4:00:01:fe:fd:fd
+ f7:ff:d5:00:01:fe:fd:fc
+ f7:ff:d3:00:01:fe:fd:fc
+ f7:ff:d5:00:01:fe:fd:fb
+ 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
+ f7:ff:d4:fe:fd:fc:fb:fa
+(19 rows)
+
+SELECT b & '00:00:00:ff:ff:ff' FROM macaddr8_data;
+ ?column?
+-------------------------
+ 00:00:00:ff:fe:01:02:03
+ 00:00:00:ff:fe:01:02:03
+ 00:00:00:ff:fe:01:02:03
+ 00:00:00:ff:fe:01:02:03
+ 00:00:00:ff:fe:01:02:03
+ 00:00:00:ff:fe:01:02:03
+ 00:00:00:ff:fe:01:02:03
+ 00:00:00:ff:fe:01:02:04
+ 00:00:00:ff:fe:01:02:02
+ 00:00:00:ff:fe:01:02:03
+ 00:00:00:ff:fe:01:02:03
+ 00:00:00:ff:fe:01:02:04
+ 00:00:00:01:02:03:04:05
+ 00:00:00:01:02:03:04:05
+ 00:00:00:01:02:03:04:05
+ 00:00:00:01:02:03:04:05
+ 00:00:00:01:02:03:04:05
+ 00:00:00:01:02:03:04:05
+ 00:00:00:01:02:03:04:05
+(19 rows)
+
+SELECT b | '01:02:03:04:05:06' FROM macaddr8_data;
+ ?column?
+-------------------------
+ 09:02:2b:ff:fe:05:07:07
+ 09:02:2b:ff:fe:05:07:07
+ 09:02:2b:ff:fe:05:07:07
+ 09:02:2b:ff:fe:05:07:07
+ 09:02:2b:ff:fe:05:07:07
+ 09:02:2b:ff:fe:05:07:07
+ 09:02:2b:ff:fe:05:07:07
+ 09:02:2b:ff:fe:05:07:06
+ 09:02:2b:ff:fe:05:07:06
+ 09:02:2b:ff:fe:05:07:07
+ 09:02:2f:ff:fe:05:07:07
+ 09:02:2b:ff:fe:05:07:06
+ 09:02:2b:ff:fe:07:05:07
+ 09:02:2b:ff:fe:07:05:07
+ 09:02:2b:ff:fe:07:05:07
+ 09:02:2b:ff:fe:07:05:07
+ 09:02:2b:ff:fe:07:05:07
+ 09:02:2b:ff:fe:07:05:07
+ 09:02:2b:ff:fe:07:05:07
+(19 rows)
+
+DROP TABLE macaddr8_data;
diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out
index 0bcec13..64d9dd6 100644
--- a/src/test/regress/expected/opr_sanity.out
+++ b/src/test/regress/expected/opr_sanity.out
@@ -685,6 +685,12 @@ uuid_gt(uuid,uuid)
uuid_ne(uuid,uuid)
xidneq(xid,xid)
xidneqint4(xid,integer)
+macaddr8_eq(macaddr8,macaddr8)
+macaddr8_lt(macaddr8,macaddr8)
+macaddr8_le(macaddr8,macaddr8)
+macaddr8_gt(macaddr8,macaddr8)
+macaddr8_ge(macaddr8,macaddr8)
+macaddr8_ne(macaddr8,macaddr8)
-- restore normal output mode
\a\t
-- List of functions used by libpq's fe-lobj.c
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index 8641769..21e7f56 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -23,7 +23,7 @@ test: numerology
# ----------
# The second group of parallel tests
# ----------
-test: point lseg line box path polygon circle date time timetz timestamp timestamptz interval abstime reltime tinterval inet macaddr tstypes comments
+test: point lseg line box path polygon circle date time timetz timestamp timestamptz interval abstime reltime tinterval inet macaddr macaddr8 tstypes comments
# ----------
# Another group of parallel tests
diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule
index 835cf35..f72fb52 100644
--- a/src/test/regress/serial_schedule
+++ b/src/test/regress/serial_schedule
@@ -41,6 +41,7 @@ test: reltime
test: tinterval
test: inet
test: macaddr
+test: macaddr8
test: tstypes
test: comments
test: geometry
diff --git a/src/test/regress/sql/macaddr8.sql b/src/test/regress/sql/macaddr8.sql
new file mode 100644
index 0000000..48b542d
--- /dev/null
+++ b/src/test/regress/sql/macaddr8.sql
@@ -0,0 +1,60 @@
+--
+-- macaddr8
+--
+
+CREATE TABLE macaddr8_data (a int, b macaddr8);
+
+INSERT INTO macaddr8_data VALUES (1, '08:00:2b:01:02:03');
+INSERT INTO macaddr8_data VALUES (2, '08-00-2b-01-02-03');
+INSERT INTO macaddr8_data VALUES (3, '08002b:010203');
+INSERT INTO macaddr8_data VALUES (4, '08002b-010203');
+INSERT INTO macaddr8_data VALUES (5, '0800.2b01.0203');
+INSERT INTO macaddr8_data VALUES (6, '0800-2b01-0203');
+INSERT INTO macaddr8_data VALUES (7, '08002b010203');
+INSERT INTO macaddr8_data VALUES (8, '0800:2b01:0203'); -- invalid
+INSERT INTO macaddr8_data VALUES (9, 'not even close'); -- invalid
+
+INSERT INTO macaddr8_data VALUES (10, '08:00:2b:01:02:04');
+INSERT INTO macaddr8_data VALUES (11, '08:00:2b:01:02:02');
+INSERT INTO macaddr8_data VALUES (12, '08:00:2a:01:02:03');
+INSERT INTO macaddr8_data VALUES (13, '08:00:2c:01:02:03');
+INSERT INTO macaddr8_data VALUES (14, '08:00:2a:01:02:04');
+
+INSERT INTO macaddr8_data VALUES (15, '08:00:2b:01:02:03:04:05');
+INSERT INTO macaddr8_data VALUES (16, '08-00-2b-01-02-03-04-05');
+INSERT INTO macaddr8_data VALUES (17, '08002b:0102030405');
+INSERT INTO macaddr8_data VALUES (18, '08002b-0102030405');
+INSERT INTO macaddr8_data VALUES (19, '0800.2b01.0203.0405');
+INSERT INTO macaddr8_data VALUES (20, '08002b01:02030405');
+INSERT INTO macaddr8_data VALUES (21, '08002b0102030405');
+
+SELECT * FROM macaddr8_data;
+
+CREATE INDEX macaddr8_data_btree ON macaddr8_data USING btree (b);
+CREATE INDEX macaddr8_data_hash ON macaddr8_data USING hash (b);
+
+SELECT a, b, trunc(b) FROM macaddr8_data ORDER BY 2, 1;
+
+SELECT b < '08:00:2b:01:02:04' FROM macaddr8_data WHERE a = 1; -- true
+SELECT b > '08:00:2b:ff:fe:01:02:04' FROM macaddr8_data WHERE a = 1; -- false
+SELECT b > '08:00:2b:ff:fe:01:02:03' FROM macaddr8_data WHERE a = 1; -- false
+SELECT b::macaddr <= '08:00:2b:01:02:04' FROM macaddr8_data WHERE a = 1; -- true
+SELECT b::macaddr >= '08:00:2b:01:02:04' FROM macaddr8_data WHERE a = 1; -- false
+SELECT b = '08:00:2b:ff:fe:01:02:03' FROM macaddr8_data WHERE a = 1; -- true
+SELECT b::macaddr <> '08:00:2b:01:02:04'::macaddr FROM macaddr8_data WHERE a = 1; -- true
+SELECT b::macaddr <> '08:00:2b:01:02:03'::macaddr FROM macaddr8_data WHERE a = 1; -- false
+
+SELECT b < '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15; -- true
+SELECT b > '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15; -- false
+SELECT b > '08:00:2b:01:02:03:04:05' FROM macaddr8_data WHERE a = 15; -- false
+SELECT b <= '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15; -- true
+SELECT b >= '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15; -- false
+SELECT b = '08:00:2b:01:02:03:04:05' FROM macaddr8_data WHERE a = 15; -- true
+SELECT b <> '08:00:2b:01:02:03:04:06' FROM macaddr8_data WHERE a = 15; -- true
+SELECT b <> '08:00:2b:01:02:03:04:05' FROM macaddr8_data WHERE a = 15; -- false
+
+SELECT ~b FROM macaddr8_data;
+SELECT b & '00:00:00:ff:ff:ff' FROM macaddr8_data;
+SELECT b | '01:02:03:04:05:06' FROM macaddr8_data;
+
+DROP TABLE macaddr8_data;