diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/executor/nodeGather.c | 22 | ||||
-rw-r--r-- | src/backend/executor/nodeGatherMerge.c | 14 |
2 files changed, 31 insertions, 5 deletions
diff --git a/src/backend/executor/nodeGather.c b/src/backend/executor/nodeGather.c index e45e07f0a1a..c979a557749 100644 --- a/src/backend/executor/nodeGather.c +++ b/src/backend/executor/nodeGather.c @@ -91,10 +91,14 @@ ExecInitGather(Gather *node, EState *estate, int eflags) outerPlanState(gatherstate) = ExecInitNode(outerNode, estate, eflags); tupDesc = ExecGetResultType(outerPlanState(gatherstate)); - /* this node uses tuples from the tuple queue as scan slot */ - gatherstate->ps.scanops = &TTSOpsHeapTuple; - gatherstate->ps.scanopsfixed = true; - gatherstate->ps.scanopsset = true; + /* + * Leader may access ExecProcNode result directly (if + * need_to_scan_locally), or from workers via tuple queue. So we can't + * trivially rely on the slot type being fixed for expressions evaluated + * within this node. + */ + gatherstate->ps.outeropsset = true; + gatherstate->ps.outeropsfixed = false; /* * Initialize result type and projection. @@ -103,6 +107,16 @@ ExecInitGather(Gather *node, EState *estate, int eflags) ExecConditionalAssignProjectionInfo(&gatherstate->ps, tupDesc, OUTER_VAR); /* + * Without projections result slot type is not trivially known, see + * comment above. + */ + if (gatherstate->ps.ps_ProjInfo == NULL) + { + gatherstate->ps.resultopsset = true; + gatherstate->ps.resultopsfixed = false; + } + + /* * Initialize funnel slot to same tuple descriptor as outer plan. */ gatherstate->funnel_slot = ExecInitExtraTupleSlot(estate, tupDesc, diff --git a/src/backend/executor/nodeGatherMerge.c b/src/backend/executor/nodeGatherMerge.c index 651565123be..51d910bd5ee 100644 --- a/src/backend/executor/nodeGatherMerge.c +++ b/src/backend/executor/nodeGatherMerge.c @@ -110,6 +110,15 @@ ExecInitGatherMerge(GatherMerge *node, EState *estate, int eflags) outerPlanState(gm_state) = ExecInitNode(outerNode, estate, eflags); /* + * Leader may access ExecProcNode result directly (if + * need_to_scan_locally), or from workers via tuple queue. So we can't + * trivially rely on the slot type being fixed for expressions evaluated + * within this node. + */ + gm_state->ps.outeropsset = true; + gm_state->ps.outeropsfixed = false; + + /* * Store the tuple descriptor into gather merge state, so we can use it * while initializing the gather merge slots. */ @@ -122,7 +131,10 @@ ExecInitGatherMerge(GatherMerge *node, EState *estate, int eflags) ExecInitResultTypeTL(&gm_state->ps); ExecConditionalAssignProjectionInfo(&gm_state->ps, tupDesc, OUTER_VAR); - /* leader accesses ExecProcNode result directly, others go through tuple queue */ + /* + * Without projections result slot type is not trivially known, see + * comment above. + */ if (gm_state->ps.ps_ProjInfo == NULL) { gm_state->ps.resultopsset = true; |