Re: BUG #18830: ExecInitMerge Segfault on MERGE

Поиск
Список
Период
Сортировка
От Tender Wang
Тема Re: BUG #18830: ExecInitMerge Segfault on MERGE
Дата
Msg-id CAHewXNkiadMy42eDPNc7A1jxm1=wUjGi1_beMGKj6=sqxpvmOw@mail.gmail.com
обсуждение исходный текст
Ответ на Re: BUG #18830: ExecInitMerge Segfault on MERGE  (Tender Wang <tndrwang@gmail.com>)
Ответы Re: BUG #18830: ExecInitMerge Segfault on MERGE
Список pgsql-bugs


Tender Wang <tndrwang@gmail.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

В списке pgsql-bugs по дате отправления: