Re: BUG #19802: MERGE into a partitioned table fails with "SubPlan found with no parent plan"

From: Tender Wang <tndrwang(at)gmail(dot)com>
To: gowthamdoma18(at)gmail(dot)com, pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: BUG #19802: MERGE into a partitioned table fails with "SubPlan found with no parent plan"
Date: 2026-10-29 00:39:04
Message-ID: CAHewXN=u1vYZM4ZBBxJ2Go8Z3hNzOPc-Uw464QMZeiD_gtD5VQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

PG Bug reporting form <noreply(at)postgresql(dot)org> 于2026年10月29日周四 00:25写道:
> MERGE into a partitioned table fails with an internal error when the source
> is a
> subquery that is not pulled up, an UPDATE SET clause contains a scalar
> subquery
> that references the source, and the statement has both WHEN MATCHED UPDATE
> and
> WHEN NOT MATCHED INSERT:
>
> CREATE TABLE mp (a int, b text) PARTITION BY RANGE (a);
> CREATE TABLE mp1 PARTITION OF mp FOR VALUES FROM (0) TO (10);
> MERGE INTO mp t
> USING (SELECT true AS c OFFSET 0) s ON t.a IS NULL
> WHEN MATCHED THEN UPDATE SET b = (SELECT NULL WHERE s.c)
> WHEN NOT MATCHED THEN INSERT VALUES (1, 'x');
>
> ERROR: SubPlan found with no parent plan
>
Hi,

Thanks for the report and the nicely reduced test case.

The problem is in ExecInitPartitionInfo(). When tuple routing creates a
ResultRelInfo for a partition during MERGE, it also builds
partition-specific state for the MERGE actions. For an UPDATE action, it
calls ExecBuildUpdateProjection() with a NULL parent PlanState.

If the UPDATE target list contains a SubPlan, ExecInitSubPlanExpr() needs
the parent PlanState to initialize the SubPlan and add the resulting
SubPlanState to the parent's subPlan list. Because no parent was supplied,
executor initialization fails with:

ERROR: SubPlan found with no parent plan

The corresponding code in ExecInitMerge() passes &mtstate->ps when
building the UPDATE projection. There is also another call to
ExecBuildUpdateProjection() earlier in ExecInitPartitionInfo(), for
ON CONFLICT DO UPDATE, that already passes &mtstate->ps. Only the
partition-specific MERGE UPDATE path passes NULL.

Passing the same parent in that path fixes the problem:

- NULL);
+ &mtstate->ps);

Attached is a patch with the fix. I have run the regression tests successfully.

--
Thanks,
Tender Wang

Attachment Content-Type Size
0001-Fix-MERGE-into-partitioned-tables-with-SubPlans-in-U.patch text/plain 1.5 KB

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message David Rowley 2026-10-29 01:22:01 Re: BUG #19803: Assertion "!parallel_aware || pathnode->path.parallel_safe" in create_append_path
Previous Message Sebastian Webber 2026-10-28 20:57:20 Re: pg_rewind and hint bits leads to visibility corruption