Skip to content

Commit

Permalink
Fix error: invalid child of chunk append
Browse files Browse the repository at this point in the history
When doing startup and runtime chunk exclusion, the chunk append node
could sometimes throw an error: "invalid child of chunk append:
Sort". Unfortunately, this error hasn't been successfully reproduced
in a test but has been reported by users.

However, it seems clear that the error happens in
ts_chunk_append_get_scan_plan() when it can't find a "known" plan node
to use for chunk exclusion. This function should ideally never throw
and error and instead just return NULL, which means that chunk append
falls back to not doing any exclusion instead of throwing an error.

It is also possible to improve the code and make it properly handle
Sort and Result nodes by not special-casing them. By inspecting
ts_chunk_append_get_scan_plan(), it is clear that it can only throw
the error if it encounters a Result node with a Sort child, because in
those two cases it didn't descend down the lefttree child node using a
recursive call. Therefore, remove the special case and instead do a
recursive call similar to how other nodes are handled.
  • Loading branch information
erimatnor committed Dec 11, 2024
1 parent 1be011a commit 38dbe3c
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 15 deletions.
1 change: 1 addition & 0 deletions .unreleased/pr_7514
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixes: #7514 Fix error: invalid child of chunk append
21 changes: 6 additions & 15 deletions src/nodes/chunk_append/planner.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,9 +333,6 @@ make_sort(Plan *lefttree, int numCols, AttrNumber *sortColIdx, Oid *sortOperator
Scan *
ts_chunk_append_get_scan_plan(Plan *plan)
{
if (plan != NULL && (IsA(plan, Sort) || IsA(plan, Result)))
plan = plan->lefttree;

if (plan == NULL)
return NULL;

Expand All @@ -356,7 +353,6 @@ ts_chunk_append_get_scan_plan(Plan *plan)
case T_WorkTableScan:
case T_TidRangeScan:
return (Scan *) plan;
break;
case T_CustomScan:
{
CustomScan *custom = castNode(CustomScan, plan);
Expand All @@ -380,26 +376,21 @@ ts_chunk_append_get_scan_plan(Plan *plan)
*/
return ts_chunk_append_get_scan_plan(linitial(custom->custom_plans));
}

/*
* This is some other unknown custom scan node, we can't recurse
* into it.
*/
return NULL;
break;
}
case T_Sort:
case T_Result:
case T_Agg:
if (plan->lefttree != NULL)
{
Assert(plan->righttree == NULL);
/* Let ts_chunk_append_get_scan_plan handle the subplan */
return ts_chunk_append_get_scan_plan(plan->lefttree);
}
return NULL;
break;
case T_MergeAppend:
return NULL;
default:
elog(ERROR, "invalid child of chunk append: %s", ts_get_node_name((Node *) plan));
break;
}
pg_unreachable();

return NULL;
}

0 comments on commit 38dbe3c

Please sign in to comment.