Re: improper call to spi_printtup ??? - Mailing list pgsql-hackers
From | Darko Prenosil |
---|---|
Subject | Re: improper call to spi_printtup ??? |
Date | |
Msg-id | 000a01c45d52$2a4edf50$f096bfd5@darko Whole thread Raw |
In response to | improper call to spi_printtup ??? (Darko Prenosil <darko.prenosil@finteh.hr>) |
Responses |
Re: improper call to spi_printtup ???
|
List | pgsql-hackers |
Here is the source, but now when You mentioned SPI state, I see that I put SPI_finish stupidly after SRF_RETURN_NEXT(funcctx, result); Could that be my problem ? Regards ! PG_FUNCTION_INFO_V1(check_view); Datum check_view(PG_FUNCTION_ARGS) {FuncCallContext *funcctx;MemoryContext oldcontext;int spiRet=0;PQExpBuffer queryBuff;void *plan=0; char *schemaName =0; char *viewName = 0;int ret = -1; uint call_cntr;uint max_calls;TupleTableSlot *slot;AttInMetadata *attinmeta; typedef struct sqlPlanInfo{ SPITupleTable* result; List* targetList;} sqlPlanInfo; if ( SRF_IS_FIRSTCALL()){ schemaName = GET_STR(PG_GETARG_TEXT_P(0)); viewName = GET_STR(PG_GETARG_TEXT_P(1)); queryBuff = createPQExpBuffer(); if (schemaName == NULL) elog(ERROR, "schemaName not set"); if (viewName == NULL) elog(ERROR, "viewName not set"); if (_SPI_connected >=0){ elog(NOTICE, "ALREADY CONNECTED"); spiRet = _SPI_connected; }else{ if ((spiRet = SPI_connect())< 0) elog(ERROR, "rlog: SPI_connect returned %d", spiRet); } funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); printfPQExpBuffer(queryBuff, "SELECT definition" " FROM pg_views WHERE schemaname='%s' " " AND viewname ='%s';",schemaName,viewName); ret = SPI_exec(queryBuff->data,1); if (ret == SPI_OK_SELECT){ if ( SPI_processed > 0 ){ TupleDesc tupdesc = SPI_tuptable->tupdesc; printfPQExpBuffer( queryBuff, "%s", SPI_getvalue(SPI_tuptable->vals[0],tupdesc,1) ); }else{ elog(ERROR, "Unexisting view %s.%s", schemaName,viewName ); } }else{ elog(ERROR, "Error executing %s", queryBuff->data); } plan = SPI_prepare(queryBuff->data, 0, 0); if (!plan) elog(ERROR, "Unable to create plan for %s", queryBuff->data ); ret = SPI_execp(plan,0, 0, 0); if (ret < 0){ elog(ERROR, "Error executing %s", queryBuff->data ); }else{ List *raw_parsetree_list=pg_parse_query(queryBuff->data); Node *parsetree = (Node *) lfirst(raw_parsetree_list); List *query_list= pg_analyze_and_rewrite(parsetree,0,0); Query *queryTree = (Query *) lfirst(query_list); sqlPlanInfo* inf =(sqlPlanInfo*) palloc(sizeof(sqlPlanInfo)); inf->result = SPI_tuptable; inf->targetList = queryTree->targetList; funcctx->max_calls = inf->result->tupdesc->natts; /* * Generate attribute metadata needed later to produce tuples */ TupleDesc tupdescRes; tupdescRes = CreateTemplateTupleDesc(18,false); TupleDescInitEntry(tupdescRes, (AttrNumber) 1, "attrelid",OIDOID, -1, 0, false); TupleDescInitEntry(tupdescRes, (AttrNumber) 2, "attname",NAMEOID, -1, 0, false); TupleDescInitEntry(tupdescRes, (AttrNumber) 3, "atttypid",OIDOID, -1, 0, false); TupleDescInitEntry(tupdescRes, (AttrNumber) 4, "attstattarget", INT4OID, -1, 0, false); TupleDescInitEntry(tupdescRes, (AttrNumber) 5, "attlen",INT2OID, -1, 0, false); TupleDescInitEntry(tupdescRes, (AttrNumber) 6, "attnum",INT2OID, -1, 0, false); TupleDescInitEntry(tupdescRes, (AttrNumber) 7, "attndims",INT4OID, -1, 0, false); TupleDescInitEntry(tupdescRes, (AttrNumber) 8, "attcacheoff",INT4OID, -1, 0, false); TupleDescInitEntry(tupdescRes, (AttrNumber) 9, "atttypmod", INT4OID, -1, 0, false); TupleDescInitEntry(tupdescRes, (AttrNumber) 10, "attbyval",BOOLOID, -1, 0, false); TupleDescInitEntry(tupdescRes, (AttrNumber) 11, "attstorage",CHAROID, -1, 0, false); TupleDescInitEntry(tupdescRes, (AttrNumber) 12, "attisset", BOOLOID, -1, 0, false); TupleDescInitEntry(tupdescRes, (AttrNumber) 13, "attalign",CHAROID, -1, 0, false); TupleDescInitEntry(tupdescRes, (AttrNumber) 14, "attnotnull",BOOLOID, -1, 0, false); TupleDescInitEntry(tupdescRes, (AttrNumber) 15, "atthasdef", BOOLOID, -1, 0, false); TupleDescInitEntry(tupdescRes, (AttrNumber) 16, "attisdropped",BOOLOID, -1, 0, false); TupleDescInitEntry(tupdescRes, (AttrNumber) 17, "attislocal",BOOLOID, -1, 0, false); TupleDescInitEntry(tupdescRes, (AttrNumber) 18, "attinhcount",INT4OID, -1, 0, false); slot = TupleDescGetSlot(tupdescRes); funcctx->slot = slot; attinmeta = TupleDescGetAttInMetadata(tupdescRes); funcctx->attinmeta= attinmeta; funcctx->user_fctx = inf; } MemoryContextSwitchTo(oldcontext);} funcctx = SRF_PERCALL_SETUP();call_cntr = funcctx->call_cntr;max_calls = funcctx->max_calls;slot = funcctx->slot;sqlPlanInfo*inf = (sqlPlanInfo*)funcctx->user_fctx; if (call_cntr >= funcctx->max_calls) SRF_RETURN_DONE(funcctx); /* Do we have a non-resjunk tlist item? */while (inf->targetList && ((TargetEntry *) lfirst(inf->targetList))->resdom->resjunk) inf->targetList = lnext(inf->targetList); char **values;HeapTuple tuple;Datum result;values = (char **) palloc(18 * sizeof(char *)); if (inf->targetList){ Resdom *res = ((TargetEntry *) lfirst(inf->targetList))->resdom; inf->result->tupdesc->attrs[call_cntr]->attrelid= res->resorigtbl; inf->result->tupdesc->attrs[call_cntr]->attnum = res->resorigcol;inf->targetList = lnext(inf->targetList);} int cols=0;for (cols=0; cols<18;cols++){ values[cols] = (char *) palloc(256);} sprintf(values[0], "%i", inf->result->tupdesc->attrs[call_cntr]->attrelid);sprintf(values[1], "%s", inf->result->tupdesc->attrs[call_cntr]->attname.data);sprintf(values[2],"%i",inf->result->tupdesc->attrs[call_cntr]->atttypid); sprintf(values[3],"%i",inf->result->tupdesc->attrs[call_cntr]->attstattarget );sprintf(values[4],"%i",inf->result->tupdesc->attrs[call_cntr]->attlen);sprintf(values[5],"%i",inf->result->tupdesc->attrs[call_cntr]->attnum);sprintf(values[6],"%i",inf->result->tupdesc->attrs[call_cntr]->attndims); sprintf(values[7],"%i",inf->result->tupdesc->attrs[call_cntr]->attcacheoff);sprintf(values[8],"%i",inf->result->tupdesc->attrs[call_cntr]->atttypmod);sprintf(values[9],"%i",inf->result->tupdesc->attrs[call_cntr]->attbyval); sprintf(values[10],"%c",inf->result->tupdesc->attrs[call_cntr]->attstorage);sprintf(values[11],"%i",inf->result->tupdesc->attrs[call_cntr]->attisset);sprintf(values[12],"%c",inf->result->tupdesc->attrs[call_cntr]->attalign); sprintf(values[13],"%i",inf->result->tupdesc->attrs[call_cntr]->attnotnull);sprintf(values[14],"%i",inf->result->tupdesc->attrs[call_cntr]->atthasdef); sprintf(values[15],"%i",inf->result->tupdesc->attrs[call_cntr]->attisdropped ); sprintf(values[16],"%i",inf->result->tupdesc->attrs[call_cntr]->attislocal); sprintf(values[17],"%i",inf->result->tupdesc->attrs[call_cntr]->attinhcount) ; /* build a tuple */tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);/* make the tuple into a datum */result = TupleGetDatum(slot,tuple);SRF_RETURN_NEXT(funcctx, result); SPI_finish(); } ----- Original Message ----- From: "Tom Lane" <tgl@sss.pgh.pa.us> To: "Darko Prenosil" <darko.prenosil@finteh.hr> Cc: <pgsql-hackers@postgresql.org> Sent: Monday, June 28, 2004 9:39 PM Subject: Re: [HACKERS] improper call to spi_printtup ??? > Darko Prenosil <darko.prenosil@finteh.hr> writes: > > Anyone knows what I'm doing wrong ? > > Well, when you didn't show us the text of the function, no. > > However, a reasonable bet would be that you used SPI inside the function > and did not use it correctly, leaving the SPI state corrupted when > control got back to plpgsql. > > regards, tom lane > > ---------------------------(end of broadcast)--------------------------- > TIP 7: don't forget to increase your free space map settings >
pgsql-hackers by date: