mirror of
https://github.com/postgres/postgres.git
synced 2025-10-29 22:49:41 +03:00
Change more places to be less trusting of RestrictInfo.is_pushed_down.
On further reflection, commit e5d83995e didn't go far enough: pretty much
everywhere in the planner that examines a clause's is_pushed_down flag
ought to be changed to use the more complicated behavior where we also
check the clause's required_relids. Otherwise we could make incorrect
decisions about whether, say, a clause is safe to use as a hash clause.
Some (many?) of these places are safe as-is, either because they are
never reached while considering a parameterized path, or because there
are additional checks that would reject a pushed-down clause anyway.
However, it seems smarter to just code them all the same way rather
than rely on easily-broken reasoning of that sort.
In support of that, invent a new macro RINFO_IS_PUSHED_DOWN that should
be used in place of direct tests on the is_pushed_down flag.
Like the previous patch, back-patch to all supported branches.
Discussion: https://postgr.es/m/f8128b11-c5bf-3539-48cd-234178b2314d@proxel.se
This commit is contained in:
@@ -1789,7 +1789,8 @@ typedef struct LimitPath
|
||||
* if we decide that it can be pushed down into the nullable side of the join.
|
||||
* In that case it acts as a plain filter qual for wherever it gets evaluated.
|
||||
* (In short, is_pushed_down is only false for non-degenerate outer join
|
||||
* conditions. Possibly we should rename it to reflect that meaning?)
|
||||
* conditions. Possibly we should rename it to reflect that meaning? But
|
||||
* see also the comments for RINFO_IS_PUSHED_DOWN, below.)
|
||||
*
|
||||
* RestrictInfo nodes also contain an outerjoin_delayed flag, which is true
|
||||
* if the clause's applicability must be delayed due to any outer joins
|
||||
@@ -1931,6 +1932,20 @@ typedef struct RestrictInfo
|
||||
Selectivity right_mcvfreq; /* right side's most common val's freq */
|
||||
} RestrictInfo;
|
||||
|
||||
/*
|
||||
* This macro embodies the correct way to test whether a RestrictInfo is
|
||||
* "pushed down" to a given outer join, that is, should be treated as a filter
|
||||
* clause rather than a join clause at that outer join. This is certainly so
|
||||
* if is_pushed_down is true; but examining that is not sufficient anymore,
|
||||
* because outer-join clauses will get pushed down to lower outer joins when
|
||||
* we generate a path for the lower outer join that is parameterized by the
|
||||
* LHS of the upper one. We can detect such a clause by noting that its
|
||||
* required_relids exceed the scope of the join.
|
||||
*/
|
||||
#define RINFO_IS_PUSHED_DOWN(rinfo, joinrelids) \
|
||||
((rinfo)->is_pushed_down || \
|
||||
!bms_is_subset((rinfo)->required_relids, joinrelids))
|
||||
|
||||
/*
|
||||
* Since mergejoinscansel() is a relatively expensive function, and would
|
||||
* otherwise be invoked many times while planning a large join tree,
|
||||
|
||||
@@ -115,7 +115,8 @@ extern bool have_join_order_restriction(PlannerInfo *root,
|
||||
extern bool have_dangerous_phv(PlannerInfo *root,
|
||||
Relids outer_relids, Relids inner_params);
|
||||
extern void mark_dummy_rel(RelOptInfo *rel);
|
||||
extern bool have_partkey_equi_join(RelOptInfo *rel1, RelOptInfo *rel2,
|
||||
extern bool have_partkey_equi_join(RelOptInfo *joinrel,
|
||||
RelOptInfo *rel1, RelOptInfo *rel2,
|
||||
JoinType jointype, List *restrictlist);
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user