]> granicus.if.org Git - postgresql/commitdiff
Partially restore qual scope checks in distribute_qual_to_rels().
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 31 Aug 2012 22:57:12 +0000 (18:57 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 31 Aug 2012 22:57:12 +0000 (18:57 -0400)
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.

src/backend/optimizer/plan/initsplan.c

index 824c6a7e473cbeb454eabe2e311667e58437d6c6..f582d4067b9255406d49c97e020bcabbc615901a 100644 (file)
@@ -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,