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

Reply via email to