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:

Previous
From: Tom Lane
Date:
Subject: Re: improper call to spi_printtup ???
Next
From: Satoshi Nagayasu
Date:
Subject: Re: lock timeout patch