So I went off to convert contrib/intagg to a wrapper around the new core functions, along this line:
CREATE OR REPLACE FUNCTION int_agg_state (internal, int4) RETURNS internal AS 'array_agg_transfn' LANGUAGE INTERNAL; CREATE OR REPLACE FUNCTION int_agg_final_array (internal) RETURNS int4[] AS 'array_agg_finalfn' LANGUAGE INTERNAL; CREATE AGGREGATE int_array_aggregate ( BASETYPE = int4, SFUNC = int_agg_state, STYPE = internal, FINALFUNC = int_agg_final_array ); But it doesn't work: psql:int_aggregate.sql:27: ERROR: aggregate transition data type cannot be internal I thought about declaring the transition functions with some other datatype, but that seemed entirely unsafe. Now CREATE AGGREGATE has fairly good reason to reject internal as the transition type, since nodeAgg.c doesn't really know how to copy that type around --- but we're effectively *exploiting* that fact in the new array_agg stuff, as per the comment I added: /* * We cheat quite a lot here by assuming that a pointer datum will be * preserved intact when nodeAgg.c thinks it is a value of type "internal". * This will in fact work because internal is stated to be pass-by-value * in pg_type.h, and nodeAgg will never do anything with a pass-by-value * transvalue except pass it around in Datum form. But it's mighty * shaky seeing that internal is also stated to be 4 bytes wide in * pg_type.h. If nodeAgg did put the value into a tuple this would * crash and burn on 64-bit machines. */ So it seems like maybe we should open up the same technique to writers of add-on modules. You can certainly screw yourself up by connecting some incompatible internal-accepting functions together this way. So what I propose is that we allow STYPE = internal to be specified in CREATE AGGREGATE, but only by superusers, who are trusted not to create security holes anyway. Comments? regards, tom lane -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers