Skip to content

Commit 9eeac0b

Browse files
committed
Fix crash in explain with append info for ShareInputScan nodes.
The issue occurs when ShareInputScan nodes are reused multiple times during explain with append info in deparse_context_for_plan_tree(). Address that by marking only the producer of ShareInputScan with the same share_id to prevent the crash. This ensures proper handling of shared scan nodes during plan tree deparsing. Authored-by: Zhang Mingli [email protected]
1 parent 889859d commit 9eeac0b

File tree

7 files changed

+24
-0
lines changed

7 files changed

+24
-0
lines changed

src/backend/cdb/cdbmutate.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,8 @@ shareinput_save_producer(ShareInputScan *plan, ApplyShareInputContext *ctxt)
659659
ctxt->shared_input_count = new_shared_input_count;
660660
}
661661

662+
plan->ref_set = true;
663+
662664
Assert(ctxt->shared_plans[share_id] == NULL);
663665
ctxt->shared_plans[share_id] = plan->scan.plan.lefttree;
664666
}

src/backend/nodes/copyfuncs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,6 +1262,7 @@ _copyShareInputScan(const ShareInputScan *from)
12621262
COPY_SCALAR_FIELD(this_slice_id);
12631263
COPY_SCALAR_FIELD(nconsumers);
12641264
COPY_SCALAR_FIELD(discard_output);
1265+
COPY_SCALAR_FIELD(ref_set);
12651266

12661267
return newnode;
12671268
}

src/backend/nodes/outfuncs_common.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ _outShareInputScan(StringInfo str, const ShareInputScan *node)
398398
WRITE_INT_FIELD(this_slice_id);
399399
WRITE_INT_FIELD(nconsumers);
400400
WRITE_BOOL_FIELD(discard_output);
401+
WRITE_BOOL_FIELD(ref_set);
401402

402403
_outPlanInfo(str, (Plan *) node);
403404
}

src/backend/nodes/readfast.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,6 +1002,7 @@ _readShareInputScan(void)
10021002
READ_INT_FIELD(this_slice_id);
10031003
READ_INT_FIELD(nconsumers);
10041004
READ_BOOL_FIELD(discard_output);
1005+
READ_BOOL_FIELD(ref_set);
10051006

10061007
ReadCommonPlan(&local_node->scan.plan);
10071008

src/backend/optimizer/plan/planshare.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ make_shareinputscan(PlannerInfo *root, Plan *inputplan)
4040
sisc->this_slice_id = -1;
4141
sisc->nconsumers = 0;
4242
sisc->discard_output = false;
43+
sisc->ref_set = false;
4344

4445
sisc->scan.plan.qual = NIL;
4546
sisc->scan.plan.righttree = NULL;

src/backend/optimizer/plan/setrefs.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,7 @@ set_plan_references(PlannerInfo *root, Plan *plan)
387387
PlannerGlobal *glob = root->glob;
388388
int rtoffset = list_length(glob->finalrtable);
389389
ListCell *lc;
390+
bool need_append_rel = true;
390391

391392
#ifdef USE_ASSERT_CHECKING
392393
/*
@@ -422,6 +423,17 @@ set_plan_references(PlannerInfo *root, Plan *plan)
422423
glob->finalrowmarks = lappend(glob->finalrowmarks, newrc);
423424
}
424425

426+
/*
427+
* ShareInputScan nodes can be reused multiple times during execution, but this
428+
* causes a crash when explaining plans with append info in the function
429+
* deparse_context_for_plan_tree().
430+
*
431+
* To fix this, we only add appendrels for the producer ShareInputScan node of
432+
* a given share_id, rather than all nodes with the same share_id.
433+
*/
434+
if (plan != NULL && IsA(plan, ShareInputScan))
435+
need_append_rel = ((ShareInputScan *) plan)->ref_set;
436+
425437
/*
426438
* Adjust RT indexes of AppendRelInfos and add to final appendrels list.
427439
* We assume the AppendRelInfos were built during planning and don't need
@@ -431,6 +443,9 @@ set_plan_references(PlannerInfo *root, Plan *plan)
431443
{
432444
AppendRelInfo *appinfo = lfirst_node(AppendRelInfo, lc);
433445

446+
if (!need_append_rel)
447+
break;
448+
434449
/* adjust RT indexes */
435450
appinfo->parent_relid += rtoffset;
436451
appinfo->child_relid += rtoffset;

src/include/nodes/plannodes.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,6 +1245,9 @@ typedef struct ShareInputScan
12451245

12461246
/* Discard the scan output? True for ORCA CTE producer, false otherwise. */
12471247
bool discard_output;
1248+
1249+
/* Could be set reference? */
1250+
bool ref_set;
12481251
} ShareInputScan;
12491252

12501253
/* ----------------

0 commit comments

Comments
 (0)