From 223ce1438acf1b415677e509ef9ea02b96dcb1fc Mon Sep 17 00:00:00 2001 From: Aleksander Alekseev Date: Mon, 10 Mar 2025 09:35:28 +0300 Subject: [PATCH v1] Add reverse(bytea) function This allows converting between big-endian and little-endian binary strings, which works nicely with previous commits 760162fedb4f and 6da469badaff. Aleksander Alekseev, reviewed by TODO FIXME Discussion: TODO FIXME !!! BUMP CATVERSION !!! --- doc/src/sgml/func.sgml | 17 +++++++++++++++++ src/backend/utils/adt/varlena.c | 24 ++++++++++++++++++++++++ src/include/catalog/pg_proc.dat | 3 +++ src/test/regress/expected/strings.out | 21 +++++++++++++++++++++ src/test/regress/sql/strings.sql | 8 ++++++++ 5 files changed, 73 insertions(+) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 51dd8ad6571..2dde6e22799 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -4660,6 +4660,23 @@ SELECT format('Testing %3$s, %2$s, %s', 'one', 'two', 'three'); + + + + reverse + + reverse ( bytea ) + bytea + + + Reverses the order of the bytes in the binary string. + + + reverse('\xAABBCC' :: bytea) + \xCCBBAA + + + diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c index cdf185ea00b..4597e80e37c 100644 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@ -4153,6 +4153,30 @@ int8_bytea(PG_FUNCTION_ARGS) return int8send(fcinfo); } +/* + * Return reversed bytea + */ +Datum +bytea_reverse(PG_FUNCTION_ARGS) +{ + bytea *v = PG_GETARG_BYTEA_PP(0); + int len = VARSIZE_ANY_EXHDR(v); + const char *p = VARDATA_ANY(v); + const char *endp = p + len; + bytea *result; + char *dst; + + result = palloc(len + VARHDRSZ); + dst = (char *) VARDATA(result) + len; + SET_VARSIZE(result, len + VARHDRSZ); + + while (p < endp) + *(--dst) = *p++; + + PG_RETURN_BYTEA_P(result); +} + + /* * appendStringInfoText * diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index cede992b6e2..d460c55776f 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -1183,6 +1183,9 @@ { oid => '8582', descr => 'convert bytea to int8', proname => 'int8', prorettype => 'int8', proargtypes => 'bytea', prosrc => 'bytea_int8' }, +{ oid => '8583', descr => 'reverse bytea', + proname => 'reverse', prorettype => 'bytea', proargtypes => 'bytea', + prosrc => 'bytea_reverse' }, { oid => '449', descr => 'hash', proname => 'hashint2', prorettype => 'int4', proargtypes => 'int2', diff --git a/src/test/regress/expected/strings.out b/src/test/regress/expected/strings.out index f8cba9f5b24..c9f761f8332 100644 --- a/src/test/regress/expected/strings.out +++ b/src/test/regress/expected/strings.out @@ -2460,6 +2460,27 @@ SELECT '\x8000000000000000'::bytea::int8 AS "-9223372036854775808", -9223372036854775808 | 9223372036854775807 (1 row) +-- +-- reversing a bytea +-- +SELECT reverse(''::bytea); + reverse +--------- + \x +(1 row) + +SELECT reverse('\xAA'::bytea); + reverse +--------- + \xaa +(1 row) + +SELECT reverse('\xAABBCC'::bytea); + reverse +---------- + \xccbbaa +(1 row) + -- -- test behavior of escape_string_warning and standard_conforming_strings options -- diff --git a/src/test/regress/sql/strings.sql b/src/test/regress/sql/strings.sql index 4deb0683d57..5f1ca98edad 100644 --- a/src/test/regress/sql/strings.sql +++ b/src/test/regress/sql/strings.sql @@ -780,6 +780,14 @@ SELECT '\x80000000'::bytea::int4 AS "-2147483648", '\x7FFFFFFF'::bytea::int4 AS SELECT '\x8000000000000000'::bytea::int8 AS "-9223372036854775808", '\x7FFFFFFFFFFFFFFF'::bytea::int8 AS "9223372036854775807"; + +-- +-- reversing a bytea +-- +SELECT reverse(''::bytea); +SELECT reverse('\xAA'::bytea); +SELECT reverse('\xAABBCC'::bytea); + -- -- test behavior of escape_string_warning and standard_conforming_strings options -- -- 2.48.1