Обсуждение: Crash on SRF execution
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;
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;
Itai <itaid@outlook.com> writes:
> I'm attempting to program a simple SRF function but it constantly crashes (details and code below).
> Any idea why?
Looks like you're pallocing some stuff in the calling context (ie, a
short-lived context) during the first execution and expecting it to
still be there in later executions. You'd need to allocate those
data structures in the multi_call_memory_ctx instead.
regards, tom lane
Hi,
On 2015-03-15 17:40:11 +0200, Itai wrote:
> I'm attempting to program a simple SRF function but it constantly crashes (details and code below).
>
> Any idea why?
> 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);
> }
The palloc() for list above is in the per call memory context, but you
use it across several calls. You should allocate it in the multi call
context you use some lines below.
Greetings,
Andres Freund
-- Andres Freund http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training &
Services
Thanks for the quick response!! :)
But I don't get it... isn't:
if (SRF_IS_FIRSTCALL())
{
}
the iterator one time "initialization block" where I setup the data to be iterated upon? Can you please elaborate on how should I fix this? I'm probably missing something basic...
> Date: Sun, 15 Mar 2015 16:50:27 +0100
> From: andres@2ndquadrant.com
> To: itaid@outlook.com
> CC: pgsql-hackers@postgresql.org
> Subject: Re: [HACKERS] Crash on SRF execution
>
> Hi,
>
> On 2015-03-15 17:40:11 +0200, Itai wrote:
> > I'm attempting to program a simple SRF function but it constantly crashes (details and code below).
> >
> > Any idea why?
>
> > 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);
> > }
>
> The palloc() for list above is in the per call memory context, but you
> use it across several calls. You should allocate it in the multi call
> context you use some lines below.
>
> Greetings,
>
> Andres Freund
>
> --
> Andres Freund http://www.2ndQuadrant.com/
> PostgreSQL Development, 24x7 Support, Training & Services
>
>
> --
> Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-hackers
> From: andres@2ndquadrant.com
> To: itaid@outlook.com
> CC: pgsql-hackers@postgresql.org
> Subject: Re: [HACKERS] Crash on SRF execution
>
> Hi,
>
> On 2015-03-15 17:40:11 +0200, Itai wrote:
> > I'm attempting to program a simple SRF function but it constantly crashes (details and code below).
> >
> > Any idea why?
>
> > 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);
> > }
>
> The palloc() for list above is in the per call memory context, but you
> use it across several calls. You should allocate it in the multi call
> context you use some lines below.
>
> Greetings,
>
> Andres Freund
>
> --
> Andres Freund http://www.2ndQuadrant.com/
> PostgreSQL Development, 24x7 Support, Training & Services
>
>
> --
> Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-hackers
Hi,
On 2015-03-15 17:59:39 +0200, Itai wrote:
> Thanks for the quick response!! :)
> But I don't get it... isn't:
> if (SRF_IS_FIRSTCALL()){
> }
> the iterator one time
> "initialization block" where I setup the data to be iterated
> upon?
>
> Can you please elaborate on how should I fix this? I'm probably missing something basic...
> > > if (SRF_IS_FIRSTCALL())
> > > {
> > > length = 4000;
> > > base_num = 1203000000;
> > > list = (NumberList *)palloc(sizeof(NumberList));
> > > list->pp_numbers = (Number **)palloc(sizeof(Number*) * length);
You allocate memory in the per call context here.
> > > 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);
Because you only switch the memory context here. Move this up, to the
beginning of the SRF_IS_FIRSTCALL block. Before the palloc()s.
Greetings,
Andres Freund
-- Andres Freund http://www.2ndQuadrant.com/PostgreSQL Development, 24x7 Support, Training &
Services
Fantastic! That solved this problem.
However I still get a crash if I change:
is_even to bool
num->is_even = ((base_num + i) % 2 == 0) ? true : false;
retvals[1] = BoolGetDatum(list->pp_numbers[call_cntr]->is_even);
CREATE OR REPLACE FUNCTION
pg_srf(OUT value integer, OUT is_even bit)
RETURNS
SETOF record
AS
'pg_srf.so', 'pg_srf'
LANGUAGE
C
STRICT
IMMUTABLE;
> Date: Sun, 15 Mar 2015 17:03:38 +0100
> From: andres@2ndquadrant.com
> To: itaid@outlook.com
> CC: pgsql-hackers@postgresql.org
> Subject: Re: [HACKERS] Crash on SRF execution
>
> Hi,
>
> On 2015-03-15 17:59:39 +0200, Itai wrote:
> > Thanks for the quick response!! :)
> > But I don't get it... isn't:
> > if (SRF_IS_FIRSTCALL()){
> > }
> > the iterator one time
> > "initialization block" where I setup the data to be iterated
> > upon?
> >
> > Can you please elaborate on how should I fix this? I'm probably missing something basic...
>
> > > > if (SRF_IS_FIRSTCALL())
> > > > {
> > > > length = 4000;
> > > > base_num = 1203000000;
> > > > list = (NumberList *)palloc(sizeof(NumberList));
> > > > list->pp_numbers = (Number **)palloc(sizeof(Number*) * length);
>
> You allocate memory in the per call context here.
>
> > > > 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);
>
> Because you only switch the memory context here. Move this up, to the
> beginning of the SRF_IS_FIRSTCALL block. Before the palloc()s.
>
> Greetings,
>
> Andres Freund
>
> --
> Andres Freund http://www.2ndQuadrant.com/
> PostgreSQL Development, 24x7 Support, Training & Services
>
>
> --
> Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-hackers
> From: andres@2ndquadrant.com
> To: itaid@outlook.com
> CC: pgsql-hackers@postgresql.org
> Subject: Re: [HACKERS] Crash on SRF execution
>
> Hi,
>
> On 2015-03-15 17:59:39 +0200, Itai wrote:
> > Thanks for the quick response!! :)
> > But I don't get it... isn't:
> > if (SRF_IS_FIRSTCALL()){
> > }
> > the iterator one time
> > "initialization block" where I setup the data to be iterated
> > upon?
> >
> > Can you please elaborate on how should I fix this? I'm probably missing something basic...
>
> > > > if (SRF_IS_FIRSTCALL())
> > > > {
> > > > length = 4000;
> > > > base_num = 1203000000;
> > > > list = (NumberList *)palloc(sizeof(NumberList));
> > > > list->pp_numbers = (Number **)palloc(sizeof(Number*) * length);
>
> You allocate memory in the per call context here.
>
> > > > 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);
>
> Because you only switch the memory context here. Move this up, to the
> beginning of the SRF_IS_FIRSTCALL block. Before the palloc()s.
>
> Greetings,
>
> Andres Freund
>
> --
> Andres Freund http://www.2ndQuadrant.com/
> PostgreSQL Development, 24x7 Support, Training & Services
>
>
> --
> Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-hackers
Thanks Tom.
Assuming the SRF had a parameter, would this be a correct approach
(considering the iterative model) to bail-out early?
if (SRF_IS_FIRSTCALL())
{int i;if (get_call_result_type(fcinfo, NULL, &funcctx->tuple_desc) !=
TYPEFUNC_COMPOSITE) { ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("Check if sql function
definitionreturns SETOF
record"))); return;}
if (PG_ARGISNULL(0)) { ereport(ERROR, (errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), errmsg("Null value not allow
for..."))); return;} if((i = PG_GETARG_INT32(0)) != 'WHATEVER') { ereport(ERROR,
(errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("Null value not allow for ..."))); return;}
-----Original Message-----
From: Tom Lane [mailto:tgl@sss.pgh.pa.us]
Sent: Sunday, March 15, 2015 5:50 PM
To: Itai
Cc: pgsql-hackers@postgresql.org
Subject: Re: [HACKERS] Crash on SRF execution
Itai <itaid@outlook.com> writes:
> I'm attempting to program a simple SRF function but it constantly crashes
(details and code below).
> Any idea why?
Looks like you're pallocing some stuff in the calling context (ie, a
short-lived context) during the first execution and expecting it to still be
there in later executions. You'd need to allocate those data structures in
the multi_call_memory_ctx instead.
regards, tom lane