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:
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user