]> granicus.if.org Git - postgresql/commitdiff
Add bytea_agg, parallel to string_agg.
authorRobert Haas <rhaas@postgresql.org>
Fri, 23 Dec 2011 13:40:25 +0000 (08:40 -0500)
committerRobert Haas <rhaas@postgresql.org>
Fri, 23 Dec 2011 13:40:25 +0000 (08:40 -0500)
Pavel Stehule

doc/src/sgml/func.sgml
src/backend/utils/adt/varlena.c
src/include/catalog/catversion.h
src/include/catalog/pg_aggregate.h
src/include/catalog/pg_proc.h
src/include/utils/builtins.h
src/test/regress/expected/aggregates.out
src/test/regress/sql/aggregates.sql

index e7f7fe0e889af030d1a61f720da1bab9bad74727..2e06346584c8377ffcf4cd4e915d35d3933bbfba 100644 (file)
@@ -10908,6 +10908,24 @@ SELECT NULLIF(value, '(none)') ...
       <entry>true if at least one input value is true, otherwise false</entry>
      </row>
 
+     <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>
index 95893386aae6ef4f06afbef3a2082dbd558dc254..d66ba0654002d9565c5a45dac139ba74a0b5d928 100644 (file)
@@ -396,6 +396,53 @@ byteasend(PG_FUNCTION_ARGS)
        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
index f366d79366138d22b32801d8c2f3111633ec8d6f..94b7d897907ff732c28b3884c56fb55e01f671cd 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                                                     yyyymmddN */
-#define CATALOG_VERSION_NO     201112221
+#define CATALOG_VERSION_NO     201112231
 
 #endif
index 26966d283726e2d173dd0bc6413b27c5371ae062..952e89c94aace8718c6aadf360018b0a336f426c 100644 (file)
@@ -226,6 +226,9 @@ DATA(insert ( 2335  array_agg_transfn       array_agg_finalfn               0       2281    _null_ ));
 /* 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
  */
index ffe07279726c6bdfab69f23bde1db4e8b472cd81..32be6b13747c9609d433617cdffc85503178fdb2 100644 (file)
@@ -2403,12 +2403,19 @@ DATA(insert OID = 2816 (  float8_covar_samp                     PGNSP PGUID 12 1 0 0 0 f f f t f i
 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_ ));
index 217cd61c849e1c0f4b11583db2823a3441623df4..aa36db630f41faa3f0917bb7abb2ac84efcfabe3 100644 (file)
@@ -769,6 +769,8 @@ extern Datum unknownsend(PG_FUNCTION_ARGS);
 
 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);
 
index 2324c7cda821e09a3805113752316084662e1f2b..2ec4eec59b3f50caf7b675f5efb50d993b6b8b70 100644 (file)
@@ -1061,3 +1061,26 @@ select string_agg(distinct f1::text, ',' order by f1::text) from varchar_tbl;  -
  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;
index 04ec67b33af1b808a69be173b1bbcef3ff519a68..01c2e2d3cafc31053bb0505e21c1d22ef86afebf 100644 (file)
@@ -416,3 +416,18 @@ select string_agg(distinct f1, ',' order by f1) from varchar_tbl;  -- ok
 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;