1
0
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:
Tom Lane
2018-04-20 15:19:16 -04:00
parent 68c23cba34
commit c792c7db41
10 changed files with 64 additions and 37 deletions

View File

@@ -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,

View File

@@ -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);
/*