Hi, I want to write a custom agg function that, given an "int4 index", increments the element at "index" of an array and, at the end, returns the array. The array will always be int4[].
I need it in C, since plpgsql is way slower (and I need to use it in 5M+ rows). I did it, but I also need to create the array "on demand", not as initcond (the array size will be a parameter). I suppose that, since I'll be using "construct_array" (if it makes sense), I'll need a new MemoryContext? I've looked at array_agg_transfn, but I think that's a lot more complicated because it'll repalloc, so it has to keep the memorycontext... Since I'm not familiar with these things, would something like this work? if (PG_ARGISNULL(0)) { // first time, alloc array arr_context = AllocSetContextCreate(rcontext, "myCustomArrayResult", ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); oldcontext = MemoryContextSwitchTo(arr_context); transarray = construct_array([...]); MemoryContextSwitchTo(oldcontext ); } else { transarray = PG_GETARG_ARRAYTYPE_P(0); } This is how the C function is written right now: ArrayType *transarray; int32 index = PG_GETARG_INT32(1); int32 *array; if (AggCheckCallContext(fcinfo, NULL)) { // code above would go in place of this line: transarray = PG_GETARG_ARRAYTYPE_P(0); } else transarray = PG_GETARG_ARRAYTYPE_P_COPY(0); array = (int32*)ARR_DATA_PTR(transarray); array[index]++; PG_RETURN_ARRAYTYPE_P(transarray); (checks on boundaries etc omitted) The problem is that it expects the array to be already available, so I had to do: CREATE AGGREGATE cust_agg_func (int4) ( sfunc = cust_agg_funct_add, stype = int4[], initcond = '{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}' ); I would like to have: CREATE AGGREGATE cust_agg_func (int4 index, int4 array_size_to_be_created) ( sfunc = cust_agg_funct_with_array_creation_add, stype = int4[] ); -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers