Re: BUG #18830: ExecInitMerge Segfault on MERGE

Поиск
Список
Период
Сортировка
От Tender Wang
Тема Re: BUG #18830: ExecInitMerge Segfault on MERGE
Дата
Msg-id CAHewXNkQpmfD1T4W0ORVR1KwOFWu6Oba7=71eh9-FEC2eFshPw@mail.gmail.com
обсуждение исходный текст
Ответ на Re: BUG #18830: ExecInitMerge Segfault on MERGE  (Dean Rasheed <dean.a.rasheed@gmail.com>)
Ответы Re: BUG #18830: ExecInitMerge Segfault on MERGE
Список pgsql-bugs


Dean Rasheed <dean.a.rasheed@gmail.com> 于2025年3月12日周三 22:59写道:
On Wed, 12 Mar 2025 at 12:24, Amit Langote <amitlangote09@gmail.com> wrote:
>
> Thanks -- I’ve studied the code and I agree with the conclusion: when
> all result relations are pruned, we still need to lock and process the
> first one to preserve executor invariants.
>
> Your examples with ExecMerge() and ExecInitPartitionInfo() make the
> consequences of missing resultRelInfo[0] pretty clear. Locking and
> including the first result relation, even if pruned, seems like the
> most straightforward way to maintain correctness without deeper
> structural changes.
>
> I've come up with the attached. I'll still need to add a test case.

Hmm, this isn't quite sufficient.

In ExecDoInitialPruning(), stmt->resultRelations contains all the
result relations plus the root relation (if set) of each ModifyTable
node in the planned stmt (see set_plan_refs()). Therefore, just adding
the first result relation in that list may not be sufficient to ensure
that every ModifyTable node ends up with at least one unpruned result
relation.

For example, consider:

create table foo (a int);
create table part_abc (a int, b text, c bool) partition by list (a);
create table part_abc_1 (b text, c bool, a int);
create table part_abc_2 (b text, a int, c bool);
alter table part_abc attach partition part_abc_1 for values in (1);
alter table part_abc attach partition part_abc_2 for values in (2);
insert into part_abc_1 values ('b', true, 1);
insert into part_abc_2 values ('c', 2, true);
create function stable_one() returns int as
  $$ begin return 1; end; $$ language plpgsql stable;

with t as (
  merge into part_abc pt using (values(1)) v(a) on pt.a = stable_one() + 2
    when not matched then insert values (v.a, 'd', false)
    returning pt.*
)
insert into foo select a from t;

ERROR:  trying to open a pruned relation

Nice catch.   The above case can be another test case.

 I can find another same error in the below query:

with t as (update part_abc set c = true  where a = stable_one() +2  returning a) insert into foo select a from t;

--
Thanks,
Tender Wang

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