Segmentation fault when using a set-returning C function from a view in 8.4.0

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

Responses

Browse pgsql-hackers by date

  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