Re: LATERAL quals revisited
От | Tom Lane |
---|---|
Тема | Re: LATERAL quals revisited |
Дата | |
Msg-id | 14545.1374245839@sss.pgh.pa.us обсуждение исходный текст |
Ответ на | Re: LATERAL quals revisited (Ashutosh Bapat <ashutosh.bapat@enterprisedb.com>) |
Список | pgsql-hackers |
Ashutosh Bapat <ashutosh.bapat@enterprisedb.com> writes: > On Wed, Jun 26, 2013 at 1:30 AM, Tom Lane <tgl@sss.pgh.pa.us> wrote: >> For there to *be* a unique "appropriate outer join", we need to require >> that a LATERAL-using qual clause that's under an outer join contain >> lateral references only to the outer side of the nearest enclosing outer >> join. There's no such restriction in the spec of course, but we can >> make it so by refusing to flatten a sub-select if pulling it up would >> result in having a clause in the outer query that violates this rule. >> There's already some code in prepjointree.c (around line 1300) that >> attempts to enforce this, though now that I look at it again I'm not >> sure it's covering all the bases. We may need to extend that check. > Why do we need this restriction? Wouldn't a place (specifically join qual > at such a place) in join tree where all the participating relations are > present, serve as a place where the clause can be applied. No. If you hoist a qual that appears below an outer join to above the outer join, you get wrong results in general: you might eliminate rows from the outer side of the join, which a qual from within the inner side should never be able to do. > select * from tab1 left join tab2 t2 using (val) left join lateral (select > val from tab2 where val2 = tab1.val * t2.val) t3 using (val); > Can't we apply (as a join qual) the qual val2 = tab1.val * t2.val at a > place where we are computing join between tab1, t2 and t3? This particular example doesn't violate the rule I gave above, since both tab1 and t2 are on the left side of the join to the lateral subquery, and the qual doesn't have to get hoisted *past* an outer join, only to the outer join of {tab1,t2} with {t3}. >> I'm inclined to process all LATERAL-using qual clauses this way, ie >> postpone them till we recurse back up to a place where they can >> logically be evaluated. That won't make any real difference when no >> outer joins are present, but it will eliminate the ugliness that right >> now distribute_qual_to_rels is prevented from sanity-checking the scope >> of the references in a qual when LATERAL is present. If we do it like >> this, we can resurrect full enforcement of that sanity check, and then >> throw an error if any "postponed" quals are left over when we're done >> recursing. > Parameterized nested loop join would always be able to evaluate a LATERAL > query. Instead of throwing error, why can't we choose that as the default > strategy whenever we fail to flatten subquery? I think you misunderstood. That error would only be a sanity check that we'd accounted for all qual clauses, it's not something a user should ever see. regards, tom lane
В списке pgsql-hackers по дате отправления: