From: Vadim B. Mikheev Date: Wed, 9 Jun 1999 12:23:42 +0000 (+0000) Subject: Reset evaluation plan tuple table next free slot counter to 0 X-Git-Tag: REL6_5~35 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=51298bcfdafd1cc60160485e5f7e6c872a09f29c;p=postgresql Reset evaluation plan tuple table next free slot counter to 0 after ExecEndNode. It must be done! Or we'll be out of free tuple slots very soon, though slots are freed by ExecEndNode and ready for reusing. We didn't see this problem before because of int nSlots = ExecCountSlotsNode(plan); TupleTable tupleTable = ExecCreateTupleTable(nSlots + 10); /* why add ten? - jolly */ code in InitPlan - i.e. extra 10 slots. Simple select uses 3 slots and so it was possible to re-use evaluation plan 3 additional times and didn't get elog(NOTICE, "Plan requires more slots than are available"); elog(ERROR, "send mail to your local executor guru to fix this"); Changes are obvious and shouldn't be problems with them. Though, I added Assert(epqstate->es_tupleTable->next == 0) before EvalPlanQual():ExecInitNode and we'll notice if something is still wrong. Is it better to change Assert to elog(ERROR) ? --- diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index 37881f84b1..766a692aae 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -26,7 +26,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.86 1999/06/06 15:14:40 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.87 1999/06/09 12:23:42 vadim Exp $ * *------------------------------------------------------------------------- */ @@ -1673,6 +1673,7 @@ EvalPlanQual(EState *estate, Index rti, ItemPointer tid) Assert(oldepq->rti != 0); /* stop execution */ ExecEndNode(epq->plan, epq->plan); + epqstate->es_tupleTable->next = 0; pfree(epqstate->es_evTuple[epq->rti - 1]); epqstate->es_evTuple[epq->rti - 1] = NULL; /* push current PQ to freePQ stack */ @@ -1741,7 +1742,10 @@ EvalPlanQual(EState *estate, Index rti, ItemPointer tid) * ability to use ExecReScan instead of ExecInitNode, so... */ if (endNode) + { ExecEndNode(epq->plan, epq->plan); + epqstate->es_tupleTable->next = 0; + } /* free old RTE' tuple */ if (epqstate->es_evTuple[epq->rti - 1] != NULL) @@ -1774,7 +1778,11 @@ EvalPlanQual(EState *estate, Index rti, ItemPointer tid) TransactionId xwait = SnapshotDirty->xmax; if (TransactionIdIsValid(SnapshotDirty->xmin)) - elog(ERROR, "EvalPlanQual: t_xmin is uncommitted ?!"); + { + elog(NOTICE, "EvalPlanQual: t_xmin is uncommitted ?!"); + Assert(!TransactionIdIsValid(SnapshotDirty->xmin)); + elog(ERROR, "Aborting this transaction"); + } /* * If tuple is being updated by other transaction then we have @@ -1836,6 +1844,7 @@ EvalPlanQual(EState *estate, Index rti, ItemPointer tid) estate->es_origPlan->nParamExec * sizeof(ParamExecData)); memset(epqstate->es_evTupleNull, false, length(estate->es_range_table) * sizeof(bool)); + Assert(epqstate->es_tupleTable->next == 0); ExecInitNode(epq->plan, epqstate, NULL); /* @@ -1866,6 +1875,7 @@ lpqnext:; if (TupIsNull(slot)) { ExecEndNode(epq->plan, epq->plan); + epqstate->es_tupleTable->next = 0; pfree(epqstate->es_evTuple[epq->rti - 1]); epqstate->es_evTuple[epq->rti - 1] = NULL; /* pop old PQ from the stack */