0002-Fix-cross-partition-merge-fail.patch
text/plain
Filename: 0002-Fix-cross-partition-merge-fail.patch
Type: text/plain
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
Series: patch 0002
| File | + | − |
|---|---|---|
| src/backend/executor/execPartition.c | 1 | 0 |
| src/backend/executor/nodeModifyTable.c | 4 | 0 |
| src/test/regress/expected/partition_prune.out | 28 | 0 |
| src/test/regress/sql/partition_prune.sql | 14 | 0 |
diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c
index 84ccd7d457d..8d1e3c0624f 100644
--- a/src/backend/executor/execPartition.c
+++ b/src/backend/executor/execPartition.c
@@ -956,6 +956,7 @@ ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate,
NULL);
break;
case CMD_DELETE:
+ case CMD_NOTHING:
break;
default:
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index 87c820276a8..381847cfdf3 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -3712,6 +3712,10 @@ ExecInitMerge(ModifyTableState *mtstate, EState *estate)
lappend(resultRelInfo->ri_MergeActions[action->matchKind],
action_state);
+ /*
+ * ExecInitPartitionInfo() duplicates much of the logic here, so if
+ * you change something here, look there, too.
+ */
switch (action->commandType)
{
case CMD_INSERT:
diff --git a/src/test/regress/expected/partition_prune.out b/src/test/regress/expected/partition_prune.out
index 0bf35260b46..2f3e5db8252 100644
--- a/src/test/regress/expected/partition_prune.out
+++ b/src/test/regress/expected/partition_prune.out
@@ -4694,6 +4694,34 @@ table part_abc_view;
2 | c | t
(2 rows)
+rollback;
+-- Cross-partition merge
+begin;
+explain (costs off)
+merge into part_abc_view pt
+using (select 3 as a) as q on pt.a = q.a
+WHEN NOT MATCHED THEN INSERT VALUES (1, 2)
+WHEN MATCHED THEN DO NOTHING;
+ QUERY PLAN
+--------------------------------------
+ Merge on part_abc
+ -> Nested Loop Left Join
+ -> Result
+ -> Result
+ One-Time Filter: false
+(5 rows)
+
+merge into part_abc_view pt
+using (select 3 as a) as q on pt.a = q.a
+WHEN NOT MATCHED THEN INSERT VALUES (1, 2)
+WHEN MATCHED THEN DO NOTHING;
+table part_abc_view;
+ a | b | c
+---+---+---
+ 1 | 2 |
+ 2 | c | t
+(2 rows)
+
rollback;
-- A case with multiple ModifyTable nodes.
begin;
diff --git a/src/test/regress/sql/partition_prune.sql b/src/test/regress/sql/partition_prune.sql
index f6db9479f54..339c8d9a4e8 100644
--- a/src/test/regress/sql/partition_prune.sql
+++ b/src/test/regress/sql/partition_prune.sql
@@ -1413,6 +1413,20 @@ when not matched then insert values (1, 'd', false) returning pt.a;
table part_abc_view;
rollback;
+-- Cross-partition merge
+begin;
+explain (costs off)
+merge into part_abc_view pt
+using (select 3 as a) as q on pt.a = q.a
+WHEN NOT MATCHED THEN INSERT VALUES (1, 2)
+WHEN MATCHED THEN DO NOTHING;
+merge into part_abc_view pt
+using (select 3 as a) as q on pt.a = q.a
+WHEN NOT MATCHED THEN INSERT VALUES (1, 2)
+WHEN MATCHED THEN DO NOTHING;
+table part_abc_view;
+rollback;
+
-- A case with multiple ModifyTable nodes.
begin;
create table part_abc_log (action text, a int, b text, c bool);