1
0
mirror of https://github.com/postgres/postgres.git synced 2026-10-23 13:29:09 +03:00

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.

Author: Richard Guo <guofenglinux@gmail.com>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Discussion: https://postgr.es/m/CAMbWs49H275KzgZr3Cd1Hy+6Lmwp35bZ+5PrVc62k3HDLj6hNQ@mail.gmail.com
Backpatch-through: 16
This commit is contained in:
Richard Guo
2026-07-20 12:13:11 +09:00
parent 3e1fe25e68
commit d610d8e8be

View File

@@ -3290,16 +3290,18 @@ report_reduced_full_join(reduce_outer_joins_pass2_state *state2,
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));
@@ -3369,7 +3371,8 @@ remove_useless_result_rtes(PlannerInfo *root)
* (Note that in some cases, parent_quals points to the quals of a parent
* more than one level up in the tree.)
*
* baserels is the set of base (non-join) RT indexes in the whole jointree.
* baserels is the set of base (non-join) RT indexes in the whole jointree;
* it can be NULL if the query contains no PHVs.
*/
static Node *
remove_useless_results_recurse(PlannerInfo *root, Node *jtnode,
@@ -3710,7 +3713,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
@@ -3722,7 +3727,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;