mirror of
https://github.com/postgres/postgres.git
synced 2025-07-14 08:21:07 +03:00
More fixes for planner's handling of LATERAL.
Re-allow subquery pullup for LATERAL subqueries, except when the subquery is below an outer join and contains lateral references to relations outside that outer join. If we pull up in such a case, we risk introducing lateral cross-references into outer joins' ON quals, which is something the code is entirely unprepared to cope with right now; and I'm not sure it'll ever be worth coping with. Support lateral refs in VALUES (this seems to be the only additional path type that needs such support as a consequence of re-allowing subquery pullup). Put in a slightly hacky fix for joinpath.c's refusal to consider parameterized join paths even when there cannot be any unparameterized ones. This was causing "could not devise a query plan for the given query" failures in queries involving more than two FROM items. Put in an even more hacky fix for distribute_qual_to_rels() being unhappy with join quals that contain references to rels outside their syntactic scope; which is to say, disable that test altogether. Need to think about how to preserve some sort of debugging cross-check here, while not expending more cycles than befits a debugging cross-check.
This commit is contained in:
@ -232,6 +232,8 @@ extract_lateral_references(PlannerInfo *root, int rtindex)
|
||||
vars = pull_vars_of_level((Node *) rte->subquery, 1);
|
||||
else if (rte->rtekind == RTE_FUNCTION)
|
||||
vars = pull_vars_of_level(rte->funcexpr, 0);
|
||||
else if (rte->rtekind == RTE_VALUES)
|
||||
vars = pull_vars_of_level((Node *) rte->values_lists, 0);
|
||||
else
|
||||
return;
|
||||
|
||||
@ -874,9 +876,19 @@ distribute_qual_to_rels(PlannerInfo *root, Node *clause,
|
||||
/*
|
||||
* Cross-check: clause should contain no relids not within its scope.
|
||||
* Otherwise the parser messed up.
|
||||
*
|
||||
* 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.)
|
||||
*/
|
||||
#ifdef NOT_USED
|
||||
if (!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");
|
||||
|
||||
@ -1031,7 +1043,9 @@ 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
|
||||
|
||||
/*
|
||||
* Because application of the qual will be delayed by outer join,
|
||||
|
Reference in New Issue
Block a user