Skip to content

Commit

Permalink
Remove obsolete executor cleanup code
Browse files Browse the repository at this point in the history
This commit removes unnecessary ExecExprFreeContext() calls in
ExecEnd* routines because the actual cleanup is managed by
FreeExecutorState(). With no callers remaining for
ExecExprFreeContext(), this commit also removes the function.

This commit also drops redundant ExecClearTuple() calls, because
ExecResetTupleTable() in ExecEndPlan() already takes care of
resetting and dropping all TupleTableSlots initialized with
ExecInitScanTupleSlot() and ExecInitExtraTupleSlot().

After these modifications, the ExecEnd*() routines for ValuesScan,
NamedTuplestoreScan, and WorkTableScan became redundant. So, this
commit removes them.

Reviewed-by: Robert Haas
Discussion: https://postgr.es/m/CA+HiwqFGkMSge6TgC9KQzde0ohpAycLQuV7ooitEEpbKB0O_mg@mail.gmail.com
  • Loading branch information
amitlan committed Sep 28, 2023
1 parent 9210afd commit d060e92
Show file tree
Hide file tree
Showing 42 changed files with 6 additions and 419 deletions.
18 changes: 6 additions & 12 deletions src/backend/executor/execProcnode.c
Expand Up @@ -667,22 +667,10 @@ ExecEndNode(PlanState *node)
ExecEndTableFuncScan((TableFuncScanState *) node);
break;

case T_ValuesScanState:
ExecEndValuesScan((ValuesScanState *) node);
break;

case T_CteScanState:
ExecEndCteScan((CteScanState *) node);
break;

case T_NamedTuplestoreScanState:
ExecEndNamedTuplestoreScan((NamedTuplestoreScanState *) node);
break;

case T_WorkTableScanState:
ExecEndWorkTableScan((WorkTableScanState *) node);
break;

case T_ForeignScanState:
ExecEndForeignScan((ForeignScanState *) node);
break;
Expand Down Expand Up @@ -757,6 +745,12 @@ ExecEndNode(PlanState *node)
ExecEndLimit((LimitState *) node);
break;

/* No clean up actions for these nodes. */
case T_ValuesScanState:
case T_NamedTuplestoreScanState:
case T_WorkTableScanState:
break;

default:
elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node));
break;
Expand Down
26 changes: 0 additions & 26 deletions src/backend/executor/execUtils.c
Expand Up @@ -638,32 +638,6 @@ tlist_matches_tupdesc(PlanState *ps, List *tlist, int varno, TupleDesc tupdesc)
return true;
}

/* ----------------
* ExecFreeExprContext
*
* A plan node's ExprContext should be freed explicitly during executor
* shutdown because there may be shutdown callbacks to call. (Other resources
* made by the above routines, such as projection info, don't need to be freed
* explicitly because they're just memory in the per-query memory context.)
*
* However ... there is no particular need to do it during ExecEndNode,
* because FreeExecutorState will free any remaining ExprContexts within
* the EState. Letting FreeExecutorState do it allows the ExprContexts to
* be freed in reverse order of creation, rather than order of creation as
* will happen if we delete them here, which saves O(N^2) work in the list
* cleanup inside FreeExprContext.
* ----------------
*/
void
ExecFreeExprContext(PlanState *planstate)
{
/*
* Per above discussion, don't actually delete the ExprContext. We do
* unlink it from the plan node, though.
*/
planstate->ps_ExprContext = NULL;
}


/* ----------------------------------------------------------------
* Scan node support
Expand Down
10 changes: 0 additions & 10 deletions src/backend/executor/nodeAgg.c
Expand Up @@ -4357,16 +4357,6 @@ ExecEndAgg(AggState *node)
if (node->hashcontext)
ReScanExprContext(node->hashcontext);

/*
* We don't actually free any ExprContexts here (see comment in
* ExecFreeExprContext), just unlinking the output one from the plan node
* suffices.
*/
ExecFreeExprContext(&node->ss.ps);

