Skip to content

Commit 54e1599

Browse files
committed
Teach reparameterize_path() to handle AppendPaths.
If we're inside a lateral subquery, there may be no unparameterized paths for a particular child relation of an appendrel, in which case we *must* be able to create similarly-parameterized paths for each other child relation, else the planner will fail with "could not devise a query plan for the given query". This means that there are situations where we'd better be able to reparameterize at least one path for each child. This calls into question the assumption in reparameterize_path() that it can just punt if it feels like it. However, the only case that is known broken right now is where the child is itself an appendrel so that all its paths are AppendPaths. (I think possibly I disregarded that in the original coding on the theory that nested appendrels would get folded together --- but that only happens *after* reparameterize_path(), so it's not excused from handling a child AppendPath.) Given that this code's been like this since 9.3 when LATERAL was introduced, it seems likely we'd have heard of other cases by now if there were a larger problem. Per report from Elvis Pranskevichus. Back-patch to 9.3. Discussion: https://postgr.es/m/5981018.zdth1YWmNy@hammer.magicstack.net
1 parent a0950b1 commit 54e1599

File tree

3 files changed

+51
-0
lines changed

3 files changed

+51
-0
lines changed

src/backend/optimizer/util/pathnode.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2075,6 +2075,28 @@ reparameterize_path(PlannerInfo *root, Path *path,
20752075
case T_SubqueryScan:
20762076
return create_subqueryscan_path(root, rel, path->pathkeys,
20772077
required_outer);
2078+
case T_Append:
2079+
{
2080+
AppendPath *apath = (AppendPath *) path;
2081+
List *childpaths = NIL;
2082+
ListCell *lc;
2083+
2084+
/* Reparameterize the children */
2085+
foreach(lc, apath->subpaths)
2086+
{
2087+
Path *spath = (Path *) lfirst(lc);
2088+
2089+
spath = reparameterize_path(root, spath,
2090+
required_outer,
2091+
loop_count);
2092+
if (spath == NULL)
2093+
return NULL;
2094+
childpaths = lappend(childpaths, spath);
2095+
}
2096+
return (Path *)
2097+
create_append_path(rel, childpaths,
2098+
required_outer);
2099+
}
20782100
default:
20792101
break;
20802102
}

src/test/regress/expected/join.out

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4954,6 +4954,25 @@ select * from
49544954
Output: 3
49554955
(11 rows)
49564956

4957+
-- check handling of nested appendrels inside LATERAL
4958+
select * from
4959+
((select 2 as v) union all (select 3 as v)) as q1
4960+
cross join lateral
4961+
((select * from
4962+
((select 4 as v) union all (select 5 as v)) as q3)
4963+
union all
4964+
(select q1.v)
4965+
) as q2;
4966+
v | v
4967+
---+---
4968+
2 | 4
4969+
2 | 5
4970+
2 | 2
4971+
3 | 4
4972+
3 | 5
4973+
3 | 3
4974+
(6 rows)
4975+
49574976
-- check we don't try to do a unique-ified semijoin with LATERAL
49584977
explain (verbose, costs off)
49594978
select * from

src/test/regress/sql/join.sql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1569,6 +1569,16 @@ select * from
15691569
select * from (select 3 as z) z where z.z = x.x
15701570
) zz on zz.z = y.y;
15711571

1572+
-- check handling of nested appendrels inside LATERAL
1573+
select * from
1574+
((select 2 as v) union all (select 3 as v)) as q1
1575+
cross join lateral
1576+
((select * from
1577+
((select 4 as v) union all (select 5 as v)) as q3)
1578+
union all
1579+
(select q1.v)
1580+
) as q2;
1581+
15721582
-- check we don't try to do a unique-ified semijoin with LATERAL
15731583
explain (verbose, costs off)
15741584
select * from

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy