v22-0001-Respect-disabled_nodes-in-fix_alternative_subpla.patch
application/octet-stream
Filename: v22-0001-Respect-disabled_nodes-in-fix_alternative_subpla.patch
Type: application/octet-stream
Part: 3
Message:
Re: pg_plan_advice
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v22-0001
Subject: Respect disabled_nodes in fix_alternative_subplan.
| File | + | − |
|---|---|---|
| src/backend/optimizer/path/costsize.c | 1 | 0 |
| src/backend/optimizer/plan/setrefs.c | 10 | 4 |
| src/include/nodes/primnodes.h | 1 | 0 |
From e892484828a09ce6ca6f8943c7b3e650a53050ce Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Fri, 20 Mar 2026 14:04:41 -0400
Subject: [PATCH v22 1/6] Respect disabled_nodes in fix_alternative_subplan.
When my commit 12444183e40187a9fb6002a3912053f302725f0a added the
concept of disabled_nodes, it failed to add a disabled_nodes field
to SubPlan. This is a regression: before that commit, when
fix_alternative_subplan compared the costs of two plans, the number
of disabled nodes affected the result, because it was just a
component of the total cost. After that commit, it no longer did,
making it possible for a disabled path to win on cost over one that
is not disabled. Fix that.
---
src/backend/optimizer/path/costsize.c | 1 +
src/backend/optimizer/plan/setrefs.c | 14 ++++++++++----
src/include/nodes/primnodes.h | 1 +
3 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/src/backend/optimizer/path/costsize.c b/src/backend/optimizer/path/costsize.c
index 56d45287c89..1c575e56ff6 100644
--- a/src/backend/optimizer/path/costsize.c
+++ b/src/backend/optimizer/path/costsize.c
@@ -4761,6 +4761,7 @@ cost_subplan(PlannerInfo *root, SubPlan *subplan, Plan *plan)
sp_cost.per_tuple += plan->startup_cost;
}
+ subplan->disabled_nodes = plan->disabled_nodes;
subplan->startup_cost = sp_cost.startup;
subplan->per_call_cost = sp_cost.per_tuple;
}
diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c
index 1b5b9b5ed9c..ff0e875f2a2 100644
--- a/src/backend/optimizer/plan/setrefs.c
+++ b/src/backend/optimizer/plan/setrefs.c
@@ -2234,9 +2234,12 @@ fix_alternative_subplan(PlannerInfo *root, AlternativeSubPlan *asplan,
/*
* Compute the estimated cost of each subplan assuming num_exec
- * executions, and keep the cheapest one. In event of exact equality of
- * estimates, we prefer the later plan; this is a bit arbitrary, but in
- * current usage it biases us to break ties against fast-start subplans.
+ * executions, and keep the cheapest one. If one subplan has more
+ * disabled nodes than another, choose the one with fewer disabled nodes
+ * regardless of cost; this parallels compare_path_costs. In event of
+ * exact equality of estimates, we prefer the later plan; this is a bit
+ * arbitrary, but in current usage it biases us to break ties against
+ * fast-start subplans.
*/
Assert(asplan->subplans != NIL);
@@ -2246,7 +2249,10 @@ fix_alternative_subplan(PlannerInfo *root, AlternativeSubPlan *asplan,
Cost curcost;
curcost = curplan->startup_cost + num_exec * curplan->per_call_cost;
- if (bestplan == NULL || curcost <= bestcost)
+ if (bestplan == NULL ||
+ curplan->disabled_nodes < bestplan->disabled_nodes ||
+ (curplan->disabled_nodes == bestplan->disabled_nodes &&
+ curcost <= bestcost))
{
bestplan = curplan;
bestcost = curcost;
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index b67e56e6c5a..f5b6b45664a 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -1124,6 +1124,7 @@ typedef struct SubPlan
List *parParam; /* indices of input Params from parent plan */
List *args; /* exprs to pass as parParam values */
/* Estimated execution costs: */
+ int disabled_nodes; /* count of disabled nodes in the plan */
Cost startup_cost; /* one-time setup cost */
Cost per_call_cost; /* cost for each subplan evaluation */
} SubPlan;
--
2.51.0