/* clean up tuple table */
ExecClearTuple(node->ss.ss_ScanTupleSlot);

outerPlan = outerPlanState(node);
ExecEndNode(outerPlan);
}
Expand Down
12 changes: 0 additions & 12 deletions src/backend/executor/nodeBitmapHeapscan.c
Expand Up @@ -655,18 +655,6 @@ ExecEndBitmapHeapScan(BitmapHeapScanState *node)
*/
scanDesc = node->ss.ss_currentScanDesc;

/*
* Free the exprcontext
*/
ExecFreeExprContext(&node->ss.ps);

/*
* clear out tuple table slots
*/
if (node->ss.ps.ps_ResultTupleSlot)
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
ExecClearTuple(node->ss.ss_ScanTupleSlot);

/*
* close down subplans
*/
Expand Down
8 changes: 0 additions & 8 deletions src/backend/executor/nodeBitmapIndexscan.c
Expand Up @@ -184,14 +184,6 @@ ExecEndBitmapIndexScan(BitmapIndexScanState *node)
indexRelationDesc = node->biss_RelationDesc;
indexScanDesc = node->biss_ScanDesc;

/*
* Free the exprcontext ... now dead code, see ExecFreeExprContext
*/
#ifdef NOT_USED
if (node->biss_RuntimeContext)
FreeExprContext(node->biss_RuntimeContext, true);
#endif

/*
* close the index relation (no-op if we didn't open it)
*/
Expand Down
12 changes: 0 additions & 12 deletions src/backend/executor/nodeCtescan.c
Expand Up @@ -287,18 +287,6 @@ ExecInitCteScan(CteScan *node, EState *estate, int eflags)
void
ExecEndCteScan(CteScanState *node)
{
/*
* Free exprcontext
*/
ExecFreeExprContext(&node->ss.ps);

/*
* clean out the tuple table
*/
if (node->ss.ps.ps_ResultTupleSlot)
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
ExecClearTuple(node->ss.ss_ScanTupleSlot);

/*
* If I am the leader, free the tuplestore.
*/
Expand Down
7 changes: 0 additions & 7 deletions src/backend/executor/nodeCustom.c
Expand Up @@ -129,13 +129,6 @@ ExecEndCustomScan(CustomScanState *node)
{
Assert(node->methods->EndCustomScan != NULL);
node->methods->EndCustomScan(node);

/* Free the exprcontext */
ExecFreeExprContext(&node->ss.ps);

/* Clean out the tuple table */
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
ExecClearTuple(node->ss.ss_ScanTupleSlot);
}

void
Expand Down
8 changes: 0 additions & 8 deletions src/backend/executor/nodeForeignscan.c
Expand Up @@ -312,14 +312,6 @@ ExecEndForeignScan(ForeignScanState *node)
/* Shut down any outer plan. */
if (outerPlanState(node))
ExecEndNode(outerPlanState(node));

/* Free the exprcontext */
ExecFreeExprContext(&node->ss.ps);

/* clean out the tuple table */
if (node->ss.ps.ps_ResultTupleSlot)
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
ExecClearTuple(node->ss.ss_ScanTupleSlot);
}

/* ----------------------------------------------------------------
Expand Down
15 changes: 0 additions & 15 deletions src/backend/executor/nodeFunctionscan.c
Expand Up @@ -523,28 +523,13 @@ ExecEndFunctionScan(FunctionScanState *node)
{
int i;

/*
* Free the exprcontext
*/
ExecFreeExprContext(&node->ss.ps);

/*
* clean out the tuple table
*/
if (node->ss.ps.ps_ResultTupleSlot)
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
ExecClearTuple(node->ss.ss_ScanTupleSlot);

