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;