Skip to content

Commit f9a0392

Browse files
committed
Add bit_xor aggregate function
This can be used as a checksum for unordered sets. bit_and and bit_or already exist. Author: Alexey Bashtanov <bashtanov@imap.cc> Reviewed-by: Ibrar Ahmed <ibrar.ahmad@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/9d4582ae-ecfc-3a13-2238-6ab5a37c1f41@imap.cc
1 parent 30b26df commit f9a0392

File tree

6 files changed

+73
-11
lines changed

6 files changed

+73
-11
lines changed

doc/src/sgml/func.sgml

+27
Original file line numberDiff line numberDiff line change
@@ -19224,6 +19224,33 @@ SELECT NULLIF(value, '(none)') ...
1922419224
<entry>Yes</entry>
1922519225
</row>
1922619226

19227+
<row>
19228+
<entry role="func_table_entry"><para role="func_signature">
19229+
<indexterm>
19230+
<primary>bit_xor</primary>
19231+
</indexterm>
19232+
<function>bit_xor</function> ( <type>smallint</type> )
19233+
<returnvalue>smallint</returnvalue>
19234+
</para>
19235+
<para role="func_signature">
19236+
<function>bit_xor</function> ( <type>integer</type> )
19237+
<returnvalue>integer</returnvalue>
19238+
</para>
19239+
<para role="func_signature">
19240+
<function>bit_xor</function> ( <type>bigint</type> )
19241+
<returnvalue>bigint</returnvalue>
19242+
</para>
19243+
<para role="func_signature">
19244+
<function>bit_xor</function> ( <type>bit</type> )
19245+
<returnvalue>bit</returnvalue>
19246+
</para>
19247+
<para>
19248+
Computes the bitwise exclusive OR of all non-null input values.
19249+
Can be useful as a checksum for an unordered set of values.
19250+
</para></entry>
19251+
<entry>Yes</entry>
19252+
</row>
19253+
1922719254
<row>
1922819255
<entry role="func_table_entry"><para role="func_signature">
1922919256
<indexterm>

src/include/catalog/catversion.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/* yyyymmddN */
56-
#define CATALOG_VERSION_NO 202103032
56+
#define CATALOG_VERSION_NO 202103061
5757

5858
#endif

src/include/catalog/pg_aggregate.dat

+8
Original file line numberDiff line numberDiff line change
@@ -505,18 +505,26 @@
505505
aggcombinefn => 'int2and', aggtranstype => 'int2' },
506506
{ aggfnoid => 'bit_or(int2)', aggtransfn => 'int2or', aggcombinefn => 'int2or',
507507
aggtranstype => 'int2' },
508+
{ aggfnoid => 'bit_xor(int2)', aggtransfn => 'int2xor', aggcombinefn => 'int2xor',
509+
aggtranstype => 'int2' },
508510
{ aggfnoid => 'bit_and(int4)', aggtransfn => 'int4and',
509511
aggcombinefn => 'int4and', aggtranstype => 'int4' },
510512
{ aggfnoid => 'bit_or(int4)', aggtransfn => 'int4or', aggcombinefn => 'int4or',
511513
aggtranstype => 'int4' },
514+
{ aggfnoid => 'bit_xor(int4)', aggtransfn => 'int4xor', aggcombinefn => 'int4xor',
515+
aggtranstype => 'int4' },
512516
{ aggfnoid => 'bit_and(int8)', aggtransfn => 'int8and',
513517
aggcombinefn => 'int8and', aggtranstype => 'int8' },
514518
{ aggfnoid => 'bit_or(int8)', aggtransfn => 'int8or', aggcombinefn => 'int8or',
515519
aggtranstype => 'int8' },
520+
{ aggfnoid => 'bit_xor(int8)', aggtransfn => 'int8xor', aggcombinefn => 'int8xor',
521+
aggtranstype => 'int8' },
516522
{ aggfnoid => 'bit_and(bit)', aggtransfn => 'bitand', aggcombinefn => 'bitand',
517523
aggtranstype => 'bit' },
518524
{ aggfnoid => 'bit_or(bit)', aggtransfn => 'bitor', aggcombinefn => 'bitor',
519525
aggtranstype => 'bit' },
526+
{ aggfnoid => 'bit_xor(bit)', aggtransfn => 'bitxor', aggcombinefn => 'bitxor',
527+
aggtranstype => 'bit' },
520528

521529
# xml
522530
{ aggfnoid => 'xmlagg', aggtransfn => 'xmlconcat2', aggtranstype => 'xml' },

src/include/catalog/pg_proc.dat

