From: | Leonardo Francalanci <m_lists(at)yahoo(dot)it> |
---|---|
To: | pgsql-hackers(at)postgresql(dot)org |
Subject: | Custom aggragation function that creates an array |
Date: | 2010-10-22 13:02:48 |
Message-ID: | 143197.43879.qm@web29013.mail.ird.yahoo.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
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[]
);
From | Date | Subject | |
---|---|---|---|
Next Message | Dimitri Fontaine | 2010-10-22 13:43:58 | Re: Extensions, this time with a patch |
Previous Message | Teodor Sigaev | 2010-10-22 10:58:24 | Re: knngist - 0.8 |