Re: BUG #18238: Cross-partitition MERGE/UPDATE with delete-preventing trigger leads to incorrect memory access

Поиск
Список
Период
Сортировка
От Richard Guo
Тема Re: BUG #18238: Cross-partitition MERGE/UPDATE with delete-preventing trigger leads to incorrect memory access
Дата
Msg-id CAMbWs48TaqQ-moMVu2tEbCB7qH5r-CMzd4LLFGov1LF-406FfQ@mail.gmail.com
обсуждение исходный текст
Ответ на Re: BUG #18238: Cross-partitition MERGE/UPDATE with delete-preventing trigger leads to incorrect memory access  (Dean Rasheed <dean.a.rasheed@gmail.com>)
Ответы Re: BUG #18238: Cross-partitition MERGE/UPDATE with delete-preventing trigger leads to incorrect memory access
Список pgsql-bugs

On Mon, Dec 11, 2023 at 8:53 PM Dean Rasheed <dean.a.rasheed@gmail.com> wrote:
The easiest way to do that is to have ExecDelete() return the
TM_Result status to ExecCrossPartitionUpdate(). I think
ExecCrossPartitionUpdate() should then return the TM_Result status to
ExecUpdateAct(), so that it can return the correct status, rather than
just assuming TM_Updated on failure, though possibly that's not
strictly necessary.

The simplest fix is for ExecMergeMatched() to pass canSetTag to
ExecUpdateAct(), so that it updates the command tag, if it does a
cross-partition update. That makes that code path in
ExecMergeMatched() more consistent with ExecUpdate().

So I think we need something like the attached.

I think this is the right way to go.  +1.

BTW, while testing this patch, I encountered some confusion regarding
cross-partition update.  As we know, cross-partition update works by
first deleting the old tuple from the current partition.  So if we have
BEFORE ROW DELETE triggers that suppress the delete, the update would be
suppressed.  For in-partition update, there is no such problem.  For
instance (based on Alexander's query):

CREATE TABLE t (a int) PARTITION BY RANGE (a);
CREATE TABLE tp1 PARTITION OF t FOR VALUES FROM (0) TO (10);
CREATE TABLE tp2 PARTITION OF t FOR VALUES FROM (10) TO (20);

INSERT INTO t VALUES (0), (5);    -- into tp1
INSERT INTO t VALUES (10), (15);  -- into tp2

CREATE FUNCTION tf() RETURNS TRIGGER LANGUAGE plpgsql AS
  $$ BEGIN RETURN NULL; END; $$;

CREATE TRIGGER tr BEFORE DELETE ON t
  FOR EACH ROW EXECUTE PROCEDURE tf();

-- update suppressed by the BEFORE ROW DELETE trigger
# UPDATE t SET a = 15 WHERE a = 0;
UPDATE 0

-- update performed successfully
# UPDATE t SET a = 5 WHERE a = 0;
UPDATE 1

Does this match the expected behavior?

Thanks
Richard

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

Предыдущее
От: Edouard Tollet
Дата:
Сообщение: Issue with pg_get_functiondef
Следующее
От: Daniel Gustafsson
Дата:
Сообщение: Re: BUG #18224: message bug in libpqwalreceiver.c.