summaryrefslogtreecommitdiff
path: root/src/include/nodes
diff options
context:
space:
mode:
authorTom Lane2018-04-20 19:19:17 +0000
committerTom Lane2018-04-20 19:19:17 +0000
commit58fec95268dc925b8ae77dd50589c004b43202ba (patch)
tree35b308c0e3dc19ae7ae47e194c4ae5c51b877585 /src/include/nodes
parenta347d5210ef0330b911e31c6249e4318d933b27b (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.h17
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