From e9a8fdaabc4d4e8b900b6bf733296541d9bd74d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Nordstr=C3=B6m?= Date: Tue, 3 Dec 2024 16:16:48 +0100 Subject: [PATCH] Fix error: invalid child of chunk append 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. --- .unreleased/pr_7514 | 1 + src/nodes/chunk_append/planner.c | 21 ++++++--------------- 2 files changed, 7 insertions(+), 15 deletions(-) create mode 100644 .unreleased/pr_7514 diff --git a/.unreleased/pr_7514 b/.unreleased/pr_7514 new file mode 100644 index 00000000000..e7ab40104d7 --- /dev/null +++ b/.unreleased/pr_7514 @@ -0,0 +1 @@ +Fixes: #7514 Fix error: invalid child of chunk append diff --git a/src/nodes/chunk_append/planner.c b/src/nodes/chunk_append/planner.c index 30f694557c4..7f0fb67e9c0 100644 --- a/src/nodes/chunk_append/planner.c +++ b/src/nodes/chunk_append/planner.c @@ -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; @@ -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); @@ -380,13 +376,10 @@ 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) { @@ -394,12 +387,10 @@ ts_chunk_append_get_scan_plan(Plan *plan) /* 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; }