partition-on-conflict-wholerow-fix.patch

text/plain

Filename: partition-on-conflict-wholerow-fix.patch
Type: text/plain
Part: 0
Message: Re: ON CONFLICT DO UPDATE for partitioned tables

Patch

Format: unified
File+
src/backend/executor/execPartition.c 4 9
src/test/regress/expected/insert_conflict.out 16 0
src/test/regress/sql/insert_conflict.sql 14 0
diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c
index 9a13188649..f1a972e235 100644
--- a/src/backend/executor/execPartition.c
+++ b/src/backend/executor/execPartition.c
@@ -557,7 +557,6 @@ ExecInitPartitionInfo(ModifyTableState *mtstate,
 			{
 				List	   *onconflset;
 				TupleDesc	tupDesc;
-				bool		found_whole_row;
 
 				leaf_part_rri->ri_onConflict = makeNode(OnConflictSetState);
 
@@ -571,12 +570,10 @@ ExecInitPartitionInfo(ModifyTableState *mtstate,
 				onconflset = (List *) copyObject((Node *) node->onConflictSet);
 				onconflset =
 					map_partition_varattnos(onconflset, INNER_VAR, partrel,
-											firstResultRel, &found_whole_row);
-				Assert(!found_whole_row);
+											firstResultRel, NULL);
 				onconflset =
 					map_partition_varattnos(onconflset, firstVarno, partrel,
-											firstResultRel, &found_whole_row);
-				Assert(!found_whole_row);
+											firstResultRel, NULL);
 
 				/* Finally, adjust this tlist to match the partition. */
 				onconflset = adjust_partition_tlist(onconflset, map);
@@ -609,12 +606,10 @@ ExecInitPartitionInfo(ModifyTableState *mtstate,
 					clause = copyObject((List *) node->onConflictWhere);
 					clause = map_partition_varattnos(clause, INNER_VAR,
 													 partrel, firstResultRel,
-													 &found_whole_row);
-					Assert(!found_whole_row);
+													 NULL);
 					clause = map_partition_varattnos(clause, firstVarno,
 													 partrel, firstResultRel,
-													 &found_whole_row);
-					Assert(!found_whole_row);
+													 NULL);
 					leaf_part_rri->ri_onConflict->oc_WhereClause =
 						ExecInitQual((List *) clause, &mtstate->ps);
 				}
diff --git a/src/test/regress/expected/insert_conflict.out b/src/test/regress/expected/insert_conflict.out
index 2d7061fa1b..66ca1839bc 100644
--- a/src/test/regress/expected/insert_conflict.out
+++ b/src/test/regress/expected/insert_conflict.out
@@ -884,4 +884,20 @@ insert into parted_conflict values (40, 'forty');
 insert into parted_conflict_1 values (40, 'cuarenta')
   on conflict (a) do update set b = excluded.b;
 ERROR:  there is no unique or exclusion constraint matching the ON CONFLICT specification
+-- test whole-row Vars in ON CONFLICT expressions
+create unique index on parted_conflict (a, b);
+alter table parted_conflict add c int;
+truncate parted_conflict;
+insert into parted_conflict values (50, 'cuarenta', 1);
+insert into parted_conflict values (50, 'cuarenta', 2)
+  on conflict (a, b) do update set (a, b, c) = row(excluded.*)
+  where parted_conflict = (50, text 'cuarenta', 1) and
+        excluded = (50, text 'cuarenta', 2);
+-- should see (50, 'cuarenta', 2)
+select * from parted_conflict order by a;
+ a  |    b     | c 
+----+----------+---
+ 50 | cuarenta | 2
+(1 row)
+
 drop table parted_conflict;
diff --git a/src/test/regress/sql/insert_conflict.sql b/src/test/regress/sql/insert_conflict.sql
index 6c50fd61eb..fb30530a54 100644
--- a/src/test/regress/sql/insert_conflict.sql
+++ b/src/test/regress/sql/insert_conflict.sql
@@ -558,4 +558,18 @@ create table parted_conflict_1_1 partition of parted_conflict_1 for values from
 insert into parted_conflict values (40, 'forty');
 insert into parted_conflict_1 values (40, 'cuarenta')
   on conflict (a) do update set b = excluded.b;
+
+-- test whole-row Vars in ON CONFLICT expressions
+create unique index on parted_conflict (a, b);
+alter table parted_conflict add c int;
+truncate parted_conflict;
+insert into parted_conflict values (50, 'cuarenta', 1);
+insert into parted_conflict values (50, 'cuarenta', 2)
+  on conflict (a, b) do update set (a, b, c) = row(excluded.*)
+  where parted_conflict = (50, text 'cuarenta', 1) and
+        excluded = (50, text 'cuarenta', 2);
+
+-- should see (50, 'cuarenta', 2)
+select * from parted_conflict order by a;
+
 drop table parted_conflict;