*** pgsql/src/backend/executor/execMain.c 2009/09/26 22:42:01 1.328 --- pgsql/src/backend/executor/execMain.c 2009/09/27 20:09:57 1.329 *************** *** 26,32 **** * * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.327 2009/07/29 20:56:18 tgl Exp $ * *------------------------------------------------------------------------- */ --- 26,32 ---- * * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.328 2009/09/26 22:42:01 tgl Exp $ * *------------------------------------------------------------------------- */ *************** InitPlan(QueryDesc *queryDesc, int eflag *** 755,794 **** } /* ! * Initialize the executor "tuple" table. We need slots for all the plan ! * nodes, plus possibly output slots for the junkfilter(s). At this point ! * we aren't sure if we need junkfilters, so just add slots for them ! * unconditionally. Also, if it's not a SELECT, set up a slot for use for ! * trigger output tuples. Also, one for RETURNING-list evaluation. */ ! { ! int nSlots; ! ! /* Slots for the main plan tree */ ! nSlots = ExecCountSlotsNode(plan); ! /* Add slots for subplans and initplans */ ! foreach(l, plannedstmt->subplans) ! { ! Plan *subplan = (Plan *) lfirst(l); ! ! nSlots += ExecCountSlotsNode(subplan); ! } ! /* Add slots for junkfilter(s) */ ! if (plannedstmt->resultRelations != NIL) ! nSlots += list_length(plannedstmt->resultRelations); ! else ! nSlots += 1; ! if (operation != CMD_SELECT) ! nSlots++; /* for es_trig_tuple_slot */ ! if (plannedstmt->returningLists) ! nSlots++; /* for RETURNING projection */ ! ! estate->es_tupleTable = ExecCreateTupleTable(nSlots); ! ! if (operation != CMD_SELECT) ! estate->es_trig_tuple_slot = ! ExecAllocTableSlot(estate->es_tupleTable); ! } /* mark EvalPlanQual not active */ estate->es_plannedstmt = plannedstmt; --- 755,766 ---- } /* ! * Initialize the executor's tuple table. Also, if it's not a SELECT, ! * set up a tuple table slot for use for trigger output tuples. */ ! estate->es_tupleTable = NIL; ! if (operation != CMD_SELECT) ! estate->es_trig_tuple_slot = ExecInitExtraTupleSlot(estate); /* mark EvalPlanQual not active */ estate->es_plannedstmt = plannedstmt; *************** InitPlan(QueryDesc *queryDesc, int eflag *** 909,915 **** j = ExecInitJunkFilter(subplan->plan->targetlist, resultRelInfo->ri_RelationDesc->rd_att->tdhasoid, ! ExecAllocTableSlot(estate->es_tupleTable)); /* * Since it must be UPDATE/DELETE, there had better be a --- 881,887 ---- j = ExecInitJunkFilter(subplan->plan->targetlist, resultRelInfo->ri_RelationDesc->rd_att->tdhasoid, ! ExecInitExtraTupleSlot(estate)); /* * Since it must be UPDATE/DELETE, there had better be a *************** InitPlan(QueryDesc *queryDesc, int eflag *** 953,959 **** j = ExecInitJunkFilter(planstate->plan->targetlist, tupType->tdhasoid, ! ExecAllocTableSlot(estate->es_tupleTable)); estate->es_junkFilter = j; if (estate->es_result_relation_info) estate->es_result_relation_info->ri_junkFilter = j; --- 925,931 ---- j = ExecInitJunkFilter(planstate->plan->targetlist, tupType->tdhasoid, ! ExecInitExtraTupleSlot(estate)); estate->es_junkFilter = j; if (estate->es_result_relation_info) estate->es_result_relation_info->ri_junkFilter = j; *************** InitPlan(QueryDesc *queryDesc, int eflag *** 1026,1032 **** false); /* Set up a slot for the output of the RETURNING projection(s) */ ! slot = ExecAllocTableSlot(estate->es_tupleTable); ExecSetSlotDescriptor(slot, tupType); /* Need an econtext too */ econtext = CreateExprContext(estate); --- 998,1004 ---- false); /* Set up a slot for the output of the RETURNING projection(s) */ ! slot = ExecInitExtraTupleSlot(estate); ExecSetSlotDescriptor(slot, tupType); /* Need an econtext too */ econtext = CreateExprContext(estate); *************** ExecEndPlan(PlanState *planstate, EState *** 1387,1396 **** } /* ! * destroy the executor "tuple" table. */ ! ExecDropTupleTable(estate->es_tupleTable, true); ! estate->es_tupleTable = NULL; /* * close the result relation(s) if any, but hold locks until xact commit. --- 1359,1370 ---- } /* ! * destroy the executor's tuple table. Actually we only care about ! * releasing buffer pins and tupdesc refcounts; there's no need to ! * pfree the TupleTableSlots, since the containing memory context ! * is about to go away anyway. */ ! ExecResetTupleTable(estate->es_tupleTable, false); /* * close the result relation(s) if any, but hold locks until xact commit. *************** EvalPlanQualStart(evalPlanQual *epq, ESt *** 2712,2721 **** epqstate->es_evTuple = priorepq->estate->es_evTuple; /* ! * Create sub-tuple-table; we needn't redo the CountSlots work though. */ ! epqstate->es_tupleTable = ! ExecCreateTupleTable(estate->es_tupleTable->size); /* * Initialize private state information for each SubPlan. We must do this --- 2686,2694 ---- epqstate->es_evTuple = priorepq->estate->es_evTuple; /* ! * Each epqstate also has its own tuple table. */ ! epqstate->es_tupleTable = NIL; /* * Initialize private state information for each SubPlan. We must do this *************** EvalPlanQualStop(evalPlanQual *epq) *** 2770,2777 **** ExecEndNode(subplanstate); } ! ExecDropTupleTable(epqstate->es_tupleTable, true); ! epqstate->es_tupleTable = NULL; if (epqstate->es_evTuple[epq->rti - 1] != NULL) { --- 2743,2751 ---- ExecEndNode(subplanstate); } ! /* throw away the per-epqstate tuple table completely */ ! ExecResetTupleTable(epqstate->es_tupleTable, true); ! epqstate->es_tupleTable = NIL; if (epqstate->es_evTuple[epq->rti - 1] != NULL) {