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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers