Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)