Re: BUG #5883: Error when mixing SPI_returntuple with returning regular HeapTuple

From: Vegard Bønes <vegard(dot)bones(at)met(dot)no>
To: Robert Haas <robertmhaas(at)gmail(dot)com>
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, pgsql-bugs(at)postgresql(dot)org
Subject: Re: BUG #5883: Error when mixing SPI_returntuple with returning regular HeapTuple
Date: 2011-02-17 07:58:05
Message-ID: 61692821.85256.1297929485588.JavaMail.root@imap1b
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

The updated example is pasted in below.

The given example will cause an error. You may (for example) change the code in the stwitch statement like this, and it will work like a charm:

from:
case 1:
SRF_RETURN_NEXT(funcctx, get_data_alternative_b());
//get_data_alternative_a(ret, isnull);
to:
case 1:
//SRF_RETURN_NEXT(funcctx, get_data_alternative_b());
get_data_alternative_a(ret, isnull);

VG

#include <postgres.h>
#include <fmgr.h>
#include <funcapi.h>
#include <executor/spi.h>

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

/*
* CREATE TABLE test (a int, b int);
* INSERT INTO test VALUES (1, 2);
* CREATE FUNCTION run_test() RETURNS SETOF test AS 'SOMEWHERE/something.so', 'run_test' LANGUAGE C VOLATILE;
*
* SELECT * FROM run_test();
*
* ERROR: rows returned by function are not all of the same row type
*
*/

static const char * query = "SELECT a, b FROM test";

static void get_data_alternative_a(Datum * data_out, bool * isnull)
{
SPI_connect();
SPI_execute(query, true, 1);
data_out[0] = SPI_getbinval(* SPI_tuptable->vals, SPI_tuptable->tupdesc, 1, & isnull[0]);
data_out[1] = SPI_getbinval(* SPI_tuptable->vals, SPI_tuptable->tupdesc, 2, & isnull[1]);
SPI_finish();
}

static Datum get_data_alternative_b()
{
SPI_connect();
SPI_execute(query, true, 1);
HeapTupleHeader ret = SPI_returntuple(* SPI_tuptable->vals, SPI_tuptable->tupdesc);
Datum d = PointerGetDatum(ret);
SPI_finish();
return d;
}

PG_FUNCTION_INFO_V1(run_test);
Datum run_test(PG_FUNCTION_ARGS)
{
FuncCallContext * funcctx;
int * return_count = NULL;

if ( SRF_IS_FIRSTCALL() )
{
funcctx = SRF_FIRSTCALL_INIT();
//SPI_connect();

MemoryContext oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
TupleDesc tupdesc;
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg(
"function returning record called in context "
"that cannot accept type record")));

funcctx->tuple_desc = BlessTupleDesc(tupdesc);

return_count = (int *) palloc(sizeof(int));
MemoryContextSwitchTo(oldcontext);

* return_count = 0;
funcctx->user_fctx = (void*) return_count;
}
funcctx = SRF_PERCALL_SETUP();
return_count = (int *) funcctx->user_fctx;

Datum ret[2];
bool isnull[2];
switch ( (* return_count) ++ )
{
case 0:
//SRF_RETURN_NEXT(funcctx, get_data_alternative_b());
get_data_alternative_a(ret, isnull);
break;
case 1:
SRF_RETURN_NEXT(funcctx, get_data_alternative_b());
//get_data_alternative_a(ret, isnull);
break;
default:
SRF_RETURN_DONE(funcctx);
}
HeapTuple heap_tuple = heap_form_tuple(funcctx->tuple_desc, ret, isnull);
Datum packed_ret = HeapTupleGetDatum(heap_tuple);
SRF_RETURN_NEXT(funcctx, packed_ret);
}

----- Original Message -----
Fra: "Robert Haas" <robertmhaas(at)gmail(dot)com>
Til: "Vegard Bønes" <vegard(dot)bones(at)met(dot)no>
Kopi: "Tom Lane" <tgl(at)sss(dot)pgh(dot)pa(dot)us>, pgsql-bugs(at)postgresql(dot)org
Sendt: 17. februar 2011 02:41:47
Emne: Re: [BUGS] BUG #5883: Error when mixing SPI_returntuple with returning regular HeapTuple

On Tue, Feb 15, 2011 at 2:43 AM, Vegard Bønes <vegard(dot)bones(at)met(dot)no> wrote:
> Ok, I tried to modify the example functions get_data_alternative_a() and get_data_alternative_b(), so that they start with SPI_connect, and end with SPI_finish. Also I removed SPI_connect and SPI_finish from the main function. As I understand you, that should have solved the problem. The result, however, is exactly the same as before.

You may get further if you post the modified code, instead of simply
asserting that some code we can't see doesn't work.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

In response to

Browse pgsql-bugs by date

  From Date Subject
Next Message Alexander V. Chernikov 2011-02-17 09:51:26 BUG #5891: Unique index is not unique
Previous Message Heikki Linnakangas 2011-02-17 07:42:31 Re: timestamp issue