From: | Werner Echezuria <wercool(at)gmail(dot)com> |
---|---|
To: | pgsql-hackers(at)postgresql(dot)org |
Subject: | return a set of records |
Date: | 2009-08-27 18:45:19 |
Message-ID: | 2485a25e0908271145o38daa873p8e1b8b2fe81d3407@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
Hi, I need to return a set of records from a query, first I translate
from sqlf to sql and later I wanna return the query, but the server
crash (I guess it crashes around the yyparse call).
This is the sql:
CREATE OR REPLACE FUNCTION sqlf (text) RETURNS SETOF record
AS 'MODULE_PATHNAME', 'sqlf'
LANGUAGE C IMMUTABLE STRICT;
This is the function:
Datum sqlf(PG_FUNCTION_ARGS) {
char *query = TextDatumGetCString(PG_GETARG_DATUM(0));
void *result;
int ret,proc;
int j,i;
FuncCallContext *funcctx;
int call_cntr;
int max_calls;
TupleDesc tupdesc;
SPITupleTable *tuptable;
AttInMetadata *attinmeta;
yy_scan_string(query);
sqlf_yyparse(&result);
// stuff done only on the first call of the function
if (SRF_IS_FIRSTCALL()) {
MemoryContext oldcontext;
// create a function context for cross-call persistence
funcctx = SRF_FIRSTCALL_INIT();
// switch to memory context appropriate for multiple
// function calls
oldcontext =MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
SPI_connect();
ret=SPI_execute(result,true,0);
proc=SPI_processed;
// total number of tuples to be returned
funcctx->max_calls = proc;
if (ret > 0 && SPI_tuptable != NULL){
tupdesc = SPI_tuptable->tupdesc;
tuptable = SPI_tuptable;
}
MemoryContextSwitchTo(oldcontext);
}
// stuff done on every call of the function
funcctx = SRF_PERCALL_SETUP();
call_cntr = funcctx->call_cntr;
max_calls = funcctx->max_calls;
attinmeta = funcctx->attinmeta;
j=0;
if (call_cntr < max_calls) { // do when there is more left to send
Datum *values;
HeapTuple tuple;
Datum datum_result;
bool isnull;
values = (Datum **) palloc(tupdesc->natts * sizeof(Datum *));
for (i = 1; i <= tupdesc->natts; i++)
values[i]=SPI_getbinval(tuple,tupdesc,i,&isnull);
tuple=tuptable->vals[j];
// make the tuple into a datum
datum_result = HeapTupleGetDatum(tuple);
j++;
SRF_RETURN_NEXT(funcctx, datum_result);
} else { // do when there is no more left
SRF_RETURN_DONE(funcctx);
}
}
Greetings.
From | Date | Subject | |
---|---|---|---|
Next Message | Peter Eisentraut | 2009-08-27 18:54:23 | Re: 8.5 release timetable, again |
Previous Message | Rob Wultsch | 2009-08-27 18:39:22 | Re: MySQL Compatibility WAS: 8.5 release timetable, again |