mirror of
https://github.com/postgres/postgres.git
synced 2025-07-18 17:42:25 +03:00
Ignore whole-rows in INSERT/CONFLICT with partitioned tables
We had an Assert() preventing whole-row expressions from being used in the SET clause of INSERT ON CONFLICT, but it seems unnecessary, given some tests, so remove it. Add a new test to exercise the case. Still at ExecInitPartitionInfo, we used map_partition_varattnos (which constructs an attribute map, then calls map_variable_attnos) using the same two relations many times in different expressions and with different parameters. Constructing the map over and over is a waste. To avoid this repeated work, construct the map once, and use map_variable_attnos() directly instead. Author: Amit Langote, per comments by me (Álvaro) Discussion: https://postgr.es/m/20180326142016.m4st5e34chrzrknk@alvherre.pgsql
This commit is contained in:
@ -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, 'cincuenta', 1);
|
||||
insert into parted_conflict values (50, 'cincuenta', 2)
|
||||
on conflict (a, b) do update set (a, b, c) = row(excluded.*)
|
||||
where parted_conflict = (50, text 'cincuenta', 1) and
|
||||
excluded = (50, text 'cincuenta', 2);
|
||||
-- should see (50, 'cincuenta', 2)
|
||||
select * from parted_conflict order by a;
|
||||
a | b | c
|
||||
----+-----------+---
|
||||
50 | cincuenta | 2
|
||||
(1 row)
|
||||
|
||||
drop table parted_conflict;
|
||||
|
@ -559,3 +559,21 @@ insert into parted_conflict values (40, 'forty');
|
||||
insert into parted_conflict_1 values (40, 'cuarenta')
|
||||
on conflict (a) do update set b = excluded.b;
|
||||
drop table parted_conflict;
|
||||
|
||||
-- test whole-row Vars in ON CONFLICT expressions
|
||||
create table parted_conflict (a int, b text, c int) partition by range (a);
|
||||
create table parted_conflict_1 (drp text, c int, a int, b text);
|
||||
alter table parted_conflict_1 drop column drp;
|
||||
create unique index on parted_conflict (a, b);
|
||||
alter table parted_conflict attach partition parted_conflict_1 for values from (0) to (1000);
|
||||
truncate parted_conflict;
|
||||
insert into parted_conflict values (50, 'cincuenta', 1);
|
||||
insert into parted_conflict values (50, 'cincuenta', 2)
|
||||
on conflict (a, b) do update set (a, b, c) = row(excluded.*)
|
||||
where parted_conflict = (50, text 'cincuenta', 1) and
|
||||
excluded = (50, text 'cincuenta', 2);
|
||||
|
||||
-- should see (50, 'cincuenta', 2)
|
||||
select * from parted_conflict order by a;
|
||||
|
||||
drop table parted_conflict;
|
||||
|
Reference in New Issue
Block a user