/*
* Now we must find the Param nodes that reference the MULTIEXPR outputs
* and update their sublink IDs so they'll reference the new outputs.
- * Fortunately, those too must be at top level of the cloned targetlist.
+ * Fortunately, those too must be in the cloned targetlist, but they could
+ * be buried under FieldStores and SubscriptingRefs and CoerceToDomains
+ * (cf processIndirection()), and underneath those there could be an
+ * implicit type coercion.
*/
offset = list_length(root->multiexpr_params);
foreach(lc, subroot->parse->targetList)
{
TargetEntry *tent = (TargetEntry *) lfirst(lc);
+ Node *expr;
Param *p;
int subqueryid;
int colno;
- if (!IsA(tent->expr, Param))
+ expr = (Node *) tent->expr;
+ while (expr)
+ {
+ if (IsA(expr, FieldStore))
+ {
+ FieldStore *fstore = (FieldStore *) expr;
+
+ expr = (Node *) linitial(fstore->newvals);
+ }
+ else if (IsA(expr, SubscriptingRef))
+ {
+ SubscriptingRef *sbsref = (SubscriptingRef *) expr;
+
+ if (sbsref->refassgnexpr == NULL)
+ break;
+
+ expr = (Node *) sbsref->refassgnexpr;
+ }
+ else if (IsA(expr, CoerceToDomain))
+ {
+ CoerceToDomain *cdomain = (CoerceToDomain *) expr;
+
+ if (cdomain->coercionformat != COERCE_IMPLICIT_CAST)
+ break;
+ expr = (Node *) cdomain->arg;
+ }
+ else
+ break;
+ }
+ expr = strip_implicit_coercions(expr);
+ if (expr == NULL || !IsA(expr, Param))
continue;
- p = (Param *) tent->expr;
+ p = (Param *) expr;
if (p->paramkind != PARAM_MULTIEXPR)
continue;
subqueryid = p->paramid >> 16;
--
-- Check handling of MULTIEXPR SubPlans in inherited updates
--
-create table inhpar(f1 int, f2 name);
+create table inhpar(f1 int, f2 text[]);
insert into inhpar select generate_series(1,10);
create table inhcld() inherits(inhpar);
insert into inhcld select generate_series(11,10000);
vacuum analyze inhcld;
vacuum analyze inhpar;
explain (verbose, costs off)
-update inhpar set (f1, f2) = (select p2.unique2, p2.stringu1
- from int4_tbl limit 1)
+update inhpar set (f1, f2[1]) = (select p2.unique2, p2.stringu1
+ from int4_tbl limit 1)
from onek p2 where inhpar.f1 = p2.unique1;
- QUERY PLAN
----------------------------------------------------------------------------
+ QUERY PLAN
+-------------------------------------------------------------------------------------------
Update on public.inhpar
Update on public.inhpar
Update on public.inhcld
-> Merge Join
- Output: $4, $5, (SubPlan 1 (returns $2,$3)), inhpar.ctid, p2.ctid
+ Output: $4, inhpar.f2[1] := $5, (SubPlan 1 (returns $2,$3)), inhpar.ctid, p2.ctid
Merge Cond: (p2.unique1 = inhpar.f1)
-> Index Scan using onek_unique1 on public.onek p2
Output: p2.unique2, p2.stringu1, p2.ctid, p2.unique1
-> Sort
- Output: inhpar.ctid, inhpar.f1
+ Output: inhpar.f2, inhpar.ctid, inhpar.f1
Sort Key: inhpar.f1
-> Seq Scan on public.inhpar
- Output: inhpar.ctid, inhpar.f1
+ Output: inhpar.f2, inhpar.ctid, inhpar.f1
SubPlan 1 (returns $2,$3)
-> Limit
Output: (p2.unique2), (p2.stringu1)
-> Seq Scan on public.int4_tbl
Output: p2.unique2, p2.stringu1
-> Hash Join
- Output: $6, $7, (SubPlan 1 (returns $2,$3)), inhcld.ctid, p2.ctid
+ Output: $6, inhcld.f2[1] := $7, (SubPlan 1 (returns $2,$3)), inhcld.ctid, p2.ctid
Hash Cond: (inhcld.f1 = p2.unique1)
-> Seq Scan on public.inhcld
- Output: inhcld.ctid, inhcld.f1
+ Output: inhcld.f2, inhcld.ctid, inhcld.f1
-> Hash
Output: p2.unique2, p2.stringu1, p2.ctid, p2.unique1
-> Seq Scan on public.onek p2
Output: p2.unique2, p2.stringu1, p2.ctid, p2.unique1
(27 rows)
-update inhpar set (f1, f2) = (select p2.unique2, p2.stringu1
- from int4_tbl limit 1)
+update inhpar set (f1, f2[1]) = (select p2.unique2, p2.stringu1
+ from int4_tbl limit 1)
from onek p2 where inhpar.f1 = p2.unique1;
drop table inhpar cascade;
NOTICE: drop cascades to table inhcld
--
-- Check handling of MULTIEXPR SubPlans in inherited updates
--
-create table inhpar(f1 int, f2 name);
+create table inhpar(f1 int, f2 text[]);
insert into inhpar select generate_series(1,10);
create table inhcld() inherits(inhpar);
insert into inhcld select generate_series(11,10000);
vacuum analyze inhpar;
explain (verbose, costs off)
-update inhpar set (f1, f2) = (select p2.unique2, p2.stringu1
- from int4_tbl limit 1)
+update inhpar set (f1, f2[1]) = (select p2.unique2, p2.stringu1
+ from int4_tbl limit 1)
from onek p2 where inhpar.f1 = p2.unique1;
-update inhpar set (f1, f2) = (select p2.unique2, p2.stringu1
- from int4_tbl limit 1)
+update inhpar set (f1, f2[1]) = (select p2.unique2, p2.stringu1
+ from int4_tbl limit 1)
from onek p2 where inhpar.f1 = p2.unique1;
drop table inhpar cascade;