Skip to content

Commit cc53a1e

Browse files
committed
Add bitwise AND, OR, and NOT operators for macaddr data type.
Brendan Jurd, reviewed by Fujii Masao
1 parent 4f42b54 commit cc53a1e

File tree

8 files changed

+122
-2
lines changed

8 files changed

+122
-2
lines changed

doc/src/sgml/func.sgml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8300,7 +8300,9 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
83008300
<para>
83018301
The <type>macaddr</type> type also supports the standard relational
83028302
operators (<literal>&gt;</literal>, <literal>&lt;=</literal>, etc.) for
8303-
lexicographical ordering.
8303+
lexicographical ordering, and the bitwise arithmetic operators
8304+
(<literal>~</literal>, <literal>&amp;</literal> and <literal>|</literal>)
8305+
for NOT, AND and OR.
83048306
</para>
83058307

83068308
</sect1>

src/backend/utils/adt/mac.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,59 @@ hashmacaddr(PG_FUNCTION_ARGS)
241241
return hash_any((unsigned char *) key, sizeof(macaddr));
242242
}
243243

244+
/*
245+
* Arithmetic functions: bitwise NOT, AND, OR.
246+
*/
247+
Datum
248+
macaddr_not(PG_FUNCTION_ARGS)
249+
{
250+
macaddr *addr = PG_GETARG_MACADDR_P(0);
251+
macaddr *result;
252+
253+
result = (macaddr *) palloc(sizeof(macaddr));
254+
result->a = ~addr->a;
255+
result->b = ~addr->b;
256+
result->c = ~addr->c;
257+
result->d = ~addr->d;
258+
result->e = ~addr->e;
259+
result->f = ~addr->f;
260+
PG_RETURN_MACADDR_P(result);
261+
}
262+
263+
Datum
264+
macaddr_and(PG_FUNCTION_ARGS)
265+
{
266+
macaddr *addr1 = PG_GETARG_MACADDR_P(0);
267+
macaddr *addr2 = PG_GETARG_MACADDR_P(1);
268+
macaddr *result;
269+
270+
result = (macaddr *) palloc(sizeof(macaddr));
271+
result->a = addr1->a & addr2->a;
272+
result->b = addr1->b & addr2->b;
273+
result->c = addr1->c & addr2->c;
274+
result->d = addr1->d & addr2->d;
275+
result->e = addr1->e & addr2->e;
276+
result->f = addr1->f & addr2->f;
277+
PG_RETURN_MACADDR_P(result);
278+
}
279+
280+
Datum
281+
macaddr_or(PG_FUNCTION_ARGS)
282+
{
283+
macaddr *addr1 = PG_GETARG_MACADDR_P(0);
284+
macaddr *addr2 = PG_GETARG_MACADDR_P(1);
285+
macaddr *result;
286+
287+
result = (macaddr *) palloc(sizeof(macaddr));
288+
result->a = addr1->a | addr2->a;
289+
result->b = addr1->b | addr2->b;
290+
result->c = addr1->c | addr2->c;
291+
result->d = addr1->d | addr2->d;
292+
result->e = addr1->e | addr2->e;
293+
result->f = addr1->f | addr2->f;
294+
PG_RETURN_MACADDR_P(result);
295+
}
296+
244297
/*
245298
* Truncation function to allow comparing mac manufacturers.
246299
* From suggestion by Alex Pilosov <alex@pilosoft.com>

src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/* yyyymmddN */
56-
#define CATALOG_VERSION_NO 201201191
56+
#define CATALOG_VERSION_NO 201201192
5757

5858
#endif

src/include/catalog/pg_operator.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,13 @@ DESCR("greater than");
11161116
DATA(insert OID = 1225 ( ">=" PGNSP PGUID b f f 829 829 16 1223 1222 macaddr_ge scalargtsel scalargtjoinsel ));
11171117
DESCR("greater than or equal");
11181118

1119+
DATA(insert OID = 3147 ( "~" PGNSP PGUID l f f 0 829 829 0 0 macaddr_not - - ));
1120+
DESCR("bitwise not");
1121+
DATA(insert OID = 3148 ( "&" PGNSP PGUID b f f 829 829 829 0 0 macaddr_and - - ));
1122+
DESCR("bitwise and");
1123+
DATA(insert OID = 3149 ( "|" PGNSP PGUID b f f 829 829 829 0 0 macaddr_or - - ));
1124+
DESCR("bitwise or");
1125+
11191126
/* INET type (these also support CIDR via implicit cast) */
11201127
DATA(insert OID = 1201 ( "=" PGNSP PGUID b t t 869 869 16 1201 1202 network_eq eqsel eqjoinsel ));
11211128
DESCR("equal");

