Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 42d0d46

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/[email protected]
1 parent 258b041 commit 42d0d46

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 = (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

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1699,49 +1699,49 @@ reset enable_bitmapscan;
16991699
--
17001700
-- Check handling of MULTIEXPR SubPlans in inherited updates
17011701
--
1702-
create table inhpar(f1 int, f2 name);
1702+
create table inhpar(f1 int, f2 text[]);
17031703
insert into inhpar select generate_series(1,10);
17041704
create table inhcld() inherits(inhpar);
17051705
insert into inhcld select generate_series(11,10000);
17061706
vacuum analyze inhcld;
17071707
vacuum analyze inhpar;
17081708
explain (verbose, costs off)
1709-
update inhpar set (f1, f2) = (select p2.unique2, p2.stringu1
1710-
from int4_tbl limit 1)
1709+
update inhpar set (f1, f2[1]) = (select p2.unique2, p2.stringu1
1710+
from int4_tbl limit 1)
17111711
from onek p2 where inhpar.f1 = p2.unique1;
1712-
QUERY PLAN
1713-
---------------------------------------------------------------------------
1712+
QUERY PLAN
1713+
-------------------------------------------------------------------------------------------
17141714
Update on public.inhpar
17151715
Update on public.inhpar
17161716
Update on public.inhcld
17171717
-> Merge Join
1718-
Output: $4, $5, (SubPlan 1 (returns $2,$3)), inhpar.ctid, p2.ctid
1718+
Output: $4, inhpar.f2[1] := $5, (SubPlan 1 (returns $2,$3)), inhpar.ctid, p2.ctid
17191719
Merge Cond: (p2.unique1 = inhpar.f1)
17201720
-> Index Scan using onek_unique1 on public.onek p2
17211721
Output: p2.unique2, p2.stringu1, p2.ctid, p2.unique1
17221722
-> Sort
1723-
Output: inhpar.ctid, inhpar.f1
1723+
Output: inhpar.f2, inhpar.ctid, inhpar.f1
17241724
Sort Key: inhpar.f1
17251725
-> Seq Scan on public.inhpar
1726-
Output: inhpar.ctid, inhpar.f1
1726+
Output: inhpar.f2, inhpar.ctid, inhpar.f1
17271727
SubPlan 1 (returns $2,$3)
17281728
-> Limit
17291729
Output: (p2.unique2), (p2.stringu1)
17301730
-> Seq Scan on public.int4_tbl
17311731
Output: p2.unique2, p2.stringu1
17321732
-> Hash Join
1733-
Output: $6, $7, (SubPlan 1 (returns $2,$3)), inhcld.ctid, p2.ctid
1733+
Output: $6, inhcld.f2[1] := $7, (SubPlan 1 (returns $2,$3)), inhcld.ctid, p2.ctid
17341734
Hash Cond: (inhcld.f1 = p2.unique1)
17351735
-> Seq Scan on public.inhcld
1736-
Output: inhcld.ctid, inhcld.f1
1736+
Output: inhcld.f2, inhcld.ctid, inhcld.f1
17371737
-> Hash
17381738
Output: p2.unique2, p2.stringu1, p2.ctid, p2.unique1
17391739
-> Seq Scan on public.onek p2
17401740
Output: p2.unique2, p2.stringu1, p2.ctid, p2.unique1
17411741
(27 rows)
17421742

1743-
update inhpar set (f1, f2) = (select p2.unique2, p2.stringu1
1744-
from int4_tbl limit 1)
1743+
update inhpar set (f1, f2[1]) = (select p2.unique2, p2.stringu1
1744+
from int4_tbl limit 1)
17451745
from onek p2 where inhpar.f1 = p2.unique1;
17461746
drop table inhpar cascade;
17471747
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
@@ -622,19 +622,19 @@ reset enable_bitmapscan;
622622
--
623623
-- Check handling of MULTIEXPR SubPlans in inherited updates
624624
--
625-
create table inhpar(f1 int, f2 name);
625+
create table inhpar(f1 int, f2 text[]);
626626
insert into inhpar select generate_series(1,10);
627627
create table inhcld() inherits(inhpar);
628628
insert into inhcld select generate_series(11,10000);
629629
vacuum analyze inhcld;
630630
vacuum analyze inhpar;
631631

632632
explain (verbose, costs off)
633-
update inhpar set (f1, f2) = (select p2.unique2, p2.stringu1
634-
from int4_tbl limit 1)
633+
update inhpar set (f1, f2[1]) = (select p2.unique2, p2.stringu1
634+
from int4_tbl limit 1)
635635
from onek p2 where inhpar.f1 = p2.unique1;
636-
update inhpar set (f1, f2) = (select p2.unique2, p2.stringu1
637-
from int4_tbl limit 1)
636+
update inhpar set (f1, f2[1]) = (select p2.unique2, p2.stringu1
637+
from int4_tbl limit 1)
638638
from onek p2 where inhpar.f1 = p2.unique1;
639639

640640
drop table inhpar cascade;

0 commit comments

Comments
 (0)