/*
* Release slots and tuplestore resources
*/
for (i = 0; i < node->nfuncs; i++)
{
FunctionScanPerFuncState *fs = &node->funcstates[i];

if (fs->func_slot)
ExecClearTuple(fs->func_slot);

if (fs->tstore != NULL)
{
tuplestore_end(node->funcstates[i].tstore);
Expand Down
3 changes: 0 additions & 3 deletions src/backend/executor/nodeGather.c
Expand Up @@ -250,9 +250,6 @@ ExecEndGather(GatherState *node)
{
ExecEndNode(outerPlanState(node)); /* let children clean up first */
ExecShutdownGather(node);
ExecFreeExprContext(&node->ps);
if (node->ps.ps_ResultTupleSlot)
ExecClearTuple(node->ps.ps_ResultTupleSlot);
}

/*
Expand Down
3 changes: 0 additions & 3 deletions src/backend/executor/nodeGatherMerge.c
Expand Up @@ -290,9 +290,6 @@ ExecEndGatherMerge(GatherMergeState *node)
{
ExecEndNode(outerPlanState(node)); /* let children clean up first */
ExecShutdownGatherMerge(node);
ExecFreeExprContext(&node->ps);
if (node->ps.ps_ResultTupleSlot)
ExecClearTuple(node->ps.ps_ResultTupleSlot);
}

/* ----------------------------------------------------------------
Expand Down
5 changes: 0 additions & 5 deletions src/backend/executor/nodeGroup.c
Expand Up @@ -228,11 +228,6 @@ ExecEndGroup(GroupState *node)
{
PlanState *outerPlan;

ExecFreeExprContext(&node->ss.ps);

/* clean up tuple table */
ExecClearTuple(node->ss.ss_ScanTupleSlot);

outerPlan = outerPlanState(node);
ExecEndNode(outerPlan);
}
Expand Down
5 changes: 0 additions & 5 deletions src/backend/executor/nodeHash.c
Expand Up @@ -415,11 +415,6 @@ ExecEndHash(HashState *node)
{
PlanState *outerPlan;

/*
* free exprcontext
*/
ExecFreeExprContext(&node->ps);

/*
* shut down the subplan
*/
Expand Down
12 changes: 0 additions & 12 deletions src/backend/executor/nodeHashjoin.c
Expand Up @@ -867,18 +867,6 @@ ExecEndHashJoin(HashJoinState *node)
node->hj_HashTable = NULL;
}

/*
* Free the exprcontext
*/
ExecFreeExprContext(&node->js.ps);

/*
* clean out the tuple table
*/
ExecClearTuple(node->js.ps.ps_ResultTupleSlot);
ExecClearTuple(node->hj_OuterTupleSlot);
ExecClearTuple(node->hj_HashTupleSlot);

/*
* clean up subtrees
*/
Expand Down
5 changes: 0 additions & 5 deletions src/backend/executor/nodeIncrementalSort.c
Expand Up @@ -1079,11 +1079,6 @@ ExecEndIncrementalSort(IncrementalSortState *node)
{
SO_printf("ExecEndIncrementalSort: shutting down sort node\n");

/* clean out the scan tuple */
ExecClearTuple(node->ss.ss_ScanTupleSlot);
/* must drop pointer to sort result tuple */
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
/* must drop standalone tuple slots from outer node */
ExecDropSingleTupleTableSlot(node->group_pivot);
ExecDropSingleTupleTableSlot(node->transfer_tuple);

Expand Down
16 changes: 0 additions & 16 deletions src/backend/executor/nodeIndexonlyscan.c
Expand Up @@ -380,22 +380,6 @@ ExecEndIndexOnlyScan(IndexOnlyScanState *node)
node->ioss_VMBuffer = InvalidBuffer;
}

/*
* Free the exprcontext(s) ... now dead code, see ExecFreeExprContext
*/
#ifdef NOT_USED
ExecFreeExprContext(&node->ss.ps);
if (node->ioss_RuntimeContext)
FreeExprContext(node->ioss_RuntimeContext, true);
#endif