src/include/catalog/pg_proc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2039,6 +2039,9 @@ DATA(insert OID = 834 ( macaddr_ge PGNSP PGUID 12 1 0 0 0 f f f t f i 2 0 16
20392039
DATA(insert OID = 835 ( macaddr_ne PGNSP PGUID 12 1 0 0 0 f f f t f i 2 0 16 "829 829" _null_ _null_ _null_ _null_ macaddr_ne _null_ _null_ _null_ ));
20402040
DATA(insert OID = 836 ( macaddr_cmp PGNSP PGUID 12 1 0 0 0 f f f t f i 2 0 23 "829 829" _null_ _null_ _null_ _null_ macaddr_cmp _null_ _null_ _null_ ));
20412041
DESCR("less-equal-greater");
2042+
DATA(insert OID = 3144 ( macaddr_not PGNSP PGUID 12 1 0 0 0 f f f t f i 1 0 829 "829" _null_ _null_ _null_ _null_ macaddr_not _null_ _null_ _null_ ));
2043+
DATA(insert OID = 3145 ( macaddr_and PGNSP PGUID 12 1 0 0 0 f f f t f i 2 0 829 "829 829" _null_ _null_ _null_ _null_ macaddr_and _null_ _null_ _null_ ));
2044+
DATA(insert OID = 3146 ( macaddr_or PGNSP PGUID 12 1 0 0 0 f f f t f i 2 0 829 "829 829" _null_ _null_ _null_ _null_ macaddr_or _null_ _null_ _null_ ));
20422045

20432046
/* for inet type support */
20442047
DATA(insert OID = 910 ( inet_in PGNSP PGUID 12 1 0 0 0 f f f t f i 1 0 869 "2275" _null_ _null_ _null_ _null_ inet_in _null_ _null_ _null_ ));

src/include/utils/builtins.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,9 @@ extern Datum macaddr_eq(PG_FUNCTION_ARGS);
900900
extern Datum macaddr_ge(PG_FUNCTION_ARGS);
901901
extern Datum macaddr_gt(PG_FUNCTION_ARGS);
902902
extern Datum macaddr_ne(PG_FUNCTION_ARGS);
903+
extern Datum macaddr_not(PG_FUNCTION_ARGS);
904+
extern Datum macaddr_and(PG_FUNCTION_ARGS);
905+
extern Datum macaddr_or(PG_FUNCTION_ARGS);
903906
extern Datum macaddr_trunc(PG_FUNCTION_ARGS);
904907
extern Datum hashmacaddr(PG_FUNCTION_ARGS);
905908

src/test/regress/expected/macaddr.out

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,52 @@ SELECT b <> '08:00:2b:01:02:03' FROM macaddr_data WHERE a = 1; -- false
103103
f
104104
(1 row)
105105

106+
SELECT ~b FROM macaddr_data;
107+
?column?
108+
-------------------
109+
f7:ff:d4:fe:fd:fc
110+
f7:ff:d4:fe:fd:fc
111+
f7:ff:d4:fe:fd:fc
112+
f7:ff:d4:fe:fd:fc
113+
f7:ff:d4:fe:fd:fc
114+
f7:ff:d4:fe:fd:fc
115+
f7:ff:d4:fe:fd:fb
116+
f7:ff:d4:fe:fd:fd
117+
f7:ff:d5:fe:fd:fc
118+
f7:ff:d3:fe:fd:fc
119+
f7:ff:d5:fe:fd:fb
120+
(11 rows)
121+
122+
SELECT b & '00:00:00:ff:ff:ff' FROM macaddr_data;
123+
?column?
124+
-------------------
125+
00:00:00:01:02:03
126+
00:00:00:01:02:03
127+
00:00:00:01:02:03
128+
00:00:00:01:02:03
129+
00:00:00:01:02:03
130+
00:00:00:01:02:03
131+
00:00:00:01:02:04
132+
00:00:00:01:02:02
133+
00:00:00:01:02:03
134+
00:00:00:01:02:03
135+
00:00:00:01:02:04
136+
(11 rows)
137+
138+
SELECT b | '01:02:03:04:05:06' FROM macaddr_data;
139+
?column?
140+
-------------------
141+
09:02:2b:05:07:07
142+
09:02:2b:05:07:07
143+
09:02:2b:05:07:07
144+
09:02:2b:05:07:07
145+
09:02:2b:05:07:07
146+
09:02:2b:05:07:07
147+
09:02:2b:05:07:06
148+
09:02:2b:05:07:06
149+
09:02:2b:05:07:07
150+
09:02:2f:05:07:07
151+
09:02:2b:05:07:06
152+
(11 rows)
153+
106154
DROP TABLE macaddr_data;

src/test/regress/sql/macaddr.sql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,8 @@ SELECT b = '08:00:2b:01:02:03' FROM macaddr_data WHERE a = 1; -- true
3535
SELECT b <> '08:00:2b:01:02:04' FROM macaddr_data WHERE a = 1; -- true
3636
SELECT b <> '08:00:2b:01:02:03' FROM macaddr_data WHERE a = 1; -- false
3737

38+
SELECT ~b FROM macaddr_data;
39+
SELECT b & '00:00:00:ff:ff:ff' FROM macaddr_data;
40+
SELECT b | '01:02:03:04:05:06' FROM macaddr_data;
41+
3842
DROP TABLE macaddr_data;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy