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

From: Dilip Kumar <dilipbalaut(at)gmail(dot)com>
To: Tender Wang <tndrwang(at)gmail(dot)com>
Cc: 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-11-04 10:48:44
Message-ID: CAFiTN-sgjD-kq=1FRyR9Ai8kHx3RQhboLiYc2nCETXETt58t4Q@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

On Thu, Oct 29, 2026 at 6:09 AM Tender Wang <tndrwang(at)gmail(dot)com> wrote:
>
> 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.

Yeah, that seems to be wrong

>
> 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.

I think your analysis and fix LGTM. Can you also add a test case so
that we do not break this in the future? Thanks.

--
Regards,
Dilip Kumar
Google

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Tender Wang 2026-11-04 11:25:42 Re: BUG #19802: MERGE into a partitioned table fails with "SubPlan found with no parent plan"
Previous Message Álvaro Herrera 2026-11-04 10:15:45 Re: BUG #19827: postgres_fdw: Assert in add_foreign_ordered_paths() with redundant ORDER BY in set-op input