/*
* clear out tuple table slots
*/
if (node->ss.ps.ps_ResultTupleSlot)
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
ExecClearTuple(node->ss.ss_ScanTupleSlot);

/*
* close the index relation (no-op if we didn't open it)
*/
Expand Down
16 changes: 0 additions & 16 deletions src/backend/executor/nodeIndexscan.c
Expand Up @@ -794,22 +794,6 @@ ExecEndIndexScan(IndexScanState *node)
indexRelationDesc = node->iss_RelationDesc;
indexScanDesc = node->iss_ScanDesc;

/*
* Free the exprcontext(s) ... now dead code, see ExecFreeExprContext
*/
#ifdef NOT_USED
ExecFreeExprContext(&node->ss.ps);
if (node->iss_RuntimeContext)
FreeExprContext(node->iss_RuntimeContext, true);
#endif

/*
* clear out tuple table slots
*/
if (node->ss.ps.ps_ResultTupleSlot)
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);
ExecClearTuple(node->ss.ss_ScanTupleSlot);

/*
* close the index relation (no-op if we didn't open it)
*/
Expand Down
1 change: 0 additions & 1 deletion src/backend/executor/nodeLimit.c
Expand Up @@ -534,7 +534,6 @@ ExecInitLimit(Limit *node, EState *estate, int eflags)
void
ExecEndLimit(LimitState *node)
{
ExecFreeExprContext(&node->ps);
ExecEndNode(outerPlanState(node));
}

Expand Down
5 changes: 0 additions & 5 deletions src/backend/executor/nodeMaterial.c
Expand Up @@ -239,11 +239,6 @@ ExecInitMaterial(Material *node, EState *estate, int eflags)
void
ExecEndMaterial(MaterialState *node)
{
/*
* clean out the tuple table
*/
ExecClearTuple(node->ss.ss_ScanTupleSlot);

/*
* Release tuplestore resources
*/
Expand Down
9 changes: 0 additions & 9 deletions src/backend/executor/nodeMemoize.c
Expand Up @@ -1091,15 +1091,6 @@ ExecEndMemoize(MemoizeState *node)
/* Remove the cache context */
MemoryContextDelete(node->tableContext);

ExecClearTuple(node->ss.ss_ScanTupleSlot);
/* must drop pointer to cache result tuple */
ExecClearTuple(node->ss.ps.ps_ResultTupleSlot);

/*
* free exprcontext
*/
ExecFreeExprContext(&node->ss.ps);

/*
* shut down the subplan
*/
Expand Down
11 changes: 0 additions & 11 deletions src/backend/executor/nodeMergejoin.c
Expand Up @@ -1643,17 +1643,6 @@ ExecEndMergeJoin(MergeJoinState *node)
MJ1_printf("ExecEndMergeJoin: %s\n",
"ending node processing");

/*
* Free the exprcontext
*/
ExecFreeExprContext(&node->js.ps);

/*
* clean out the tuple table
*/
ExecClearTuple(node->js.ps.ps_ResultTupleSlot);
ExecClearTuple(node->mj_MarkedTupleSlot);

/*
* shut down the subplans
*/
Expand Down
11 changes: 0 additions & 11 deletions src/backend/executor/nodeModifyTable.c
Expand Up @@ -4446,17 +4446,6 @@ ExecEndModifyTable(ModifyTableState *node)
ExecDropSingleTupleTableSlot(node->mt_root_tuple_slot);
}

/*
* Free the exprcontext
*/
ExecFreeExprContext(&node->ps);

/*
* clean out the tuple table
*/
if (node->ps.ps_ResultTupleSlot)
ExecClearTuple(node->ps.ps_ResultTupleSlot);

/*
* Terminate EPQ execution if active
*/
Expand Down

0 comments on commit d060e92

Please sign in to comment.