+12
Original file line numberDiff line numberDiff line change
@@ -7995,24 +7995,36 @@
79957995
{ oid => '2237', descr => 'bitwise-or smallint aggregate',
79967996
proname => 'bit_or', prokind => 'a', proisstrict => 'f', prorettype => 'int2',
79977997
proargtypes => 'int2', prosrc => 'aggregate_dummy' },
7998+
{ oid => '8452', descr => 'bitwise-xor smallint aggregate',
7999+
proname => 'bit_xor', prokind => 'a', proisstrict => 'f', prorettype => 'int2',
8000+
proargtypes => 'int2', prosrc => 'aggregate_dummy' },
79988001
{ oid => '2238', descr => 'bitwise-and integer aggregate',
79998002
proname => 'bit_and', prokind => 'a', proisstrict => 'f',
80008003
prorettype => 'int4', proargtypes => 'int4', prosrc => 'aggregate_dummy' },
80018004
{ oid => '2239', descr => 'bitwise-or integer aggregate',
80028005
proname => 'bit_or', prokind => 'a', proisstrict => 'f', prorettype => 'int4',
80038006
proargtypes => 'int4', prosrc => 'aggregate_dummy' },
8007+
{ oid => '8453', descr => 'bitwise-xor integer aggregate',
8008+
proname => 'bit_xor', prokind => 'a', proisstrict => 'f', prorettype => 'int4',
8009+
proargtypes => 'int4', prosrc => 'aggregate_dummy' },
80048010
{ oid => '2240', descr => 'bitwise-and bigint aggregate',
80058011
proname => 'bit_and', prokind => 'a', proisstrict => 'f',
80068012
prorettype => 'int8', proargtypes => 'int8', prosrc => 'aggregate_dummy' },
80078013
{ oid => '2241', descr => 'bitwise-or bigint aggregate',
80088014
proname => 'bit_or', prokind => 'a', proisstrict => 'f', prorettype => 'int8',
80098015
proargtypes => 'int8', prosrc => 'aggregate_dummy' },
8016+
{ oid => '8454', descr => 'bitwise-xor bigint aggregate',
8017+
proname => 'bit_xor', prokind => 'a', proisstrict => 'f', prorettype => 'int8',
8018+
proargtypes => 'int8', prosrc => 'aggregate_dummy' },
80108019
{ oid => '2242', descr => 'bitwise-and bit aggregate',
80118020
proname => 'bit_and', prokind => 'a', proisstrict => 'f', prorettype => 'bit',
80128021
proargtypes => 'bit', prosrc => 'aggregate_dummy' },
80138022
{ oid => '2243', descr => 'bitwise-or bit aggregate',
80148023
proname => 'bit_or', prokind => 'a', proisstrict => 'f', prorettype => 'bit',
80158024
proargtypes => 'bit', prosrc => 'aggregate_dummy' },
8025+
{ oid => '8455', descr => 'bitwise-xor bit aggregate',
8026+
proname => 'bit_xor', prokind => 'a', proisstrict => 'f', prorettype => 'bit',
8027+
proargtypes => 'bit', prosrc => 'aggregate_dummy' },
80168028

80178029
# formerly-missing interval + datetime operators
80188030
{ oid => '2546',

src/test/regress/expected/aggregates.out

+15-8
Original file line numberDiff line numberDiff line change
@@ -742,11 +742,12 @@ CREATE TEMPORARY TABLE bitwise_test(
742742
-- empty case
743743
SELECT
744744
BIT_AND(i2) AS "?",
745-
BIT_OR(i4) AS "?"
745+
BIT_OR(i4) AS "?",
746+
BIT_XOR(i8) AS "?"
746747
FROM bitwise_test;
747-
? | ?
748-
---+---
749-
|
748+
? | ? | ?
749+
---+---+---
750+
| |
750751
(1 row)
751752

752753
COPY bitwise_test FROM STDIN NULL 'null';
@@ -762,11 +763,17 @@ SELECT
762763
BIT_OR(i8) AS "7",
763764
BIT_OR(i) AS "?",
764765
BIT_OR(x) AS "7",
765-
BIT_OR(y) AS "1101"
766+
BIT_OR(y) AS "1101",
767+
BIT_XOR(i2) AS "5",
768+
BIT_XOR(i4) AS "5",
769+
BIT_XOR(i8) AS "5",
770+
BIT_XOR(i) AS "?",
771+
BIT_XOR(x) AS "7",
772+
BIT_XOR(y) AS "1101"
766773
FROM bitwise_test;
767-
1 | 1 | 1 | ? | 0 | 0100 | 7 | 7 | 7 | ? | 7 | 1101
768-
---+---+---+---+---+------+---+---+---+---+---+------
769-
1 | 1 | 1 | 1 | 0 | 0100 | 7 | 7 | 7 | 3 | 7 | 1101
774+
1 | 1 | 1 | ? | 0 | 0100 | 7 | 7 | 7 | ? | 7 | 1101 | 5 | 5 | 5 | ? | 7 | 1101
775+
---+---+---+---+---+------+---+---+---+---+---+------+---+---+---+---+---+------
776+
1 | 1 | 1 | 1 | 0 | 0100 | 7 | 7 | 7 | 3 | 7 | 1101 | 5 | 5 | 5 | 2 | 7 | 1101
770777
(1 row)
771778

772779
--

src/test/regress/sql/aggregates.sql

+10-2
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,8 @@ CREATE TEMPORARY TABLE bitwise_test(
212212
-- empty case
213213
SELECT
214214
BIT_AND(i2) AS "?",
215-
BIT_OR(i4) AS "?"
215+
BIT_OR(i4) AS "?",
216+
BIT_XOR(i8) AS "?"
216217
FROM bitwise_test;
217218

218219
COPY bitwise_test FROM STDIN NULL 'null';
@@ -234,7 +235,14 @@ SELECT
234235
BIT_OR(i8) AS "7",
235236
BIT_OR(i) AS "?",
236237
BIT_OR(x) AS "7",
237-
BIT_OR(y) AS "1101"
238+
BIT_OR(y) AS "1101",
239+
240+
BIT_XOR(i2) AS "5",
241+
BIT_XOR(i4) AS "5",
242+
BIT_XOR(i8) AS "5",
243+
BIT_XOR(i) AS "?",
244+
BIT_XOR(x) AS "7",
245+
BIT_XOR(y) AS "1101"
238246
FROM bitwise_test;
239247

240248
--

0 commit comments

Comments
 (0)