8000 Fix MERGE with DO NOTHING actions into a partitioned table. · postgres/postgres@8b6a0e2 · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit 8b6a0e2

Browse files
committed
Fix MERGE with DO NOTHING actions into a partitioned table.
ExecInitPartitionInfo() duplicates much of the logic in ExecInitMerge(), except that it failed to handle DO NOTHING actions. This would cause an "unknown action in MERGE WHEN clause" error if a MERGE with any DO NOTHING actions attempted to insert into a partition not already initialised by ExecInitModifyTable(). Bug: #18871 Reported-by: Alexander Lakhin <exclusion@gmail.com> Author: Tender Wang <tndrwang@gmail.com> Reviewed-by: Gurjeet Singh <gurjeet@singh.im> Discussion: https://postgr.es/m/18871-b44e3c96de3bd2e8%40postgresql.org Backpatch-through: 15
1 parent a0ed19e commit 8b6a0e2

File tree

4 files changed

+34
-2
lines changed

4 files changed

+34
-2
lines changed

src/backend/executor/execPartition.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -876,7 +876,7 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate,
876876
* reference and make copy for this relation, converting stuff that
877877
* references attribute numbers to match this relation's.
878878
*
879-
* This duplicates much of the logic in ExecInitMerge(), so something
879+
* This duplicates much of the logic in ExecInitMerge(), so if something
880880
* changes there, look here too.
881881
*/
882882
if (node && node->operation == CMD_MERGE)
@@ -956,6 +956,8 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate,
956956
NULL);
957957
break;
958958
case CMD_DELETE:
959+
case CMD_NOTHING:
960+
/* Nothing to do */
959961
break;
960962

961963
default:

src/backend/executor/nodeModifyTable.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3784,7 +3784,7 @@ ExecInitMerge(ModifyTableState *mtstate, EState *estate)
37843784
case CMD_NOTHING:
37853785
break;
37863786
default:
3787-
elog(ERROR, "unknown operation");
3787+
elog(ERROR, "unknown action in MERGE WHEN clause");
37883788
break;
37893789
}
37903790
}

src/test/regress/expected/merge.out

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2060,6 +2060,23 @@ SELECT * FROM pa_target ORDER BY tid;
20602060
15 | 1500 | initial
20612061
(8 rows)
20622062

2063+
ROLLBACK;
2064+
-- bug #18871: ExecInitPartitionInfo()'s handling of DO NOTHING actions
2065+
BEGIN;
2066+
TRUNCATE pa_target;
2067+
MERGE INTO pa_target t
2068+
USING (VALUES (10, 100)) AS s(sid, delta)
2069+
ON t.tid = s.sid
2070+
WHEN NOT MATCHED THEN
2071+
INSERT VALUES (1, 10, 'inserted by merge')
2072+
WHEN MATCHED THEN
2073+
DO NOTHING;
2074+
SELECT * FROM pa_target ORDER BY tid, val;
2075+
tid | balance | val
2076+
-----+---------+-------------------
2077< 8000 /td>+
1 | 10 | inserted by merge
2078+
(1 row)
2079+
20632080
ROLLBACK;
20642081
DROP TABLE pa_target CASCADE;
20652082
-- The target table is partitioned in the same way, but this time by attaching

src/test/regress/sql/merge.sql

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,6 +1271,19 @@ MERGE INTO pa_target t
12711271
SELECT * FROM pa_target ORDER BY tid;
12721272
ROLLBACK;
12731273

1274+
-- bug #18871: ExecInitPartitionInfo()'s handling of DO NOTHING actions
1275+
BEGIN;
1276+
TRUNCATE pa_target;
1277+
MERGE INTO pa_target t
1278+
USING (VALUES (10, 100)) AS s(sid, delta)
1279+
ON t.tid = s.sid
1280+
WHEN NOT MATCHED THEN
1281+
INSERT VALUES (1, 10, 'inserted by merge')
1282+
WHEN MATCHED THEN
1283+
DO NOTHING;
1284+
SELECT * FROM pa_target ORDER BY tid, val;
1285+
ROLLBACK;
1286+
12741287
DROP TABLE pa_target CASCADE;
12751288

12761289
-- The target table is partitioned in the same way, but this time by attaching

0 commit comments

Comments
 (0)
0