From 2a2134c07ebb3e53108f695570f2cb3df59f799a Mon Sep 17 00:00:00 2001 From: Richard Guo Date: Mon, 20 Jul 2026 11:11:11 +0900 Subject: [PATCH v1] Skip unnecessary get_relids_in_jointree() when there are no PHVs Commit 1df9e8d96 made remove_useless_result_rtes() compute the set of baserels in the jointree, to pass down to the find_dependent_phvs() checks. But those checks are no-ops when the query contains no PHVs, since find_dependent_phvs() and find_dependent_phvs_in_jointree() both return early in that case. So we can avoid the get_relids_in_jointree() scan altogether when root->glob->lastPHId is zero, leaving baserels as NULL. --- src/backend/optimizer/prep/prepjointree.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c index 1ea72af7c73..53432c2f648 100644 --- a/src/backend/optimizer/prep/prepjointree.c +++ b/src/backend/optimizer/prep/prepjointree.c @@ -3888,16 +3888,18 @@ has_notnull_forced_var(PlannerInfo *root, List *forced_null_vars, void remove_useless_result_rtes(PlannerInfo *root) { - Relids baserels; + Relids baserels = NULL; Relids dropped_outer_joins = NULL; ListCell *cell; /* * We'll need the set of baserels in the jointree to perform - * find_dependent_phvs() checks. + * find_dependent_phvs() checks. But if there are no PHVs anywhere in the + * query, those checks are no-ops, so we can skip the work. */ - baserels = get_relids_in_jointree((Node *) root->parse->jointree, - false, false); + if (root->glob->lastPHId != 0) + baserels = get_relids_in_jointree((Node *) root->parse->jointree, + false, false); /* Top level of jointree must always be a FromExpr */ Assert(IsA(root->parse->jointree, FromExpr)); @@ -4308,7 +4310,9 @@ remove_result_refs(PlannerInfo *root, int varno, Node *newjtloc) * already decided to remove those joins in remove_useless_result_rtes * and not yet have cleaned their relid bits out of upper PHVs. * But in general, it's the set of baserels that identify possible places - * to evaluate a PHV, and we mustn't let that go to empty. + * to evaluate a PHV, and we mustn't let that go to empty. (The caller is + * allowed to pass baserels as NULL if the query contains no PHVs at all, + * since then there is no work to do anyway.) * * find_dependent_phvs should be used when we want to see if there are * any such PHVs anywhere in the Query. Another use-case is to see if @@ -4320,7 +4324,7 @@ remove_result_refs(PlannerInfo *root, int varno, Node *newjtloc) typedef struct { Relids relids; /* target relid, represented as a relid set */ - Relids baserels; /* set of base (non-OJ) RT indexes in query */ + Relids baserels; /* base RT indexes in query, NULL if no PHVs */ int sublevels_up; /* current nesting level */ } find_dependent_phvs_context; -- 2.39.5 (Apple Git-154)