From d7662fd757b382383942bdd6ae0a9ea9f05ce2df Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Tue, 7 Jun 2016 16:43:31 +0300 Subject: [PATCH] Don't call ExecAssignScanProjectionInfo while in partitionMemoryContext. This allows removing the weird pfree() of the resultTupleSlot's tuple descriptor. What would've happened without the pfree() is that the old slot was allocated in the first ExecAssignScanProjectionInfo() call, in partitionMemoryContext, and then immediately destroyed when the memory context was reset. The second call to ExecAssignScanProjectionInfo() tries to free the slot, again, causing the segfault. But we can avoid that by this rearrangement of the calls in a cleaner way. In the passing, clean up the code a bit. I found having separate variables, indexState and scanState, which point to the same struct, to be confusing. --- src/backend/executor/nodeDynamicIndexscan.c | 33 ++++++--------------- 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/src/backend/executor/nodeDynamicIndexscan.c b/src/backend/executor/nodeDynamicIndexscan.c index 83183542f0..9b65fe418d 100644 --- a/src/backend/executor/nodeDynamicIndexscan.c +++ b/src/backend/executor/nodeDynamicIndexscan.c @@ -142,8 +142,8 @@ static bool initNextIndexToScan(DynamicIndexScanState *node) { IndexScanState *indexState = &(node->indexScanState); - DynamicIndexScan *dynamicIndexScan = (DynamicIndexScan *)node->indexScanState.ss.ps.plan; + EState *estate = indexState->ss.ps.state; /* Load new index when the scanning of the previous index is done. */ if (indexState->ss.scan_state == SCAN_INIT || @@ -186,18 +186,18 @@ initNextIndexToScan(DynamicIndexScanState *node) ExecAssignScanType(&indexState->ss, RelationGetDescr(currentRelation)); - ScanState *scanState = (ScanState *)node; + /* + * Initialize result tuple type and projection info. + */ + ExecAssignResultTypeFromTL(&indexState->ss.ps); + ExecAssignScanProjectionInfo(&indexState->ss); MemoryContextReset(node->partitionMemoryContext); MemoryContext oldCxt = MemoryContextSwitchTo(node->partitionMemoryContext); /* Initialize child expressions */ - scanState->ps.qual = (List *)ExecInitExpr((Expr *)scanState->ps.plan->qual, (PlanState*)scanState); - scanState->ps.targetlist = (List *)ExecInitExpr((Expr *)scanState->ps.plan->targetlist, (PlanState*)scanState); - - ExecAssignScanProjectionInfo(scanState); - - EState *estate = indexState->ss.ps.state; + indexState->ss.ps.qual = (List *) ExecInitExpr((Expr *) indexState->ss.ps.plan->qual, (PlanState *) indexState); + indexState->ss.ps.targetlist = (List *) ExecInitExpr((Expr *) indexState->ss.ps.plan->targetlist, (PlanState *) indexState); indexState->iss_RelationDesc = OpenIndexRelation(estate, pindex, *pid); @@ -219,29 +219,14 @@ initNextIndexToScan(DynamicIndexScanState *node) MemoryContextSwitchTo(oldCxt); - ExprContext *econtext = indexState->iss_RuntimeContext; /* context for runtime keys */ - if (indexState->iss_NumRuntimeKeys != 0) { - ExecIndexEvalRuntimeKeys(econtext, + ExecIndexEvalRuntimeKeys(indexState->iss_RuntimeContext, indexState->iss_RuntimeKeys, indexState->iss_NumRuntimeKeys); } - indexState->iss_RuntimeKeysReady = true; - /* - * Initialize result tuple type and projection info. - */ - TupleDesc td = indexState->ss.ps.ps_ResultTupleSlot->tts_tupleDescriptor; - if (td) - { - pfree(td); - td = NULL; - } - ExecAssignResultTypeFromTL(&indexState->ss.ps); - ExecAssignScanProjectionInfo(&indexState->ss); - indexState->iss_ScanDesc = index_beginscan(currentRelation, indexState->iss_RelationDesc, estate->es_snapshot, -- GitLab