8000 Fix oversight in recent MULTIEXPR_SUBLINK fix. · postgres/postgres@56dc442 · GitHub
[go: up one dir, main page]

Skip to content

Commit 56dc442

Browse files
committed
Fix oversight in recent MULTIEXPR_SUBLINK fix.
Commits 3f7323c et al missed the possibility that the Params they are looking for could be buried under implicit coercions, as well as other stuff that processIndirection() could add to the original targetlist entry. Copy the code in ruleutils.c that deals with such cases. (I thought about refactoring so that there's just one copy; but seeing that we only need this in old back branches, it seems not worth the trouble.) Per off-list report from Andre Lin. As before, only v10-v13 need the patch. Discussion: https://postgr.es/m/17596-c5357f61427a81dc@postgresql.org
1 parent 1b11543 commit 56dc442

File tree

3 files changed

+54
-20
lines changed

3 files changed

+54
-20
lines changed

src/backend/optimizer/plan/subselect.c

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -915,20 +915,54 @@ SS_make_multiexprs_unique(PlannerInfo *root, PlannerInfo *subroot)
915915
/*
916916
* Now we must find the Param nodes that reference the MULTIEXPR outputs
917917
* and update their sublink IDs so they'll reference the new outputs.
918-
* Fortunately, those too must be at top level of the cloned targetlist.
918+
* Fortunately, those too must be in the cloned targetlist, but they could
919+
* be buried under FieldStores and ArrayRefs and CoerceToDomains
920+
* (cf processIndirection()), and underneath those there could be an
921+
* implicit type coercion.
919922
*/
920923
offset = list_length(root->multiexpr_params);
921924

922925
foreach(lc, subroot->parse->targetList)
923926
{
924927
TargetEntry *tent< 10BC0 /span> = (TargetEntry *) lfirst(lc);
928+
Node *expr;
925929
Param *p;
926930
int subqueryid;
927931
int colno;
928932

929-
if (!IsA(tent->expr, Param))
933+
expr = (Node *) tent->expr;
934+
while (expr)
935+
{
936+
if (IsA(expr, FieldStore))
937+
{
938+
FieldStore *fstore = (FieldStore *) expr;
939+
940+
expr = (Node *) linitial(fstore->newvals);
941+
}
942+
else if (IsA(expr, ArrayRef))
943+
{
944+
ArrayRef *aref = (ArrayRef *) expr;
945+
946+
if (aref->refassgnexpr == NULL)
947+
break;
948+
949+
expr = (Node *) aref->refassgnexpr;
950+
}
951+
else if (IsA(expr, CoerceToDomain))
952+
{
953+
CoerceToDomain *cdomain = (CoerceToDomain *) expr;
954+
955+
if (cdomain->coercionformat != COERCE_IMPLICIT_CAST)
956+
break;
957+
expr = (Node *) cdomain->arg;
958+
}
959+
else
960+
break;
961+
}
962+
expr = strip_implicit_coercions(expr);
963+
if (expr == NULL || !IsA(expr, Param))
930964
continue;
931-
p = (Param *) tent->expr;
965+
p = (Param *) expr;
932966
if (p->paramkind != PARAM_MULTIEXPR)
933967
continue;
934968
subqueryid = p->paramid >> 16;

src/test/regress/expected/inherit.out

-12Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1748,49 +1748,49 @@ reset enable_bitmapscan;
17481748
--
17491749
-- Check handling of MULTIEXPR SubPlans in inherited updates
17501750
--
1751-
create table inhpar(f1 int, f2 name);
1751+
create table inhpar(f1 int, f2 text[]);
17521752
insert into inhpar select generate_series(1,10);
17531753
create table inhcld() inherits(inhpar);
17541754
insert into inhcld select generate_series(11,10000);
17551755
vacuum analyze inhcld;
17561756
vacuum analyze inhpar;
17571757
explain (verbose, costs off)
1758-
update inhpar set (f1, f2) = (select p2.unique2, p2.stringu1
1759-
from int4_tbl limit 1)
1758+
update inhpar set (f1, f2[1]) = (select p2.unique2, p2.stringu1
1759+
from int4_tbl limit 1)
17601760
from onek p2 where inhpar.f1 = p2.unique1;
1761-
QUERY PLAN
1762-
---------------------------------------------------------------------------
1761+
QUERY PLAN
1762+
-------------------------------------------------------------------------------------------
17631763
Update on public.inhpar
17641764
Update on public.inhpar
17651765
Update on public.inhcld
17661766
-> Merge Join
1767-
Output: $4, $5, (SubPlan 1 (returns $2,$3)), inhpar.ctid, p2.ctid
1767+
Output: $4, inhpar.f2[1] := $5, (SubPlan 1 (returns $2,$3)), inhpar.ctid, p2.ctid
17681768
Merge Cond: (p2.unique1 = inhpar.f1)
17691769
-> Index Scan using onek_unique1 on public.onek p2
17701770
Output: p2.unique2, p2.stringu1, p2.ctid, p2.unique1
17711771
-> Sort
1772-
Output: inhpar.ctid, inhpar.f1
1772+
Output: inhpar.f2, inhpar.ctid, inhpar.f1
17731773
Sort Key: inhpar.f1
17741774
-> Seq Scan on public.inhpar
1775-
Output: inhpar.ctid, inhpar.f1
1775+
Output: inhpar.f2, inhpar.ctid, inhpar.f1
17761776
SubPlan 1 (returns $2,$3)
17771777
-> Limit
17781778
Output: (p2.unique2), (p2.stringu1)
17791779
-> Seq Scan on public.int4_tbl
17801780
Output: p2.unique2, p2.stringu1
17811781
-> Hash Join
1782-
Output: $6, $7, (SubPlan 1 (returns $2,$3)), inhcld.ctid, p2.ctid
1782+
Output: $6, inhcld.f2[1] := $7, (SubPlan 1 (returns $2,$3)), inhcld.ctid, p2.ctid
17831783
Hash Cond: (inhcld.f1 = p2.unique1)
17841784
-> Seq Scan on public.inhcld
1785-
Output: inhcld.ctid, inhcld.f1
1785+
Output: inhcld.f2, inhcld.ctid, inhcld.f1
17861786
-> Hash
17871787
Output: p2.unique2, p2.stringu1, p2.ctid, p2.unique1
17881788
-> Seq Scan on public.onek p2
17891789
Output: p2.unique2, p2.stringu1, p2.ctid, p2.unique1
17901790
(27 rows)
17911791

1792-
update inhpar set (f1, f2) = (select p2.unique2, p2.stringu1
1793-
from int4_tbl limit 1)
1792+
update inhpar set (f1, f2[1]) = (select p2.unique2, p2.stringu1
1793+
from int4_tbl limit 1)
17941794
from onek p2 where inhpar.f1 = p2.unique1;
17951795
drop table inhpar cascade;
17961796
NOTICE: drop cascades to table inhcld

src/test/regress/sql/inherit.sql

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -653,19 +653,19 @@ reset enable_bitmapscan;
653653
--
654654
-- Check handling of MULTIEXPR SubPlans in inherited updates
655655
--
656-
create table inhpar(f1 int, f2 name);
656+
create table inhpar(f1 int, f2 text[]);
657657
insert into inhpar select generate_series(1,10);
658658
create table inhcld() inherits(inhpar);
659659
insert into inhcld select generate_series(11,10000);
660660
vacuum analyze inhcld;
661661
vacuum analyze inhpar;
662662

663663
explain (verbose, costs off)
664-
update inhpar set (f1, f2) = (select p2.unique2, p2.stringu1
665-
from int4_tbl limit 1)
664+
update inhpar set (f1, f2[1]) = (select p2.unique2, p2.stringu1
665+
from int4_tbl limit 1)
666666
from onek p2 where inhpar.f1 = p2.unique1;
667-
update inhpar set (f1, f2) = (select p2.unique2, p2.stringu1
668-
from int4_tbl limit 1)
667+
update inhpar set (f1, f2[1]) = (select p2.unique2, p2.stringu1
668+
from int4_tbl limit 1)
669669
from onek p2 where inhpar.f1 = p2.unique1;
670670

671671
drop table inhpar cascade;

0 commit comments

Comments
 (0)
0