mirror of
https://github.com/postgres/postgres.git
synced 2025-07-15 19:21:59 +03:00
Fix some issues with LATERAL(SELECT UNION ALL SELECT).
The LATERAL marking has to be propagated down to the UNION leaf queries when we pull them up. Also, fix the formerly stubbed-off set_append_rel_pathlist(). It does already have enough smarts to cope with making a parameterized Append path at need; it just has to not assume that there *must* be an unparameterized path.
This commit is contained in:
@ -661,6 +661,7 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
||||
int parentRTindex = rti;
|
||||
List *live_childrels = NIL;
|
||||
List *subpaths = NIL;
|
||||
bool subpaths_valid = true;
|
||||
List *all_child_pathkeys = NIL;
|
||||
List *all_child_outers = NIL;
|
||||
ListCell *l;
|
||||
@ -699,19 +700,21 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
||||
if (IS_DUMMY_REL(childrel))
|
||||
continue;
|
||||
|
||||
/* XXX need to figure out what to do for LATERAL */
|
||||
if (childrel->cheapest_total_path == NULL)
|
||||
elog(ERROR, "LATERAL within an append relation is not supported yet");
|
||||
/*
|
||||
* Child is live, so add it to the live_childrels list for use below.
|
||||
*/
|
||||
live_childrels = lappend(live_childrels, childrel);
|
||||
|
||||
/*
|
||||
* Child is live, so add its cheapest access path to the Append path
|
||||
* we are constructing for the parent.
|
||||
* If child has an unparameterized cheapest-total path, add that to
|
||||
* the unparameterized Append path we are constructing for the parent.
|
||||
* If not, there's no workable unparameterized path.
|
||||
*/
|
||||
subpaths = accumulate_append_subpath(subpaths,
|
||||
if (childrel->cheapest_total_path)
|
||||
subpaths = accumulate_append_subpath(subpaths,
|
||||
childrel->cheapest_total_path);
|
||||
|
||||
/* Remember which childrels are live, for logic below */
|
||||
live_childrels = lappend(live_childrels, childrel);
|
||||
else
|
||||
subpaths_valid = false;
|
||||
|
||||
/*
|
||||
* Collect lists of all the available path orderings and
|
||||
@ -779,17 +782,20 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
||||
}
|
||||
|
||||
/*
|
||||
* Next, build an unordered, unparameterized Append path for the rel.
|
||||
* (Note: this is correct even if we have zero or one live subpath due to
|
||||
* constraint exclusion.)
|
||||
* If we found unparameterized paths for all children, build an unordered,
|
||||
* unparameterized Append path for the rel. (Note: this is correct even
|
||||
* if we have zero or one live subpath due to constraint exclusion.)
|
||||
*/
|
||||
add_path(rel, (Path *) create_append_path(rel, subpaths, NULL));
|
||||
if (subpaths_valid)
|
||||
add_path(rel, (Path *) create_append_path(rel, subpaths, NULL));
|
||||
|
||||
/*
|
||||
* Build unparameterized MergeAppend paths based on the collected list of
|
||||
* child pathkeys.
|
||||
* Also build unparameterized MergeAppend paths based on the collected
|
||||
* list of child pathkeys.
|
||||
*/
|
||||
generate_mergeappend_paths(root, rel, live_childrels, all_child_pathkeys);
|
||||
if (subpaths_valid)
|
||||
generate_mergeappend_paths(root, rel, live_childrels,
|
||||
all_child_pathkeys);
|
||||
|
||||
/*
|
||||
* Build Append paths for each parameterization seen among the child rels.
|
||||
@ -807,11 +813,11 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
||||
foreach(l, all_child_outers)
|
||||
{
|
||||
Relids required_outer = (Relids) lfirst(l);
|
||||
bool ok = true;
|
||||
ListCell *lcr;
|
||||
|
||||
/* Select the child paths for an Append with this parameterization */
|
||||
subpaths = NIL;
|
||||
subpaths_valid = true;
|
||||
foreach(lcr, live_childrels)
|
||||
{
|
||||
RelOptInfo *childrel = (RelOptInfo *) lfirst(lcr);
|
||||
@ -831,7 +837,7 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
||||
required_outer, 1.0);
|
||||
if (cheapest_total == NULL)
|
||||
{
|
||||
ok = false;
|
||||
subpaths_valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -839,7 +845,7 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
|
||||
subpaths = accumulate_append_subpath(subpaths, cheapest_total);
|
||||
}
|
||||
|
||||
if (ok)
|
||||
if (subpaths_valid)
|
||||
add_path(rel, (Path *)
|
||||
create_append_path(rel, subpaths, required_outer));
|
||||
}
|
||||
@ -911,13 +917,11 @@ generate_mergeappend_paths(PlannerInfo *root, RelOptInfo *rel,
|
||||
*/
|
||||
if (cheapest_startup == NULL || cheapest_total == NULL)
|
||||
{
|
||||
/* XXX need to figure out what to do for LATERAL */
|
||||
if (childrel->cheapest_total_path == NULL)
|
||||
elog(ERROR, "LATERAL within an append relation is not supported yet");
|
||||
|
||||
cheapest_startup = cheapest_total =
|
||||
childrel->cheapest_total_path;
|
||||
/* Assert we do have an unparameterized path for this child */
|
||||
Assert(cheapest_total != NULL);
|
||||
Assert(cheapest_total->param_info == NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user