Commit f9a0392e authored by Peter Eisentraut's avatar Peter Eisentraut

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: default avatarIbrar Ahmed <ibrar.ahmad@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/9d4582ae-ecfc-3a13-2238-6ab5a37c1f41@imap.cc
parent 30b26dfa
...@@ -19224,6 +19224,33 @@ SELECT NULLIF(value, '(none)') ... ...@@ -19224,6 +19224,33 @@ SELECT NULLIF(value, '(none)') ...
<entry>Yes</entry> <entry>Yes</entry>
</row> </row>
<row>
<entry role="func_table_entry"><para role="func_signature">
<indexterm>
<primary>bit_xor</primary>
</indexterm>
<function>bit_xor</function> ( <type>smallint</type> )
<returnvalue>smallint</returnvalue>
</para>
<para role="func_signature">
<function>bit_xor</function> ( <type>integer</type> )
<returnvalue>integer</returnvalue>
</para>
<para role="func_signature">
<function>bit_xor</function> ( <type>bigint</type> )
<returnvalue>bigint</returnvalue>
</para>
<para role="func_signature">
<function>bit_xor</function> ( <type>bit</type> )
<returnvalue>bit</returnvalue>
</para>
<para>
Computes the bitwise exclusive OR of all non-null input values.
Can be useful as a checksum for an unordered set of values.
</para></entry>
<entry>Yes</entry>
</row>
<row> <row>
<entry role="func_table_entry"><para role="func_signature"> <entry role="func_table_entry"><para role="func_signature">
<indexterm> <indexterm>
......
...@@ -53,6 +53,6 @@ ...@@ -53,6 +53,6 @@
*/ */
/* yyyymmddN */ /* yyyymmddN */
#define CATALOG_VERSION_NO 202103032 #define CATALOG_VERSION_NO 202103061
#endif #endif
...@@ -505,18 +505,26 @@ ...@@ -505,18 +505,26 @@
aggcombinefn => 'int2and', aggtranstype => 'int2' }, aggcombinefn => 'int2and', aggtranstype => 'int2' },
{ aggfnoid => 'bit_or(int2)', aggtransfn => 'int2or', aggcombinefn => 'int2or', { aggfnoid => 'bit_or(int2)', aggtransfn => 'int2or', aggcombinefn => 'int2or',
aggtranstype => 'int2' }, aggtranstype => 'int2' },
{ aggfnoid => 'bit_xor(int2)', aggtransfn => 'int2xor', aggcombinefn => 'int2xor',
aggtranstype => 'int2' },
{ aggfnoid => 'bit_and(int4)', aggtransfn => 'int4and', { aggfnoid => 'bit_and(int4)', aggtransfn => 'int4and',
aggcombinefn => 'int4and', aggtranstype => 'int4' }, aggcombinefn => 'int4and', aggtranstype => 'int4' },
{ aggfnoid => 'bit_or(int4)', aggtransfn => 'int4or', aggcombinefn => 'int4or', { aggfnoid => 'bit_or(int4)', aggtransfn => 'int4or', aggcombinefn => 'int4or',
aggtranstype => 'int4' }, aggtranstype => 'int4' },
{ aggfnoid => 'bit_xor(int4)', aggtransfn => 'int4xor', aggcombinefn => 'int4xor',
aggtranstype => 'int4' },
{ aggfnoid => 'bit_and(int8)', aggtransfn => 'int8and', { aggfnoid => 'bit_and(int8)', aggtransfn => 'int8and',
aggcombinefn => 'int8and', aggtranstype => 'int8' }, aggcombinefn => 'int8and', aggtranstype => 'int8' },
{ aggfnoid => 'bit_or(int8)', aggtransfn => 'int8or', aggcombinefn => 'int8or', { aggfnoid => 'bit_or(int8)', aggtransfn => 'int8or', aggcombinefn => 'int8or',
aggtranstype => 'int8' }, aggtranstype => 'int8' },
{ aggfnoid => 'bit_xor(int8)', aggtransfn => 'int8xor', aggcombinefn => 'int8xor',
aggtranstype => 'int8' },
{ aggfnoid => 'bit_and(bit)', aggtransfn => 'bitand', aggcombinefn => 'bitand', { aggfnoid => 'bit_and(bit)', aggtransfn => 'bitand', aggcombinefn => 'bitand',
aggtranstype => 'bit' }, aggtranstype => 'bit' },
{ aggfnoid => 'bit_or(bit)', aggtransfn => 'bitor', aggcombinefn => 'bitor', { aggfnoid => 'bit_or(bit)', aggtransfn => 'bitor', aggcombinefn => 'bitor',
aggtranstype => 'bit' }, aggtranstype => 'bit' },
{ aggfnoid => 'bit_xor(bit)', aggtransfn => 'bitxor', aggcombinefn => 'bitxor',
aggtranstype => 'bit' },
# xml # xml
{ aggfnoid => 'xmlagg', aggtransfn => 'xmlconcat2', aggtranstype => 'xml' }, { aggfnoid => 'xmlagg', aggtransfn => 'xmlconcat2', aggtranstype => 'xml' },
......
...@@ -7995,24 +7995,36 @@ ...@@ -7995,24 +7995,36 @@
{ oid => '2237', descr => 'bitwise-or smallint aggregate', { oid => '2237', descr => 'bitwise-or smallint aggregate',
proname => 'bit_or', prokind => 'a', proisstrict => 'f', prorettype => 'int2', proname => 'bit_or', prokind => 'a', proisstrict => 'f', prorettype => 'int2',
proargtypes => 'int2', prosrc => 'aggregate_dummy' }, proargtypes => 'int2', prosrc => 'aggregate_dummy' },
{ oid => '8452', descr => 'bitwise-xor smallint aggregate',
proname => 'bit_xor', prokind => 'a', proisstrict => 'f', prorettype => 'int2',
proargtypes => 'int2', prosrc => 'aggregate_dummy' },
{ oid => '2238', descr => 'bitwise-and integer aggregate', { oid => '2238', descr => 'bitwise-and integer aggregate',
proname => 'bit_and', prokind => 'a', proisstrict => 'f', proname => 'bit_and', prokind => 'a', proisstrict => 'f',
prorettype => 'int4', proargtypes => 'int4', prosrc => 'aggregate_dummy' }, prorettype => 'int4', proargtypes => 'int4', prosrc => 'aggregate_dummy' },
{ oid => '2239', descr => 'bitwise-or integer aggregate', { oid => '2239', descr => 'bitwise-or integer aggregate',
proname => 'bit_or', prokind => 'a', proisstrict => 'f', prorettype => 'int4', proname => 'bit_or', prokind => 'a', proisstrict => 'f', prorettype => 'int4',
proargtypes => 'int4', prosrc => 'aggregate_dummy' }, proargtypes => 'int4', prosrc => 'aggregate_dummy' },
{ oid => '8453', descr => 'bitwise-xor integer aggregate',
proname => 'bit_xor', prokind => 'a', proisstrict => 'f', prorettype => 'int4',
proargtypes => 'int4', prosrc => 'aggregate_dummy' },
{ oid => '2240', descr => 'bitwise-and bigint aggregate', { oid => '2240', descr => 'bitwise-and bigint aggregate',
proname => 'bit_and', prokind => 'a', proisstrict => 'f', proname => 'bit_and', prokind => 'a', proisstrict => 'f',
prorettype => 'int8', proargtypes => 'int8', prosrc => 'aggregate_dummy' }, prorettype => 'int8', proargtypes => 'int8', prosrc => 'aggregate_dummy' },
{ oid => '2241', descr => 'bitwise-or bigint aggregate', { oid => '2241', descr => 'bitwise-or bigint aggregate',
proname => 'bit_or', prokind => 'a', proisstrict => 'f', prorettype => 'int8', proname => 'bit_or', prokind => 'a', proisstrict => 'f', prorettype => 'int8',
proargtypes => 'int8', prosrc => 'aggregate_dummy' }, proargtypes => 'int8', prosrc => 'aggregate_dummy' },
{ oid => '8454', descr => 'bitwise-xor bigint aggregate',
proname => 'bit_xor', prokind => 'a', proisstrict => 'f', prorettype => 'int8',
proargtypes => 'int8', prosrc => 'aggregate_dummy' },
{ oid => '2242', descr => 'bitwise-and bit aggregate', { oid => '2242', descr => 'bitwise-and bit aggregate',
proname => 'bit_and', prokind => 'a', proisstrict => 'f', prorettype => 'bit', proname => 'bit_and', prokind => 'a', proisstrict => 'f', prorettype => 'bit',
proargtypes => 'bit', prosrc => 'aggregate_dummy' }, proargtypes => 'bit', prosrc => 'aggregate_dummy' },
{ oid => '2243', descr => 'bitwise-or bit aggregate', { oid => '2243', descr => 'bitwise-or bit aggregate',
proname => 'bit_or', prokind => 'a', proisstrict => 'f', prorettype => 'bit', proname => 'bit_or', prokind => 'a', proisstrict => 'f', prorettype => 'bit',
proargtypes => 'bit', prosrc => 'aggregate_dummy' }, proargtypes => 'bit', prosrc => 'aggregate_dummy' },
{ oid => '8455', descr => 'bitwise-xor bit aggregate',
proname => 'bit_xor', prokind => 'a', proisstrict => 'f', prorettype => 'bit',
proargtypes => 'bit', prosrc => 'aggregate_dummy' },
# formerly-missing interval + datetime operators # formerly-missing interval + datetime operators
{ oid => '2546', { oid => '2546',
......
...@@ -742,11 +742,12 @@ CREATE TEMPORARY TABLE bitwise_test( ...@@ -742,11 +742,12 @@ CREATE TEMPORARY TABLE bitwise_test(
-- empty case -- empty case
SELECT SELECT
BIT_AND(i2) AS "?", BIT_AND(i2) AS "?",
BIT_OR(i4) AS "?" BIT_OR(i4) AS "?",
BIT_XOR(i8) AS "?"
FROM bitwise_test; FROM bitwise_test;
? | ? ? | ? | ?
---+--- ---+---+---
| | |
(1 row) (1 row)
COPY bitwise_test FROM STDIN NULL 'null'; COPY bitwise_test FROM STDIN NULL 'null';
...@@ -762,11 +763,17 @@ SELECT ...@@ -762,11 +763,17 @@ SELECT
BIT_OR(i8) AS "7", BIT_OR(i8) AS "7",
BIT_OR(i) AS "?", BIT_OR(i) AS "?",
BIT_OR(x) AS "7", BIT_OR(x) AS "7",
BIT_OR(y) AS "1101" BIT_OR(y) AS "1101",
BIT_XOR(i2) AS "5",
BIT_XOR(i4) AS "5",
BIT_XOR(i8) AS "5",
BIT_XOR(i) AS "?",
BIT_XOR(x) AS "7",
BIT_XOR(y) AS "1101"
FROM bitwise_test; FROM bitwise_test;
1 | 1 | 1 | ? | 0 | 0100 | 7 | 7 | 7 | ? | 7 | 1101 1 | 1 | 1 | ? | 0 | 0100 | 7 | 7 | 7 | ? | 7 | 1101 | 5 | 5 | 5 | ? | 7 | 1101
---+---+---+---+---+------+---+---+---+---+---+------ ---+---+---+---+---+------+---+---+---+---+---+------+---+---+---+---+---+------
1 | 1 | 1 | 1 | 0 | 0100 | 7 | 7 | 7 | 3 | 7 | 1101 1 | 1 | 1 | 1 | 0 | 0100 | 7 | 7 | 7 | 3 | 7 | 1101 | 5 | 5 | 5 | 2 | 7 | 1101
(1 row) (1 row)
-- --
......
...@@ -212,7 +212,8 @@ CREATE TEMPORARY TABLE bitwise_test( ...@@ -212,7 +212,8 @@ CREATE TEMPORARY TABLE bitwise_test(
-- empty case -- empty case
SELECT SELECT
BIT_AND(i2) AS "?", BIT_AND(i2) AS "?",
BIT_OR(i4) AS "?" BIT_OR(i4) AS "?",
BIT_XOR(i8) AS "?"
FROM bitwise_test; FROM bitwise_test;
COPY bitwise_test FROM STDIN NULL 'null'; COPY bitwise_test FROM STDIN NULL 'null';
...@@ -234,7 +235,14 @@ SELECT ...@@ -234,7 +235,14 @@ SELECT
BIT_OR(i8) AS "7", BIT_OR(i8) AS "7",
BIT_OR(i) AS "?", BIT_OR(i) AS "?",
BIT_OR(x) AS "7", BIT_OR(x) AS "7",
BIT_OR(y) AS "1101" BIT_OR(y) AS "1101",
BIT_XOR(i2) AS "5",
BIT_XOR(i4) AS "5",
BIT_XOR(i8) AS "5",
BIT_XOR(i) AS "?",
BIT_XOR(x) AS "7",
BIT_XOR(y) AS "1101"
FROM bitwise_test; FROM bitwise_test;
-- --
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment