summaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorTom Lane2023-05-25 14:28:33 +0000
committerTom Lane2023-05-25 14:28:33 +0000
commit991a3df227e9e8b16d7399df3961dfaae4ae677c (patch)
tree4b2fc9552e81e3d0c659df6970f9e2c4a631d767 /src/include
parent913b3da6aeda3f887b8796d8098d7227d32580b9 (diff)
Fix filtering of "cloned" outer-join quals some more.
We've had multiple issues with the clause_is_computable_at logic that I introduced in 2489d76c4: it's been known to accept more than one clone of the same qual at the same plan node, and also to accept no clones at all. It's looking impractical to get it 100% right on the basis of the currently-stored information, so fix it by introducing a new RestrictInfo field "incompatible_relids" that explicitly shows which outer joins a given clone mustn't be pushed above. In principle we could populate this field in every RestrictInfo, but that would cost space and there doesn't presently seem to be a need for it in general. Also, while deconstruct_distribute_oj_quals can easily fill the field with the remaining members of the commutative join set that it's considering, computing it in the general case seems again pretty complicated. So for now, just fill it for clone quals. Along the way, fix a bug that may or may not be only latent: equivclass.c was generating replacement clauses with is_pushed_down and has_clone/is_clone markings that didn't match their required_relids. This led me to conclude that leaving the clone flags out of make_restrictinfo's purview wasn't such a great idea after all, so add them. Per report from Richard Guo. Discussion: https://postgr.es/m/CAMbWs48EYi_9-pSd0ORes1kTmTeAjT4Q3gu49hJtYCbSn2JyeA@mail.gmail.com
Diffstat (limited to 'src/include')
-rw-r--r--src/include/nodes/pathnodes.h12
-rw-r--r--src/include/optimizer/restrictinfo.h9
2 files changed, 17 insertions, 4 deletions
diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h
index 23dd671bf4e..c17b53f7adb 100644
--- a/src/include/nodes/pathnodes.h
+++ b/src/include/nodes/pathnodes.h
@@ -2430,6 +2430,15 @@ typedef struct LimitPath
* conditions. Possibly we should rename it to reflect that meaning? But
* see also the comments for RINFO_IS_PUSHED_DOWN, below.)
*
+ * There is also an incompatible_relids field, which is a set of outer-join
+ * relids above which we cannot evaluate the clause (because they might null
+ * Vars it uses that should not be nulled yet). In principle this could be
+ * filled in any RestrictInfo as the set of OJ relids that appear above the
+ * clause and null Vars that it uses. In practice we only bother to populate
+ * it for "clone" clauses, as it's currently only needed to prevent multiple
+ * clones of the same clause from being accepted for evaluation at the same
+ * join level.
+ *
* There is also an outer_relids field, which is NULL except for outer join
* clauses; for those, it is the set of relids on the outer side of the
* clause's outer join. (These are rels that the clause cannot be applied to
@@ -2537,6 +2546,9 @@ typedef struct RestrictInfo
/* The set of relids required to evaluate the clause: */
Relids required_relids;
+ /* Relids above which we cannot evaluate the clause (see comment above) */
+ Relids incompatible_relids;
+
/* If an outer-join clause, the outer-side relations, else NULL: */
Relids outer_relids;
diff --git a/src/include/optimizer/restrictinfo.h b/src/include/optimizer/restrictinfo.h
index 57e7a7999d2..e140e619ace 100644
--- a/src/include/optimizer/restrictinfo.h
+++ b/src/include/optimizer/restrictinfo.h
@@ -19,14 +19,18 @@
/* Convenience macro for the common case of a valid-everywhere qual */
#define make_simple_restrictinfo(root, clause) \
- make_restrictinfo(root, clause, true, false, 0, NULL, NULL)
+ make_restrictinfo(root, clause, true, false, false, false, 0, \
+ NULL, NULL, NULL)
extern RestrictInfo *make_restrictinfo(PlannerInfo *root,
Expr *clause,
bool is_pushed_down,
+ bool has_clone,
+ bool is_clone,
bool pseudoconstant,
Index security_level,
Relids required_relids,
+ Relids incompatible_relids,
Relids outer_relids);
extern RestrictInfo *commute_restrictinfo(RestrictInfo *rinfo, Oid comm_op);
extern bool restriction_is_or_clause(RestrictInfo *restrictinfo);
@@ -39,9 +43,6 @@ extern void extract_actual_join_clauses(List *restrictinfo_list,
Relids joinrelids,
List **joinquals,
List **otherquals);
-extern bool clause_is_computable_at(PlannerInfo *root,
- RestrictInfo *rinfo,
- Relids eval_relids);
extern bool join_clause_is_movable_to(RestrictInfo *rinfo, RelOptInfo *baserel);
extern bool join_clause_is_movable_into(RestrictInfo *rinfo,
Relids currentrelids,