From: | Christian Thomsen <chr(at)cs(dot)aau(dot)dk> |
---|---|
To: | pgsql-hackers(at)postgresql(dot)org |
Subject: | Segmentation fault when using a set-returning C function from a view in 8.4.0 |
Date: | 2009-08-10 08:41:05 |
Message-ID: | 4A7FDD21.3020306@cs.aau.dk |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
Hello,
I have created a set-returning C function and a view that selects all
the returned rows. When I use SELECT * FROM theview, the returned rows
look fine. But if I use, e.g., SELECT count(*) FROM theview or SELECT
sum(a) FROM theview, I get a segmentation fault.
LOG: server process (PID 7099) was terminated by signal 11:
Segmentation fault
Is this a bug? SELECT count(*), sum(a) FROM thefunction() works fine.
I have created a small example that demonstrates the problem (see
below). If the C function only returns few rows, everything works. If
the function returns more rows (e.g., 5,000), I get the segmentation fault.
I have expericenced this on 8.4.0:
chr=# select version();
version
-------------------------------------------------------------------------------------------------------------
PostgreSQL 8.4.0 on x86_64-unknown-linux-gnu, compiled by GCC gcc (GCC)
4.1.2 20070115 (SUSE Linux), 64-bit
chr=# show work_mem ;
work_mem
----------
256MB
EXAMPLE:
create table demotbl(a int, b int, c int);
create function demosrf() returns setof demotbl language 'c' as
'/tmp/demo.so';
create view demoview as
select * from demotbl
union all
select * from demosrf();
The C code is shown below.
#include "postgres.h"
#include "tupdesc.h"
#include "funcapi.h"
#include "fmgr.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PG_FUNCTION_INFO_V1(demosrf);
Datum
demosrf(PG_FUNCTION_ARGS)
{
ReturnSetInfo *rsinfo = (ReturnSetInfo *)fcinfo->resultinfo;
TupleDesc tupdesc;
Tuplestorestate *tupstore;
AttInMetadata *attinmeta;
int numberOfAttributes;
int i, j;
Datum *values;
bool *isnull;
extern int work_mem;
if(rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("Context does not accept a set")));
if(!(rsinfo->allowedModes & SFRM_Materialize))
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("Materialize not allowed")));
tupdesc = rsinfo->expectedDesc;
tupstore = tuplestore_begin_heap(false, false, work_mem);
attinmeta = TupleDescGetAttInMetadata(tupdesc);
numberOfAttributes = attinmeta->tupdesc->natts;
values = (Datum *)palloc(numberOfAttributes * sizeof(Datum));
isnull = (bool *)palloc(numberOfAttributes * sizeof(bool));
// Create rows
for(i = 0; i < 10000; i++) {
for(j = 0; j < numberOfAttributes; j++) {
isnull[j] = false;
values[j] = Int32GetDatum(i);
}
tuplestore_putvalues(tupstore, tupdesc, values, isnull);
}
rsinfo->returnMode = SFRM_Materialize;
rsinfo->setResult = tupstore;
return (Datum)0;
}
Best regards,
Christian Thomsen
From | Date | Subject | |
---|---|---|---|
Next Message | Peter Eisentraut | 2009-08-10 09:52:03 | Re: pg_stat_activity.application_name |
Previous Message | Dimitri Fontaine | 2009-08-10 07:45:34 | CommitFest reviews and application support |