Re: BUG #18830: ExecInitMerge Segfault on MERGE

Tender Wang <tndrwang@gmail.com>

From: Tender Wang <tndrwang@gmail.com>
To: Amit Langote <amitlangote09@gmail.com>
Cc: tharakan@gmail.com, pgsql-bugs@lists.postgresql.org
Date: 2025-03-04T12:06:18Z
Lists: pgsql-bugs
Amit Langote <amitlangote09@gmail.com> 于2025年3月4日周二 19:51写道:

> On Mon, Mar 3, 2025 at 9:16 PM Tender Wang <tndrwang@gmail.com> wrote:
> > 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(),
>
> This needs to be fixed saparately.
>
> > relationDesc = RelationGetDescr(resultRelInfo->ri_RelationDesc);
> >
> > crash happened.
>
> Do you have a case where this access to undefined
> ModifyTableState.resultRelInfo occurs? I would have thought that it
> should not happen.
>

"undefined" may not be accurate, "invalid" seems more correct.
I still use  the case:
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);

(gdb) p *resultRelInfo
$5 = {type = 2139062142, ri_RangeTableIndex = 2139062143, ri_RelationDesc =
0x180, ri_NumIndices = 195, ri_IndexRelationDescs = 0x500000182,
ri_IndexRelationInfo = 0x7f8773b2aa38, ri_RowIdAttNo = 0,
ri_extraUpdatedCols = 0x0, ri_projectNew = 0x0,
  ri_newTupleSlot = 0x0, ri_oldTupleSlot = 0x0, ri_projectNewInfoValid =
false, ri_needLockTagTuple = false, ri_TrigDesc = 0x0, ri_TrigFunctions =
0x0, ri_TrigWhenExprs = 0x0, ri_TrigInstrument = 0x0, ri_ReturningSlot =
0x0, ri_TrigOldSlot = 0x0,
  ri_TrigNewSlot = 0x0, ri_AllNullSlot = 0x0, ri_FdwRoutine = 0x0,
ri_FdwState = 0x0, ri_usesFdwDirectModify = false, ri_NumSlots = 0,
ri_NumSlotsInitialized = 0, ri_BatchSize = 0, ri_Slots = 0x0, ri_PlanSlots
= 0x0, ri_WithCheckOptions = 0x0,
  ri_WithCheckOptionExprs = 0x0, ri_ConstraintExprs = 0x0,
ri_GeneratedExprsI = 0x0, ri_GeneratedExprsU = 0x0, ri_NumGeneratedNeededI
= 0, ri_NumGeneratedNeededU = 0, ri_returningList = 0x0,
ri_projectReturning = 0x0,
  ri_onConflictArbiterIndexes = 0x0, ri_onConflict = 0x0, ri_MergeActions =
{0x0, 0x0, 0x0}, ri_MergeJoinCondition = 0x0, ri_PartitionCheckExpr = 0x0,
ri_ChildToRootMap = 0x0, ri_ChildToRootMapValid = false, ri_RootToChildMap
= 0x0,
  ri_RootToChildMapValid = false, ri_RootResultRelInfo = 0x0,
ri_PartitionTupleSlot = 0x0, ri_CopyMultiInsertBuffer = 0x0,
ri_ancestorResultRels = 0x0}

 ri_RelationDesc = 0x180,  this address is not invalid.

-- 
Thanks,
Tender Wang

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. Ensure first ModifyTable rel initialized if all are pruned

  2. Don't lock partitions pruned by initial pruning

  3. Fix an oversight in cbc127917 to handle MERGE correctly

  4. Remove some unnecessary fields from Plan trees.