Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 18f5108

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 d7bc6ea commit 18f5108

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
@@ -914,20 +914,54 @@ SS_make_multiexprs_unique(PlannerInfo *root, PlannerInfo *subroot)
914914
/*
915915
* Now we must find the Param nodes that reference the MULTIEXPR outputs
916916
* and update their sublink IDs so they'll reference the new outputs.
917-
* Fortunately, those too must be at top level of the cloned targetlist.
917+
* Fortunately, those too must be in the cloned targetlist, but they could
918+
* be buried under FieldStores and SubscriptingRefs and CoerceToDomains
919+
* (cf processIndirection()), and underneath those there could be an
920+
* implicit type coercion.
918921
*/
919922
offset = list_length(root->multiexpr_params);
920923

921924
foreach(lc, subroot->parse->targetList)
922925
{
923926
TargetEntry *tent = (TargetEntry *) lfirst(lc);
927+
Node *expr;
924928
Param *p;
925929
int subqueryid;
926930
int colno;
927931

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

src/test/regress/expected/inherit.out

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1717,49 +1717,49 @@ reset enable_bitmapscan;
17171717
--
17181718
-- Check handling of MULTIEXPR SubPlans in inherited updates
17191719
--
1720-
create table inhpar(f1 int, f2 name);
1720+
create table inhpar(f1 int, f2 text[]);
17211721
insert into inhpar select generate_series(1,10);
17221722
create table inhcld() inherits(inhpar);
17231723
insert into inhcld select generate_series(11,10000);
17241724
vacuum analyze inhcld;
17251725
vacuum analyze inhpar;
17261726
explain (verbose, costs off)
1727-
update inhpar set (f1, f2) = (select p2.unique2, p2.stringu1
1728-
from int4_tbl limit 1)
1727+
update inhpar set (f1, f2[1]) = (select p2.unique2, p2.stringu1
1728+
from int4_tbl limit 1)
17291729
from onek p2 where inhpar.f1 = p2.unique1;
1730-
QUERY PLAN
1731-
-----------------------------------------------------------------------------
1730+
QUERY PLAN
1731+
-----------------------------------------------------------------------------------------------
17321732
Update on public.inhpar
17331733
Update on public.inhpar
17341734
Update on public.inhcld inhpar_1
17351735
-> Merge Join
1736-
Output: $4, $5, (SubPlan 1 (returns $2,$3)), inhpar.ctid, p2.ctid
1736+
Output: $4, inhpar.f2[1] := $5, (SubPlan 1 (returns $2,$3)), inhpar.ctid, p2.ctid
17371737
Merge Cond: (p2.unique1 = inhpar.f1)
17381738
-> Index Scan using onek_unique1 on public.onek p2
17391739
Output: p2.unique2, p2.stringu1, p2.ctid, p2.unique1
17401740
-> Sort
1741-
Output: inhpar.ctid, inhpar.f1
1741+
Output: inhpar.f2, inhpar.ctid, inhpar.f1
17421742
Sort Key: inhpar.f1
17431743
-> Seq Scan on public.inhpar
1744-
Output: inhpar.ctid, inhpar.f1
1744+
Output: inhpar.f2, inhpar.ctid, inhpar.f1
17451745
SubPlan 1 (returns $2,$3)
17461746
-> Limit
17471747
Output: (p2.unique2), (p2.stringu1)
17481748
-> Seq Scan on public.int4_tbl
17491749
Output: p2.unique2, p2.stringu1
17501750
-> Hash Join
1751-
Output: $6, $7, (SubPlan 1 (returns $2,$3)), inhpar_1.ctid, p2.ctid
1751+
Output: $6, inhpar_1.f2[1] := $7, (SubPlan 1 (returns $2,$3)), inhpar_1.ctid, p2.ctid
17521752
Hash Cond: (inhpar_1.f1 = p2.unique1)
17531753
-> Seq Scan on public.inhcld inhpar_1
1754-
Output: inhpar_1.ctid, inhpar_1.f1
1754+
Output: inhpar_1.f2, inhpar_1.ctid, inhpar_1.f1
17551755
-> Hash
17561756
Output: p2.unique2, p2.stringu1, p2.ctid, p2.unique1
17571757
-> Seq Scan on public.onek p2
17581758
Output: p2.unique2, p2.stringu1, p2.ctid, p2.unique1
17591759
(27 rows)
17601760

1761-
update inhpar set (f1, f2) = (select p2.unique2, p2.stringu1
1762-
from int4_tbl limit 1)
1761+
update inhpar set (f1, f2[1]) = (select p2.unique2, p2.stringu1
1762+
from int4_tbl limit 1)
17631763
from onek p2 where inhpar.f1 = p2.unique1;
17641764
drop table inhpar cascade;
17651765
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
@@ -632,19 +632,19 @@ reset enable_bitmapscan;
632632
--
633633
-- Check handling of MULTIEXPR SubPlans in inherited updates
634634
--
635-
create table inhpar(f1 int, f2 name);
635+
create table inhpar(f1 int, f2 text[]);
636636
insert into inhpar select generate_series(1,10);
637637
create table inhcld() inherits(inhpar);
638638
insert into inhcld select generate_series(11,10000);
639639
vacuum analyze inhcld;
640640
vacuum analyze inhpar;
641641

642642
explain (verbose, costs off)
643-
update inhpar set (f1, f2) = (select p2.unique2, p2.stringu1
644-
from int4_tbl limit 1)
643+
update inhpar set (f1, f2[1]) = (select p2.unique2, p2.stringu1
644+
from int4_tbl limit 1)
645645
from onek p2 where inhpar.f1 = p2.unique1;
646-
update inhpar set (f1, f2) = (select p2.unique2, p2.stringu1
647-
from int4_tbl limit 1)
646+
update inhpar set (f1, f2[1]) = (select p2.unique2, p2.stringu1
647+
from int4_tbl limit 1)
648648
from onek p2 where inhpar.f1 = p2.unique1;
649649

650650
drop table inhpar cascade;

0 commit comments

Comments
 (0)