aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2012-08-31 18:57:12 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2012-08-31 18:57:12 -0400
commitc97a547a4a0913e37e5dd1f026ac3c281326b215 (patch)
tree0bb672e912204f2766cfdcbed1779c63986c1df9
parentda3df998702061b4b63d83d5354b148e812f21f8 (diff)
downloadpostgresql-c97a547a4a0913e37e5dd1f026ac3c281326b215.tar.gz
postgresql-c97a547a4a0913e37e5dd1f026ac3c281326b215.zip
Partially restore qual scope checks in distribute_qual_to_rels().
The LATERAL implementation is now basically complete, and I still don't see a cost-effective way to make an exact qual scope cross-check in the presence of LATERAL. However, I did add a PlannerInfo.hasLateralRTEs flag along the way, so it's easy to make the check only when not hasLateralRTEs. That seems to still be useful, and it beats having no check at all.
-rw-r--r--src/backend/optimizer/plan/initsplan.c28
1 files changed, 13 insertions, 15 deletions
diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c
index 824c6a7e473..f582d4067b9 100644
--- a/src/backend/optimizer/plan/initsplan.c
+++ b/src/backend/optimizer/plan/initsplan.c
@@ -1103,21 +1103,20 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause,
relids = pull_varnos(clause);
/*
- * Cross-check: clause should contain no relids not within its scope.
- * Otherwise the parser messed up.
+ * Normally relids is a subset of qualscope, and we like to check that
+ * here as a crosscheck on the parser and rewriter. That need not be the
+ * case when there are LATERAL RTEs, however: the clause could contain
+ * references to rels outside its syntactic scope as a consequence of
+ * pull-up of such references from a LATERAL subquery below it. So, only
+ * check if the query contains no LATERAL RTEs.
*
- * XXX temporarily disable the qualscope cross-check, which tends to
- * reject quals pulled up from LATERAL subqueries. This is only in the
- * nature of a debugging crosscheck anyway. I'm loath to remove it
- * permanently, but need to think a bit harder about how to replace it.
- * See also disabled Assert below. (The ojscope test is still okay
- * because we prevent pullup of LATERAL subqueries that might cause it to
- * be violated.)
+ * However, if it's an outer-join clause, we always insist that relids be
+ * a subset of ojscope. This is safe because is_simple_subquery()
+ * disallows pullup of LATERAL subqueries that could cause the restriction
+ * to be violated.
*/
-#ifdef NOT_USED
- if (!bms_is_subset(relids, qualscope))
+ if (!root->hasLateralRTEs && !bms_is_subset(relids, qualscope))
elog(ERROR, "JOIN qualification cannot refer to other relations");
-#endif
if (ojscope && !bms_is_subset(relids, ojscope))
elog(ERROR, "JOIN qualification cannot refer to other relations");
@@ -1272,9 +1271,8 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause,
if (outerjoin_delayed)
{
/* Should still be a subset of current scope ... */
-#ifdef NOT_USED /* XXX temporarily disabled for LATERAL */
- Assert(bms_is_subset(relids, qualscope));
-#endif
+ Assert(root->hasLateralRTEs || bms_is_subset(relids, qualscope));
+ Assert(ojscope == NULL || bms_is_subset(relids, ojscope));
/*
* Because application of the qual will be delayed by outer join,