Skip to content

Commit 80a48e0

Browse files
committed
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
1 parent 2ddab01 commit 80a48e0

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

src/backend/executor/nodeModifyTable.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2878,7 +2878,7 @@ ExecMergeMatched(ModifyTableContext *context, ResultRelInfo *resultRelInfo,
28782878
}
28792879
ExecUpdatePrepareSlot(resultRelInfo, newslot, context->estate);
28802880
result = ExecUpdateAct(context, resultRelInfo, tupleid, NULL,
2881-
newslot, mtstate->canSetTag, &updateCxt);
2881+
newslot, false, &updateCxt);
28822882
if (result == TM_Ok && updateCxt.updated)
28832883
{
28842884
ExecUpdateEpilogue(context, &updateCxt, resultRelInfo,

src/test/regress/expected/merge.out

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1582,13 +1582,29 @@ SELECT * FROM pa_target ORDER BY tid;
15821582
ROLLBACK;
15831583
-- try updating the partition key column
15841584
BEGIN;
1585+
CREATE FUNCTION merge_func() RETURNS integer LANGUAGE plpgsql AS $$
1586+
DECLARE
1587+
result integer;
1588+
BEGIN
15851589
MERGE INTO pa_target t
15861590
USING pa_source s
15871591
ON t.tid = s.sid
15881592
WHEN MATCHED THEN
15891593
UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge'
15901594
WHEN NOT MATCHED THEN
15911595
INSERT VALUES (sid, delta, 'inserted by merge');
1596+
IF FOUND THEN
1597+
GET DIAGNOSTICS result := ROW_COUNT;
1598+
END IF;
1599+
RETURN result;
1600+
END;
1601+
$$;
1602+
SELECT merge_func();
1603+
merge_func
1604+
------------
1605+
14
1606+
(1 row)
1607+
15921608
SELECT * FROM pa_target ORDER BY tid;
15931609
tid | balance | val
15941610
-----+---------+--------------------------

src/test/regress/sql/merge.sql

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,13 +999,24 @@ ROLLBACK;
999999

10001000
-- try updating the partition key column
10011001
BEGIN;
1002+
CREATE FUNCTION merge_func() RETURNS integer LANGUAGE plpgsql AS $$
1003+
DECLARE
1004+
result integer;
1005+
BEGIN
10021006
MERGE INTO pa_target t
10031007
USING pa_source s
10041008
ON t.tid = s.sid
10051009
WHEN MATCHED THEN
10061010
UPDATE SET tid = tid + 1, balance = balance + delta, val = val || ' updated by merge'
10071011
WHEN NOT MATCHED THEN
10081012
INSERT VALUES (sid, delta, 'inserted by merge');
1013+
IF FOUND THEN
1014+
GET DIAGNOSTICS result := ROW_COUNT;
1015+
END IF;
1016+
RETURN result;
1017+
END;
1018+
$$;
1019+
SELECT merge_func();
10091020
SELECT * FROM pa_target ORDER BY tid;
10101021
ROLLBACK;
10111022

0 commit comments

Comments
 (0)