v1-0002-Fix-ON-CONFLICT-DO-NOTHING-with-partitioned-index.patch

text/plain

Filename: v1-0002-Fix-ON-CONFLICT-DO-NOTHING-with-partitioned-index.patch
Type: text/plain
Part: 1
Message: Re: unique indexes on partitioned tables

Patch

Format: format-patch
Series: patch v1-0002
Subject: Fix ON CONFLICT DO NOTHING with partitioned indexes
File+
src/backend/optimizer/plan/createplan.c 32 9
src/test/regress/expected/insert_conflict.out 0 2
From e88b485ec4aab08b80061c1899b38ad12736d8f9 Mon Sep 17 00:00:00 2001
From: amit <amitlangote09@gmail.com>
Date: Tue, 20 Feb 2018 18:02:59 +0900
Subject: [PATCH v1 2/2] Fix ON CONFLICT DO NOTHING with partitioned indexes

---
 src/backend/optimizer/plan/createplan.c       | 41 +++++++++++++++++++++------
 src/test/regress/expected/insert_conflict.out |  2 --
 2 files changed, 32 insertions(+), 11 deletions(-)

diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index da0cc7f266..98825b0b27 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -6504,20 +6504,43 @@ make_modifytable(PlannerInfo *root,
 	}
 	else
 	{
+		RangeTblEntry *rte;
+
 		node->onConflictAction = onconflict->action;
-		node->onConflictSet = onconflict->onConflictSet;
-		node->onConflictWhere = onconflict->onConflictWhere;
 
 		/*
-		 * If a set of unique index inference elements was provided (an
-		 * INSERT...ON CONFLICT "inference specification"), then infer
-		 * appropriate unique indexes (or throw an error if none are
-		 * available).
+		 * Partitioned tables don't yet have the executor support needed
+		 * to handle ON CONFLICT actions that rely on partitioned indexes,
+		 * so leave the following fields unset for them.
 		 */
-		node->arbiterIndexes = infer_arbiter_indexes(root);
 
-		node->exclRelRTI = onconflict->exclRelIndex;
-		node->exclRelTlist = onconflict->exclRelTlist;
+		 /* Must have only one result relation in the case of INSERT. */
+		Assert(list_length(node->resultRelations) == 1);
+		rte = planner_rt_fetch(linitial_int(node->resultRelations), root);
+		Assert(rte->rtekind == RTE_RELATION);
+		if (rte->relkind != RELKIND_PARTITIONED_TABLE)
+		{
+			node->onConflictSet = onconflict->onConflictSet;
+			node->onConflictWhere = onconflict->onConflictWhere;
+
+			/*
+			 * If a set of unique index inference elements was provided (an
+			 * INSERT...ON CONFLICT "inference specification"), then infer
+			 * appropriate unique indexes (or throw an error if none are
+			 * available).
+			 */
+			node->arbiterIndexes = infer_arbiter_indexes(root);
+			node->exclRelRTI = onconflict->exclRelIndex;
+			node->exclRelTlist = onconflict->exclRelTlist;
+		}
+		else
+		{
+			node->onConflictSet = NIL;
+			node->onConflictWhere = NULL;
+			node->arbiterIndexes = NIL;
+			node->exclRelRTI = 0;
+			node->exclRelTlist = NIL;
+		}
 	}
 	node->withCheckOptionLists = withCheckOptionLists;
 	node->returningLists = returningLists;
diff --git a/src/test/regress/expected/insert_conflict.out b/src/test/regress/expected/insert_conflict.out
index a46fe7ec60..7fa4282e0d 100644
--- a/src/test/regress/expected/insert_conflict.out
+++ b/src/test/regress/expected/insert_conflict.out
@@ -791,9 +791,7 @@ drop table selfconflict;
 create table parted_conflict_test (a int unique, b char) partition by list (a);
 create table parted_conflict_test_1 partition of parted_conflict_test (b unique) for values in (1, 2);
 insert into parted_conflict_test values (1, 'a') on conflict (a) do nothing;
-ERROR:  unexpected failure to find arbiter index
 insert into parted_conflict_test values (1, 'a') on conflict (a) do nothing;
-ERROR:  unexpected failure to find arbiter index
 -- however, on conflict do update is not supported yet
 insert into parted_conflict_test values (1, 'a') on conflict (b) do update set a = excluded.a;
 ERROR:  ON CONFLICT DO UPDATE cannot be applied to partitioned table "parted_conflict_test"
-- 
2.11.0