From c97a547a4a0913e37e5dd1f026ac3c281326b215 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Fri, 31 Aug 2012 18:57:12 -0400 Subject: [PATCH] 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. --- src/backend/optimizer/plan/initsplan.c | 28 ++++++++++++-------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 824c6a7e47..f582d4067b 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, -- 2.40.0