Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit f92e8a4

Browse files
committed
Replace the array-style TupleTable data structure with a simple List of
TupleTableSlot nodes. This eliminates the need to count in advance how many Slots will be needed, which seems more than worth the small increase in the amount of palloc traffic during executor startup. The ExecCountSlots infrastructure is now all dead code, but I'll remove it in a separate commit for clarity. Per a comment from Robert Haas.
1 parent 61be11f commit f92e8a4

File tree

6 files changed

+112
-231
lines changed

6 files changed

+112
-231
lines changed

src/backend/executor/execMain.c

Lines changed: 19 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
*
2727
*
2828
* IDENTIFICATION
29-
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.328 2009/09/26 22:42:01 tgl Exp $
29+
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.329 2009/09/27 20:09:57 tgl Exp $
3030
*
3131
*-------------------------------------------------------------------------
3232
*/
@@ -755,40 +755,12 @@ InitPlan(QueryDesc *queryDesc, int eflags)
755755
}
756756

757757
/*
758-
* Initialize the executor "tuple" table. We need slots for all the plan
759-
* nodes, plus possibly output slots for the junkfilter(s). At this point
760-
* we aren't sure if we need junkfilters, so just add slots for them
761-
* unconditionally. Also, if it's not a SELECT, set up a slot for use for
762-
* trigger output tuples. Also, one for RETURNING-list evaluation.
758+
* Initialize the executor's tuple table. Also, if it's not a SELECT,
759+
* set up a tuple table slot for use for trigger output tuples.
763760
*/
764-
{
765-
int nSlots;
766-
767-
/* Slots for the main plan tree */
768-
nSlots = ExecCountSlotsNode(plan);
769-
/* Add slots for subplans and initplans */
770-
foreach(l, plannedstmt->subplans)
771-
{
772-
Plan *subplan = (Plan *) lfirst(l);
773-
774-
nSlots += ExecCountSlotsNode(subplan);
775-
}
776-
/* Add slots for junkfilter(s) */
777-
if (plannedstmt->resultRelations != NIL)
778-
nSlots += list_length(plannedstmt->resultRelations);
779-
else
780-
nSlots += 1;
781-
if (operation != CMD_SELECT)
782-
nSlots++; /* for es_trig_tuple_slot */
783-
if (plannedstmt->returningLists)
784-
nSlots++; /* for RETURNING projection */
785-
786-
estate->es_tupleTable = ExecCreateTupleTable(nSlots);
787-
788-
if (operation != CMD_SELECT)
789-
estate->es_trig_tuple_slot =
790-
ExecAllocTableSlot(estate->es_tupleTable);
791-
}
761+
estate->es_tupleTable = NIL;
762+
if (operation != CMD_SELECT)
763+
estate->es_trig_tuple_slot = ExecInitExtraTupleSlot(estate);
792764

793765
/* mark EvalPlanQual not active */
794766
estate->es_plannedstmt = plannedstmt;
@@ -909,7 +881,7 @@ InitPlan(QueryDesc *queryDesc, int eflags)
909881

910882
j = ExecInitJunkFilter(subplan->plan->targetlist,
911883
resultRelInfo->ri_RelationDesc->rd_att->tdhasoid,
912-
ExecAllocTableSlot(estate->es_tupleTable));
884+
ExecInitExtraTupleSlot(estate));
913885

914886
/*
915887
* Since it must be UPDATE/DELETE, there had better be a
@@ -953,7 +925,7 @@ InitPlan(QueryDesc *queryDesc, int eflags)
953925

954926
j = ExecInitJunkFilter(planstate->plan->targetlist,
955927
tupType->tdhasoid,
956-
ExecAllocTableSlot(estate->es_tupleTable));
928+
ExecInitExtraTupleSlot(estate));
957929
estate->es_junkFilter = j;
958930
if (estate->es_result_relation_info)
959931
estate->es_result_relation_info->ri_junkFilter = j;
@@ -1026,7 +998,7 @@ InitPlan(QueryDesc *queryDesc, int eflags)
1026998
false);
1027999

10281000
/* Set up a slot for the output of the RETURNING projection(s) */
1029-
slot = ExecAllocTableSlot(estate->es_tupleTable);
1001+
slot = ExecInitExtraTupleSlot(estate);
10301002
ExecSetSlotDescriptor(slot, tupType);
10311003
/* Need an econtext too */
10321004
econtext = CreateExprContext(estate);
@@ -1387,10 +1359,12 @@ ExecEndPlan(PlanState *planstate, EState *estate)
13871359
}
13881360

13891361
/*
1390-
* destroy the executor "tuple" table.
1362+
* destroy the executor's tuple table. Actually we only care about
1363+
* releasing buffer pins and tupdesc refcounts; there's no need to
1364+
* pfree the TupleTableSlots, since the containing memory context
1365+
* is about to go away anyway.
13911366
*/
1392-
ExecDropTupleTable(estate->es_tupleTable, true);
1393-
estate->es_tupleTable = NULL;
1367+
ExecResetTupleTable(estate->es_tupleTable, false);
13941368

13951369
/*
13961370
* close the result relation(s) if any, but hold locks until xact commit.
@@ -2712,10 +2686,9 @@ EvalPlanQualStart(evalPlanQual *epq, EState *estate, evalPlanQual *priorepq)
27122686
epqstate->es_evTuple = priorepq->estate->es_evTuple;
27132687

27142688
/*
2715-
* Create sub-tuple-table; we needn't redo the CountSlots work though.
2689+
* Each epqstate also has its own tuple table.
27162690
*/
2717-
epqstate->es_tupleTable =
2718-
ExecCreateTupleTable(estate->es_tupleTable->size);
2691+
epqstate->es_tupleTable = NIL;
27192692

27202693
/*
27212694
* Initialize private state information for each SubPlan. We must do this
@@ -2770,8 +2743,9 @@ EvalPlanQualStop(evalPlanQual *epq)
27702743
ExecEndNode(subplanstate);
27712744
}
27722745

2773-
ExecDropTupleTable(epqstate->es_tupleTable, true);
2774-
epqstate->es_tupleTable = NULL;
2746+
/* throw away the per-epqstate tuple table completely */
2747+
ExecResetTupleTable(epqstate->es_tupleTable, true);
2748+
epqstate->es_tupleTable = NIL;
27752749

27762750
if (epqstate->es_evTuple[epq->rti - 1] != NULL)
27772751
{

0 commit comments

Comments
 (0)