Re: BUG #18830: ExecInitMerge Segfault on MERGE

From: Tender Wang <tndrwang(at)gmail(dot)com>
To: pgsql-bugs(at)lists(dot)postgresql(dot)org, Amit Langote <amitlangote09(at)gmail(dot)com>
Cc: tharakan(at)gmail(dot)com
Subject: Re: BUG #18830: ExecInitMerge Segfault on MERGE
Date: 2025-03-04 06:58:01
Message-ID: CAHewXNkiadMy42eDPNc7A1jxm1=wUjGi1_beMGKj6=sqxpvmOw@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Tender Wang <tndrwang(at)gmail(dot)com> 于2025年3月3日周一 23:46写道:

>
> Thanks for reporting.
> I can reproduce this crash. On HEAD 3f1db99bfa, crash on a different
> place due to the commit 75dfde1.
> But cbc127917e is the root cause commit.
>
> MERGE INTO e USING h ON a = xmlserialize WHEN NOT MATCHED THEN INSERT
> VALUES (CAST(NULL AS text));
> The plan of the above query looks as below:
> QUERY PLAN
> ------------------------------------------------------------------
> Merge on e (cost=0.00..58.29 rows=0 width=0)
> -> Nested Loop Left Join (cost=0.00..58.29 rows=12 width=10)
> -> Result (cost=0.00..0.01 rows=1 width=0)
> -> Append (cost=0.00..58.16 rows=12 width=10)
> Subplans Removed: 2
>
> You can see that all partitions are pruned. After cbc127917e, we only
> consider unpruned relations, then the list resultRelations is empty.
> the estate->es_unpruned_relids contains (1,2), the node->resultRelations
> contains (5,6).
>
> nrels = list_length(resultRelations);
> ...
> mtstate->resultRelInfo = (ResultRelInfo *)
> palloc(nrels * sizeof(ResultRelInfo));
>
> The memory of mtstate->resultRelInfo point to is undefined. When we access
> its memory in ExecInitMerge(),
>
> relationDesc = RelationGetDescr(resultRelInfo->ri_RelationDesc);
>
> crash happened.
>
> After 75dfde1, mergeActionLists list is empty, so in ExecInitMerge() we
> don't enter the foreach(lc, mergeActionLists),
> and the mtstate->ps.ps_ExprContext has no chance to initialize. So
> in ExecMergeNotMatched(), econtext is NULL.
> econtext->ecxt_scantuple = NULL;
> The above statement can trigger a segment fault.
>
> For Merge command NOT MATCH, should we need the logic that only consider
> unpruned relations in ExecInitModifyTable()?
>
> Merge command seems more complex than update and delete. Can we consider
> the unpruned relations in ExecInitModifyTable()
> according to the command type. For merge, we do the logic before
> cbc127917e, for now?
>
>
I found the partition_prune.sql does not cover merge into ... not match
case, and I found an easy reproduce step, seeing below:

postgres=# merge into part_abc_view pt
using (select stable_one() + 2 as pid) as q join part_abc_1 pt1 on (true)
on pt.a = stable_one() +2
when not matched then insert values(1, 'd', false);
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.

--
Thanks,
Tender Wang

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Richard Guo 2025-03-04 07:30:26 Re: Query result differences between PostgreSQL 17 vs 16
Previous Message Noah Misch 2025-03-04 03:34:42 Re: BUG #17821: Assertion failed in heap_update() due to heap pruning