mirror of
https://github.com/postgres/postgres.git
synced 2025-06-17 17:02:08 +03:00
Add min and max aggregates for bytea type.
Similar to a0f1fce80
, although we chose to duplicate logic
rather than invoke byteacmp, primarily to avoid repeat detoasting.
Marat Buharov, Aleksander Alekseev
Discussion: https://postgr.es/m/CAPCEVGXiASjodos4P8pgyV7ixfVn-ZgG9YyiRZRbVqbGmfuDyg@mail.gmail.com
This commit is contained in:
@ -22125,7 +22125,7 @@ SELECT NULLIF(value, '(none)') ...
|
|||||||
<para>
|
<para>
|
||||||
Computes the maximum of the non-null input
|
Computes the maximum of the non-null input
|
||||||
values. Available for any numeric, string, date/time, or enum type,
|
values. Available for any numeric, string, date/time, or enum type,
|
||||||
as well as <type>inet</type>, <type>interval</type>,
|
as well as <type>bytea</type>, <type>inet</type>, <type>interval</type>,
|
||||||
<type>money</type>, <type>oid</type>, <type>pg_lsn</type>,
|
<type>money</type>, <type>oid</type>, <type>pg_lsn</type>,
|
||||||
<type>tid</type>, <type>xid8</type>,
|
<type>tid</type>, <type>xid8</type>,
|
||||||
and also arrays and composite types containing sortable data types.
|
and also arrays and composite types containing sortable data types.
|
||||||
@ -22144,7 +22144,7 @@ SELECT NULLIF(value, '(none)') ...
|
|||||||
<para>
|
<para>
|
||||||
Computes the minimum of the non-null input
|
Computes the minimum of the non-null input
|
||||||
values. Available for any numeric, string, date/time, or enum type,
|
values. Available for any numeric, string, date/time, or enum type,
|
||||||
as well as <type>inet</type>, <type>interval</type>,
|
as well as <type>bytea</type>, <type>inet</type>, <type>interval</type>,
|
||||||
<type>money</type>, <type>oid</type>, <type>pg_lsn</type>,
|
<type>money</type>, <type>oid</type>, <type>pg_lsn</type>,
|
||||||
<type>tid</type>, <type>xid8</type>,
|
<type>tid</type>, <type>xid8</type>,
|
||||||
and also arrays and composite types containing sortable data types.
|
and also arrays and composite types containing sortable data types.
|
||||||
|
@ -3931,6 +3931,44 @@ byteacmp(PG_FUNCTION_ARGS)
|
|||||||
PG_RETURN_INT32(cmp);
|
PG_RETURN_INT32(cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Datum
|
||||||
|
bytea_larger(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
bytea *arg1 = PG_GETARG_BYTEA_PP(0);
|
||||||
|
bytea *arg2 = PG_GETARG_BYTEA_PP(1);
|
||||||
|
bytea *result;
|
||||||
|
int len1,
|
||||||
|
len2;
|
||||||
|
int cmp;
|
||||||
|
|
||||||
|
len1 = VARSIZE_ANY_EXHDR(arg1);
|
||||||
|
len2 = VARSIZE_ANY_EXHDR(arg2);
|
||||||
|
|
||||||
|
cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
|
||||||
|
result = ((cmp > 0) || ((cmp == 0) && (len1 > len2)) ? arg1 : arg2);
|
||||||
|
|
||||||
|
PG_RETURN_BYTEA_P(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
Datum
|
||||||
|
bytea_smaller(PG_FUNCTION_ARGS)
|
||||||
|
{
|
||||||
|
bytea *arg1 = PG_GETARG_BYTEA_PP(0);
|
||||||
|
bytea *arg2 = PG_GETARG_BYTEA_PP(1);
|
||||||
|
bytea *result;
|
||||||
|
int len1,
|
||||||
|
len2;
|
||||||
|
int cmp;
|
||||||
|
|
||||||
|
len1 = VARSIZE_ANY_EXHDR(arg1);
|
||||||
|
len2 = VARSIZE_ANY_EXHDR(arg2);
|
||||||
|
|
||||||
|
cmp = memcmp(VARDATA_ANY(arg1), VARDATA_ANY(arg2), Min(len1, len2));
|
||||||
|
result = ((cmp < 0) || ((cmp == 0) && (len1 < len2)) ? arg1 : arg2);
|
||||||
|
|
||||||
|
PG_RETURN_BYTEA_P(result);
|
||||||
|
}
|
||||||
|
|
||||||
Datum
|
Datum
|
||||||
bytea_sortsupport(PG_FUNCTION_ARGS)
|
bytea_sortsupport(PG_FUNCTION_ARGS)
|
||||||
{
|
{
|
||||||
|
@ -57,6 +57,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* yyyymmddN */
|
/* yyyymmddN */
|
||||||
#define CATALOG_VERSION_NO 202410021
|
#define CATALOG_VERSION_NO 202410081
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -161,6 +161,9 @@
|
|||||||
{ aggfnoid => 'max(xid8)', aggtransfn => 'xid8_larger',
|
{ aggfnoid => 'max(xid8)', aggtransfn => 'xid8_larger',
|
||||||
aggcombinefn => 'xid8_larger', aggsortop => '>(xid8,xid8)',
|
aggcombinefn => 'xid8_larger', aggsortop => '>(xid8,xid8)',
|
||||||
aggtranstype => 'xid8' },
|
aggtranstype => 'xid8' },
|
||||||
|
{ aggfnoid => 'max(bytea)', aggtransfn => 'bytea_larger',
|
||||||
|
aggcombinefn => 'bytea_larger', aggsortop => '>(bytea,bytea)',
|
||||||
|
aggtranstype => 'bytea' },
|
||||||
|
|
||||||
# min
|
# min
|
||||||
{ aggfnoid => 'min(int8)', aggtransfn => 'int8smaller',
|
{ aggfnoid => 'min(int8)', aggtransfn => 'int8smaller',
|
||||||
@ -232,6 +235,9 @@
|
|||||||
{ aggfnoid => 'min(xid8)', aggtransfn => 'xid8_smaller',
|
{ aggfnoid => 'min(xid8)', aggtransfn => 'xid8_smaller',
|
||||||
aggcombinefn => 'xid8_smaller', aggsortop => '<(xid8,xid8)',
|
aggcombinefn => 'xid8_smaller', aggsortop => '<(xid8,xid8)',
|
||||||
aggtranstype => 'xid8' },
|
aggtranstype => 'xid8' },
|
||||||
|
{ aggfnoid => 'min(bytea)', aggtransfn => 'bytea_smaller',
|
||||||
|
aggcombinefn => 'bytea_smaller', aggsortop => '<(bytea,bytea)',
|
||||||
|
aggtranstype => 'bytea' },
|
||||||
|
|
||||||
# count
|
# count
|
||||||
{ aggfnoid => 'count(any)', aggtransfn => 'int8inc_any',
|
{ aggfnoid => 'count(any)', aggtransfn => 'int8inc_any',
|
||||||
|
@ -1314,6 +1314,13 @@
|
|||||||
proname => 'text_smaller', proleakproof => 't', prorettype => 'text',
|
proname => 'text_smaller', proleakproof => 't', prorettype => 'text',
|
||||||
proargtypes => 'text text', prosrc => 'text_smaller' },
|
proargtypes => 'text text', prosrc => 'text_smaller' },
|
||||||
|
|
||||||
|
{ oid => '8920', descr => 'larger of two',
|
||||||
|
proname => 'bytea_larger', proleakproof => 't', prorettype => 'bytea',
|
||||||
|
proargtypes => 'bytea bytea', prosrc => 'bytea_larger' },
|
||||||
|
{ oid => '8921', descr => 'smaller of two',
|
||||||
|
proname => 'bytea_smaller', proleakproof => 't', prorettype => 'bytea',
|
||||||
|
proargtypes => 'bytea bytea', prosrc => 'bytea_smaller' },
|
||||||
|
|
||||||
{ oid => '460', descr => 'I/O',
|
{ oid => '460', descr => 'I/O',
|
||||||
proname => 'int8in', prorettype => 'int8', proargtypes => 'cstring',
|
proname => 'int8in', prorettype => 'int8', proargtypes => 'cstring',
|
||||||
prosrc => 'int8in' },
|
prosrc => 'int8in' },
|
||||||
@ -6879,6 +6886,9 @@
|
|||||||
{ oid => '5099', descr => 'maximum value of all xid8 input values',
|
{ oid => '5099', descr => 'maximum value of all xid8 input values',
|
||||||
proname => 'max', prokind => 'a', proisstrict => 'f', prorettype => 'xid8',
|
proname => 'max', prokind => 'a', proisstrict => 'f', prorettype => 'xid8',
|
||||||
proargtypes => 'xid8', prosrc => 'aggregate_dummy' },
|
proargtypes => 'xid8', prosrc => 'aggregate_dummy' },
|
||||||
|
{ oid => '8922', descr => 'maximum value of all bytea input values',
|
||||||
|
proname => 'max', prokind => 'a', proisstrict => 'f', prorettype => 'bytea',
|
||||||
|
proargtypes => 'bytea', prosrc => 'aggregate_dummy' },
|
||||||
|
|
||||||
{ oid => '2131', descr => 'minimum value of all bigint input values',
|
{ oid => '2131', descr => 'minimum value of all bigint input values',
|
||||||
proname => 'min', prokind => 'a', proisstrict => 'f', prorettype => 'int8',
|
proname => 'min', prokind => 'a', proisstrict => 'f', prorettype => 'int8',
|
||||||
@ -6952,6 +6962,9 @@
|
|||||||
{ oid => '5100', descr => 'minimum value of all xid8 input values',
|
{ oid => '5100', descr => 'minimum value of all xid8 input values',
|
||||||
proname => 'min', prokind => 'a', proisstrict => 'f', prorettype => 'xid8',
|
proname => 'min', prokind => 'a', proisstrict => 'f', prorettype => 'xid8',
|
||||||
proargtypes => 'xid8', prosrc => 'aggregate_dummy' },
|
proargtypes => 'xid8', prosrc => 'aggregate_dummy' },
|
||||||
|
{ oid => '8923', descr => 'minimum value of all bytea input values',
|
||||||
|
proname => 'min', prokind => 'a', proisstrict => 'f', prorettype => 'bytea',
|
||||||
|
proargtypes => 'bytea', prosrc => 'aggregate_dummy' },
|
||||||
|
|
||||||
# count has two forms: count(any) and count(*)
|
# count has two forms: count(any) and count(*)
|
||||||
{ oid => '2147',
|
{ oid => '2147',
|
||||||
|
@ -1950,7 +1950,7 @@ select string_agg(distinct f1::text, ',' order by f1::text) from varchar_tbl; -
|
|||||||
a,ab,abcd
|
a,ab,abcd
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
-- string_agg bytea tests
|
-- string_agg, min, max bytea tests
|
||||||
create table bytea_test_table(v bytea);
|
create table bytea_test_table(v bytea);
|
||||||
select string_agg(v, '') from bytea_test_table;
|
select string_agg(v, '') from bytea_test_table;
|
||||||
string_agg
|
string_agg
|
||||||
@ -1984,6 +1984,32 @@ select string_agg(v, decode('ee', 'hex')) from bytea_test_table;
|
|||||||
\xffeeaa
|
\xffeeaa
|
||||||
(1 row)
|
(1 row)
|
||||||
|
|
||||||
|
select min(v) from bytea_test_table;
|
||||||
|
min
|
||||||
|
------
|
||||||
|
\xaa
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select max(v) from bytea_test_table;
|
||||||
|
max
|
||||||
|
------
|
||||||
|
\xff
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
insert into bytea_test_table values(decode('ffff','hex'));
|
||||||
|
insert into bytea_test_table values(decode('aaaa','hex'));
|
||||||
|
select min(v) from bytea_test_table;
|
||||||
|
min
|
||||||
|
------
|
||||||
|
\xaa
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
select max(v) from bytea_test_table;
|
||||||
|
max
|
||||||
|
--------
|
||||||
|
\xffff
|
||||||
|
(1 row)
|
||||||
|
|
||||||
drop table bytea_test_table;
|
drop table bytea_test_table;
|
||||||
-- Test parallel string_agg and array_agg
|
-- Test parallel string_agg and array_agg
|
||||||
create table pagg_test (x int, y int) with (autovacuum_enabled = off);
|
create table pagg_test (x int, y int) with (autovacuum_enabled = off);
|
||||||
|
@ -876,6 +876,8 @@ uuid_extract_timestamp(uuid)
|
|||||||
uuid_extract_version(uuid)
|
uuid_extract_version(uuid)
|
||||||
crc32(bytea)
|
crc32(bytea)
|
||||||
crc32c(bytea)
|
crc32c(bytea)
|
||||||
|
bytea_larger(bytea,bytea)
|
||||||
|
bytea_smaller(bytea,bytea)
|
||||||
-- restore normal output mode
|
-- restore normal output mode
|
||||||
\a\t
|
\a\t
|
||||||
-- List of functions used by libpq's fe-lobj.c
|
-- List of functions used by libpq's fe-lobj.c
|
||||||
|
@ -747,7 +747,7 @@ select string_agg(distinct f1::text, ',' order by f1) from varchar_tbl; -- not
|
|||||||
select string_agg(distinct f1, ',' order by f1::text) from varchar_tbl; -- not ok
|
select string_agg(distinct f1, ',' order by f1::text) from varchar_tbl; -- not ok
|
||||||
select string_agg(distinct f1::text, ',' order by f1::text) from varchar_tbl; -- ok
|
select string_agg(distinct f1::text, ',' order by f1::text) from varchar_tbl; -- ok
|
||||||
|
|
||||||
-- string_agg bytea tests
|
-- string_agg, min, max bytea tests
|
||||||
create table bytea_test_table(v bytea);
|
create table bytea_test_table(v bytea);
|
||||||
|
|
||||||
select string_agg(v, '') from bytea_test_table;
|
select string_agg(v, '') from bytea_test_table;
|
||||||
@ -762,6 +762,15 @@ select string_agg(v, '') from bytea_test_table;
|
|||||||
select string_agg(v, NULL) from bytea_test_table;
|
select string_agg(v, NULL) from bytea_test_table;
|
||||||
select string_agg(v, decode('ee', 'hex')) from bytea_test_table;
|
select string_agg(v, decode('ee', 'hex')) from bytea_test_table;
|
||||||
|
|
||||||
|
select min(v) from bytea_test_table;
|
||||||
|
select max(v) from bytea_test_table;
|
||||||
|
|
||||||
|
insert into bytea_test_table values(decode('ffff','hex'));
|
||||||
|
insert into bytea_test_table values(decode('aaaa','hex'));
|
||||||
|
|
||||||
|
select min(v) from bytea_test_table;
|
||||||
|
select max(v) from bytea_test_table;
|
||||||
|
|
||||||
drop table bytea_test_table;
|
drop table bytea_test_table;
|
||||||
|
|
||||||
-- Test parallel string_agg and array_agg
|
-- Test parallel string_agg and array_agg
|
||||||
|
Reference in New Issue
Block a user