diff options
| author | Tom Lane | 2018-04-20 19:19:17 +0000 |
|---|---|---|
| committer | Tom Lane | 2018-04-20 19:19:17 +0000 |
| commit | 58fec95268dc925b8ae77dd50589c004b43202ba (patch) | |
| tree | 35b308c0e3dc19ae7ae47e194c4ae5c51b877585 /src/include/nodes | |
| parent | a347d5210ef0330b911e31c6249e4318d933b27b (diff) | |
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
Diffstat (limited to 'src/include/nodes')
| -rw-r--r-- | src/include/nodes/relation.h | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index eda8dac56bd..47826c87c44 100644 --- a/src/include/nodes/relation.h +++ b/src/include/nodes/relation.h @@ -1118,7 +1118,8 @@ typedef struct HashPath * 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 @@ -1246,6 +1247,20 @@ typedef struct RestrictInfo } 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, * we go out of our way to cache its results. Each mergejoinable |
