Hello this patch adds a bytea_agg aggregation.
It allow fast bytea concatetation. Regards Pavel Stehule
*** ./doc/src/sgml/func.sgml.orig 2011-12-07 11:04:33.000000000 +0100 --- ./doc/src/sgml/func.sgml 2011-12-21 11:00:18.255753111 +0100 *************** *** 10911,10916 **** --- 10911,10934 ---- <row> <entry> <indexterm> + <primary>bytea_agg</primary> + </indexterm> + <function> + bytea_agg(<replaceable class="parameter">expression</replaceable>) + </function> + </entry> + <entry> + <type>bytea</type> + </entry> + <entry> + <type>bytea</type> + </entry> + <entry>input values concatenated into a bytea</entry> + </row> + + <row> + <entry> + <indexterm> <primary>count</primary> </indexterm> <function>count(*)</function> *** ./src/backend/utils/adt/varlena.c.orig 2011-12-21 08:21:10.000000000 +0100 --- ./src/backend/utils/adt/varlena.c 2011-12-21 10:46:33.344807038 +0100 *************** *** 396,401 **** --- 396,448 ---- PG_RETURN_BYTEA_P(vlena); } + Datum + bytea_agg_transfn(PG_FUNCTION_ARGS) + { + StringInfo state; + + state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0); + + /* Append the value unless null. */ + if (!PG_ARGISNULL(1)) + { + bytea *value = PG_GETARG_BYTEA_PP(1); + + if (state == NULL) + state = makeStringAggState(fcinfo); + + appendBinaryStringInfo(state, VARDATA_ANY(value), VARSIZE_ANY_EXHDR(value)); + } + + /* + * The transition type for bytea_agg() is declared to be "internal", + * which is a pass-by-value type the same size as a pointer. + */ + PG_RETURN_POINTER(state); + } + + Datum + bytea_agg_finalfn(PG_FUNCTION_ARGS) + { + StringInfo state; + + /* cannot be called directly because of internal-type argument */ + Assert(AggCheckCallContext(fcinfo, NULL)); + + state = PG_ARGISNULL(0) ? NULL : (StringInfo) PG_GETARG_POINTER(0); + + if (state != NULL) + { + bytea *result; + + result = (bytea *) palloc(state->len + VARHDRSZ); + SET_VARSIZE(result, state->len + VARHDRSZ); + memcpy(VARDATA(result), state->data, state->len); + PG_RETURN_BYTEA_P(result); + } + else + PG_RETURN_NULL(); + } /* * textin - converts "..." to internal representation *** ./src/include/catalog/pg_aggregate.h.orig 2011-12-07 11:04:33.000000000 +0100 --- ./src/include/catalog/pg_aggregate.h 2011-12-21 10:28:37.016877356 +0100 *************** *** 226,231 **** --- 226,234 ---- /* text */ DATA(insert ( 3538 string_agg_transfn string_agg_finalfn 0 2281 _null_ )); + /* bytea */ + DATA(insert ( 3545 bytea_agg_transfn bytea_agg_finalfn 0 2281 _null_ )); + /* * prototypes for functions in pg_aggregate.c */ *** ./src/include/catalog/pg_proc.h.orig 2011-12-21 08:21:10.000000000 +0100 --- ./src/include/catalog/pg_proc.h 2011-12-21 10:25:29.533889614 +0100 *************** *** 2403,2414 **** --- 2403,2421 ---- DESCR("aggregate final function"); DATA(insert OID = 2817 ( float8_corr PGNSP PGUID 12 1 0 0 0 f f f t f i 1 0 701 "1022" _null_ _null_ _null_ _null_ float8_corr _null_ _null_ _null_ )); DESCR("aggregate final function"); + DATA(insert OID = 3535 ( string_agg_transfn PGNSP PGUID 12 1 0 0 0 f f f f f i 3 0 2281 "2281 25 25" _null_ _null_ _null_ _null_ string_agg_transfn _null_ _null_ _null_ )); DESCR("aggregate transition function"); DATA(insert OID = 3536 ( string_agg_finalfn PGNSP PGUID 12 1 0 0 0 f f f f f i 1 0 25 "2281" _null_ _null_ _null_ _null_ string_agg_finalfn _null_ _null_ _null_ )); DESCR("aggregate final function"); DATA(insert OID = 3538 ( string_agg PGNSP PGUID 12 1 0 0 0 t f f f f i 2 0 25 "25 25" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); DESCR("concatenate aggregate input into a string"); + DATA(insert OID = 3543 ( bytea_agg_transfn PGNSP PGUID 12 1 0 0 0 f f f f f i 2 0 2281 "2281 17" _null_ _null_ _null_ _null_ bytea_agg_transfn _null_ _null_ _null_ )); + DESCR("aggregate transition function"); + DATA(insert OID = 3544 ( bytea_agg_finalfn PGNSP PGUID 12 1 0 0 0 f f f f f i 1 0 17 "2281" _null_ _null_ _null_ _null_ bytea_agg_finalfn _null_ _null_ _null_ )); + DESCR("aggregate final function"); + DATA(insert OID = 3545 ( bytea_agg PGNSP PGUID 12 1 0 0 0 t f f f f i 1 0 17 "17" _null_ _null_ _null_ _null_ aggregate_dummy _null_ _null_ _null_ )); + DESCR("concatenate aggregate input into a bytea"); /* To ASCII conversion */ DATA(insert OID = 1845 ( to_ascii PGNSP PGUID 12 1 0 0 0 f f f t f i 1 0 25 "25" _null_ _null_ _null_ _null_ to_ascii_default _null_ _null_ _null_ )); *** ./src/include/utils/builtins.h.orig 2011-12-21 08:21:10.000000000 +0100 --- ./src/include/utils/builtins.h 2011-12-21 10:16:10.521926024 +0100 *************** *** 769,774 **** --- 769,776 ---- extern Datum pg_column_size(PG_FUNCTION_ARGS); + extern Datum bytea_agg_transfn(PG_FUNCTION_ARGS); + extern Datum bytea_agg_finalfn(PG_FUNCTION_ARGS); extern Datum string_agg_transfn(PG_FUNCTION_ARGS); extern Datum string_agg_finalfn(PG_FUNCTION_ARGS); *** ./src/test/regress/expected/aggregates.out.orig 2011-12-07 11:04:33.000000000 +0100 --- ./src/test/regress/expected/aggregates.out 2011-12-21 10:54:02.000000000 +0100 *************** *** 1061,1063 **** --- 1061,1086 ---- a,ab,abcd (1 row) + -- bytea_agg tests + create table bytea_test_table(v bytea); + select bytea_agg(v) from bytea_test_table; + bytea_agg + ----------- + + (1 row) + + insert into bytea_test_table values(decode('ff','hex')); + select bytea_agg(v) from bytea_test_table; + bytea_agg + ----------- + \xff + (1 row) + + insert into bytea_test_table values(decode('aa','hex')); + select bytea_agg(v) from bytea_test_table; + bytea_agg + ----------- + \xffaa + (1 row) + + drop table bytea_test_table; *** ./src/test/regress/sql/aggregates.sql.orig 2011-12-21 10:53:32.062779653 +0100 --- ./src/test/regress/sql/aggregates.sql 2011-12-21 10:53:16.771780651 +0100 *************** *** 416,418 **** --- 416,433 ---- select string_agg(distinct f1::text, ',' order by f1) 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 + + -- bytea_agg tests + create table bytea_test_table(v bytea); + + select bytea_agg(v) from bytea_test_table; + + insert into bytea_test_table values(decode('ff','hex')); + + select bytea_agg(v) from bytea_test_table; + + insert into bytea_test_table values(decode('aa','hex')); + + select bytea_agg(v) from bytea_test_table; + + drop table bytea_test_table;
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers