mirror of
https://github.com/postgres/postgres.git
synced 2025-04-21 12:05:57 +03:00
Fix MERGE command tag for cross-partition updates.
This ensures that the row count in the command tag for a MERGE is correctly computed. Previously, if MERGE updated a partitioned table, the row count would be incorrect if any row was moved to a different partition, since such updates were counted twice. Back-patch to v15, where MERGE was introduced. Discussion: https://postgr.es/m/CAEZATCWRMG7XX2QEsVL1LswmNo2d_YG8tKTLkpD3=Lp644S7rg@mail.gmail.com
This commit is contained in:
parent
2ddab010c2
commit
80a48e0f21
@ -2878,7 +2878,7 @@ lmerge_matched:
|
|||||||
}
|
}
|
||||||
ExecUpdatePrepareSlot(resultRelInfo, newslot, context->estate);
|
ExecUpdatePrepareSlot(resultRelInfo, newslot, context->estate);
|
||||||
result = ExecUpdateAct(context, resultRelInfo, tupleid, NULL,
|
result = ExecUpdateAct(context, resultRelInfo, tupleid, NULL,
|
||||||
newslot, mtstate->canSetTag, &updateCxt);
|
newslot, false, &updateCxt);
|
||||||
if (result == TM_Ok && updateCxt.updated)
|
if (result == TM_Ok && updateCxt.updated)
|
||||||
{
|
{
|
||||||
ExecUpdateEpilogue(context, &updateCxt, resultRelInfo,
|
ExecUpdateEpilogue(context, &updateCxt, resultRelInfo,
|
||||||
|
@ -1582,6 +1582,10 @@ SELECT * FROM pa_target ORDER BY tid;
|
|||||||
ROLLBACK;
|
ROLLBACK;
|
||||||
-- try updating the partition key column
|
-- try updating the partition key column
|
||||||
BEGIN;
|
BEGIN;
|
||||||
|
CREATE FUNCTION merge_func() RETURNS integer LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
result integer;
|
||||||
|
BEGIN
|
||||||
MERGE INTO pa_target t
|
MERGE INTO pa_target t
|
||||||
USING pa_source s
|
USING pa_source s
|
||||||
ON t.tid = s.sid
|
ON t.tid = s.sid
|
||||||
@ -1589,6 +1593,18 @@ MERGE INTO pa_target t
|
|||||||
UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge'
|
UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge'
|
||||||
WHEN NOT MATCHED THEN
|
WHEN NOT MATCHED THEN
|
||||||
INSERT VALUES (sid, delta, 'inserted by merge');
|
INSERT VALUES (sid, delta, 'inserted by merge');
|
||||||
|
IF FOUND THEN
|
||||||
|
GET DIAGNOSTICS result := ROW_COUNT;
|
||||||
|
END IF;
|
||||||
|
RETURN result;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
SELECT merge_func();
|
||||||
|
merge_func
|
||||||
|
------------
|
||||||
|
14
|
||||||
|
(1 row)
|
||||||
|
|
||||||
SELECT * FROM pa_target ORDER BY tid;
|
SELECT * FROM pa_target ORDER BY tid;
|
||||||
tid | balance | val
|
tid | balance | val
|
||||||
-----+---------+--------------------------
|
-----+---------+--------------------------
|
||||||
|
@ -999,6 +999,10 @@ ROLLBACK;
|
|||||||
|
|
||||||
-- try updating the partition key column
|
-- try updating the partition key column
|
||||||
BEGIN;
|
BEGIN;
|
||||||
|
CREATE FUNCTION merge_func() RETURNS integer LANGUAGE plpgsql AS $$
|
||||||
|
DECLARE
|
||||||
|
result integer;
|
||||||
|
BEGIN
|
||||||
MERGE INTO pa_target t
|
MERGE INTO pa_target t
|
||||||
USING pa_source s
|
USING pa_source s
|
||||||
ON t.tid = s.sid
|
ON t.tid = s.sid
|
||||||
@ -1006,6 +1010,13 @@ MERGE INTO pa_target t
|
|||||||
UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge'
|
UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge'
|
||||||
WHEN NOT MATCHED THEN
|
WHEN NOT MATCHED THEN
|
||||||
INSERT VALUES (sid, delta, 'inserted by merge');
|
INSERT VALUES (sid, delta, 'inserted by merge');
|
||||||
|
IF FOUND THEN
|
||||||
|
GET DIAGNOSTICS result := ROW_COUNT;
|
||||||
|
END IF;
|
||||||
|
RETURN result;
|
||||||
|
END;
|
||||||
|
$$;
|
||||||
|
SELECT merge_func();
|
||||||
SELECT * FROM pa_target ORDER BY tid;
|
SELECT * FROM pa_target ORDER BY tid;
|
||||||
ROLLBACK;
|
ROLLBACK;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user