From 0697b23906adabccba41fa7bf19909eb98bdf0dd Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Thu, 13 Mar 2025 11:20:53 -0500 Subject: [PATCH] Add reverse(bytea). This commit introduces a function for reversing the order of the bytes in binary strings. Bumps catversion. Author: Aleksander Alekseev Discussion: https://postgr.es/m/CAJ7c6TMe0QVRuNssUArbMi0bJJK32%2BzNA3at5m3osrBQ25MHuw%40mail.gmail.com --- doc/src/sgml/func.sgml | 17 +++++++++++++++++ src/backend/utils/adt/varlena.c | 21 +++++++++++++++++++++ src/include/catalog/catversion.h | 2 +- src/include/catalog/pg_proc.dat | 3 +++ src/test/regress/expected/strings.out | 18 ++++++++++++++++++ src/test/regress/sql/strings.sql | 4 ++++ 6 files changed, 64 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 51dd8ad6571..1c3810e1a04 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('\xabcd'::bytea) + \xcdab + + + diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c index cdf185ea00b..95631eb2099 100644 --- a/src/backend/utils/adt/varlena.c +++ b/src/backend/utils/adt/varlena.c @@ -3398,6 +3398,27 @@ byteaSetBit(PG_FUNCTION_ARGS) PG_RETURN_BYTEA_P(res); } +/* + * Return reversed bytea + */ +Datum +bytea_reverse(PG_FUNCTION_ARGS) +{ + bytea *v = PG_GETARG_BYTEA_PP(0); + const char *p = VARDATA_ANY(v); + int len = VARSIZE_ANY_EXHDR(v); + const char *endp = p + len; + bytea *result = palloc(len + VARHDRSZ); + char *dst = (char *) VARDATA(result) + len; + + SET_VARSIZE(result, len + VARHDRSZ); + + while (p < endp) + *(--dst) = *p++; + + PG_RETURN_BYTEA_P(result); +} + /* text_name() * Converts a text type to a Name type. diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 2fa248e4ed4..d52944b1145 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202503111 +#define CATALOG_VERSION_NO 202503131 #endif diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 42e427f8fe8..890822eaf79 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -1518,6 +1518,9 @@ { oid => '6163', descr => 'number of set bits', proname => 'bit_count', prorettype => 'int8', proargtypes => 'bytea', prosrc => 'bytea_bit_count' }, +{ oid => '8694', descr => 'reverse bytea', + proname => 'reverse', prorettype => 'bytea', proargtypes => 'bytea', + prosrc => 'bytea_reverse' }, { oid => '725', proname => 'dist_pl', prorettype => 'float8', proargtypes => 'point line', diff --git a/src/test/regress/expected/strings.out b/src/test/regress/expected/strings.out index f8cba9f5b24..fbe7d7be71f 100644 --- a/src/test/regress/expected/strings.out +++ b/src/test/regress/expected/strings.out @@ -236,6 +236,24 @@ SELECT E'De\\678dBeEf'::bytea; ERROR: invalid input syntax for type bytea LINE 1: SELECT E'De\\678dBeEf'::bytea; ^ +SELECT reverse(''::bytea); + reverse +--------- + \x +(1 row) + +SELECT reverse('\xaa'::bytea); + reverse +--------- + \xaa +(1 row) + +SELECT reverse('\xabcd'::bytea); + reverse +--------- + \xcdab +(1 row) + SET bytea_output TO escape; SELECT E'\\xDeAdBeEf'::bytea; bytea diff --git a/src/test/regress/sql/strings.sql b/src/test/regress/sql/strings.sql index 4deb0683d57..ed054e6e99c 100644 --- a/src/test/regress/sql/strings.sql +++ b/src/test/regress/sql/strings.sql @@ -77,6 +77,10 @@ SELECT E'De\123dBeEf'::bytea; SELECT E'De\\123dBeEf'::bytea; SELECT E'De\\678dBeEf'::bytea; +SELECT reverse(''::bytea); +SELECT reverse('\xaa'::bytea); +SELECT reverse('\xabcd'::bytea); + SET bytea_output TO escape; SELECT E'\\xDeAdBeEf'::bytea; SELECT E'\\x De Ad Be Ef '::bytea; -- 2.30.2