Segmentation fault when using a set-returning C function from a view in 8.4.0 - Mailing list pgsql-hackers

From Christian Thomsen
Subject Segmentation fault when using a set-returning C function from a view in 8.4.0
Date
Msg-id 4A7FDD21.3020306@cs.aau.dk
Whole thread Raw
Responses Re: Segmentation fault when using a set-returning C function from a view in 8.4.0  (Tom Lane <tgl@sss.pgh.pa.us>)
List 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.0on 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("Contextdoes 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


pgsql-hackers by date:

Previous
From: Dimitri Fontaine
Date:
Subject: CommitFest reviews and application support
Next
From: Peter Eisentraut
Date:
Subject: Re: pg_stat_activity.application_name