Crash on SRF execution

From: Itai <itaid(at)outlook(dot)com>
To: "pgsql-hackers(at)postgresql(dot)org" <pgsql-hackers(at)postgresql(dot)org>
Subject: Crash on SRF execution
Date: 2015-03-15 15:40:11
Message-ID: DUB127-W92B3678124F37C0807FCA8AD050@phx.gbl
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi

I'm attempting to program a simple SRF function but it constantly crashes (details and code below).

Any idea why?

Thanks!

-Itai
-------------------------------------------------------------
Environment
-------------------------------------------------------------
Ubunto: 14.04.2 (server)
PG Ver: PostgreSQL 9.4.1 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2, 64-bit
Install: deb http://apt.postgresql.org/pub/repos/apt/ trusty-pgdg main
Dev: postgresql-server-dev-9.4 (9.4.1-1.pgdg14.04+1)
-------------------------------------------------------------
Execution
-------------------------------------------------------------
select * from pg_srf();
INFO: ----------- data source -----------
INFO: value: 1203000000
INFO: is_even: 1
INFO: value: 1203000001
INFO: is_even: 0
...
INFO: value: 1203003998
INFO: is_even: 1
INFO: value: 1203003999
INFO: is_even: 0
INFO: ----------- data context -----------
INFO: call_cntr: 0
INFO: value: 1203000000
INFO: is_even: 1
INFO: call_cntr: 1
INFO: value: 1203000001
INFO: is_even: 0
INFO: call_cntr: 2
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.
!>
-------------------------------------------------------------
pg_srf.h
-------------------------------------------------------------
#ifndef PGSRF_H
#define PGSRF_H
#include "fmgr.h"
// using int as bool due to a different issue (one prob. at a time)
typedef struct Number_tag
{
int value;
int is_even;
} Number;
typedef struct NumberList_tag
{
int length;
Number ** pp_numbers;
} NumberList;
extern Datum pg_srf(PG_FUNCTION_ARGS);
#endif
-------------------------------------------------------------
pg_srf.c
-------------------------------------------------------------
#include <postgres.h>
#include <access/htup_details.h>
#include <catalog/pg_type.h>
#include <funcapi.h>
#include "pg_srf.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PG_FUNCTION_INFO_V1(pg_srf);
Datum
pg_srf(PG_FUNCTION_ARGS)
{
int call_cntr, i, length, base_num;
Number * num;
NumberList * list;
HeapTuple rettuple;
FuncCallContext *funcctx;
MemoryContext oldcontext;
if (SRF_IS_FIRSTCALL())
{
length = 4000;
base_num = 1203000000;
list = (NumberList *)palloc(sizeof(NumberList));
list->pp_numbers = (Number **)palloc(sizeof(Number*) * length);
list->length = length;
i = 0;
for (; i < length; i++)
{
num = (Number *)palloc(sizeof(Number));
num->value = base_num + i;
num->is_even = ((base_num + i) % 2 == 0) ? 1 : 0;
list->pp_numbers[i] = num;
}
ereport(INFO, (errmsg("----------- data source -----------")));
i = 0;
for (; i < length; i++)
{
ereport(INFO, (errmsg("value: %d", list->pp_numbers[i]->value)));
ereport(INFO, (errmsg("is_even: %d", list->pp_numbers[i]->is_even)));
}

funcctx = SRF_FIRSTCALL_INIT();
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
funcctx->user_fctx = list;
funcctx->max_calls = list->length;
if (get_call_result_type(fcinfo, NULL, &funcctx->tuple_desc) != TYPEFUNC_COMPOSITE)
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("check if sql function definition returns SETOF record")));

BlessTupleDesc(funcctx->tuple_desc);
MemoryContextSwitchTo(oldcontext);
}
funcctx = SRF_PERCALL_SETUP();
list = funcctx->user_fctx;
call_cntr = funcctx->call_cntr;
if (call_cntr < funcctx->max_calls)
{
Datum retvals[2];
bool retnulls[2];

if (call_cntr == 0)
{
ereport(INFO, (errmsg("----------- data context -----------")));
}
ereport(INFO, (errmsg("call_cntr: %d", call_cntr)));
ereport(INFO, (errmsg("value: %d", list->pp_numbers[call_cntr]->value)));
retvals[0] = Int32GetDatum(list->pp_numbers[call_cntr]->value);
ereport(INFO, (errmsg("is_even: %d", list->pp_numbers[call_cntr]->is_even)));
retvals[1] = Int32GetDatum(list->pp_numbers[call_cntr]->is_even);
retnulls[0] = false;
retnulls[1] = false;
rettuple = heap_form_tuple(funcctx->tuple_desc, retvals, retnulls);
SRF_RETURN_NEXT(funcctx, HeapTupleGetDatum(rettuple));
}
else
{
SRF_RETURN_DONE(funcctx);
}
}
-------------------------------------------------------------
Makefile
-------------------------------------------------------------
MODULES = pg_srf
OBJS = pg_srf.o
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
-------------------------------------------------------------
SQL
-------------------------------------------------------------
CREATE OR REPLACE FUNCTION
pg_srf(OUT value integer, OUT is_even integer)
RETURNS
SETOF record
AS
'pg_srf.so', 'pg_srf'
LANGUAGE
C
STRICT
IMMUTABLE;

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2015-03-15 15:49:44 Re: Crash on SRF execution
Previous Message Andres Freund 2015-03-15 15:30:16 Re: Merge compact/non compact commits, make aborts dynamically sized