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

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to