From 2883eba2edf70b44a21ad7c1573582a1adb92a07 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Fri, 6 Jun 2025 15:22:13 -0400 Subject: [PATCH] Look through Gather and Gather Merge nodes. --- contrib/pg_plan_advice/pgpa_join.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/contrib/pg_plan_advice/pgpa_join.c b/contrib/pg_plan_advice/pgpa_join.c index d1428cc349..f0054bd0ef 100644 --- a/contrib/pg_plan_advice/pgpa_join.c +++ b/contrib/pg_plan_advice/pgpa_join.c @@ -154,12 +154,15 @@ pgpa_unroll_join(PlannedStmt *pstmt, Plan *plan, Assert(join_unroller != NULL); /* - * We need to pass the join_unroller object down through plan nodes that - * pgpa_decompose_join() regards as part of the join strategy. - * - * XXX. Gather and Gather Merge are going to be a problem here. + * We need to pass the join_unroller object down through certain types + * of plan nodes -- anything that's considered part of the join strategy, + * such as Hash Join's Hash node or a Materialize node inserted on the + * inner side of a nested loop as part of the join strategy -- and also + * Gather and Gather Merge nodes, which can occur in a join tree but + * are not themselves scans or joins. */ - if (IsA(plan, Material) || IsA(plan, Memoize) || IsA(plan, Hash) || IsA(plan, Sort)) + if (IsA(plan, Material) || IsA(plan, Memoize) || IsA(plan, Hash) || + IsA(plan, Sort) || IsA(plan, Gather) || IsA(plan, GatherMerge)) { *outer_join_unroller = join_unroller; return; @@ -392,6 +395,18 @@ pgpa_decompose_join(PlannedStmt *pstmt, Plan *plan, elog(ERROR, "unrecognized node type: %d", (int) nodeTag(plan)); } + if (IsA(outerplan, Gather) || IsA(outerplan, GatherMerge)) + { + outerplan = outerplan->lefttree; + elidedouter = pgpa_last_elided_node(pstmt, outerplan); + } + + if (IsA(innerplan, Gather) || IsA(innerplan, GatherMerge)) + { + innerplan = innerplan->lefttree; + elidedinner = pgpa_last_elided_node(pstmt, innerplan); + } + *realouter = outerplan; *realinner = innerplan; *elidedrealouter = elidedouter; -- 2.39.5