From: Robert Haas Date: Fri, 6 Jun 2025 19:22:13 +0000 (-0400) Subject: Look through Gather and Gather Merge nodes. X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=2883eba2edf70b44a21ad7c1573582a1adb92a07;p=users%2Frhaas%2Fpostgres.git Look through Gather and Gather Merge nodes. --- 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;