-- -- insert...on conflict do unique index inference -- createtable insertconflicttest(keyint4, fruit text);
-- These things should work through a view, as well create view insertconflictview asselect * from insertconflicttest;
-- -- Test unique index inference with operator class specifications and -- named collations -- createuniqueindex op_index_key on insertconflicttest(key, fruit text_pattern_ops); createuniqueindex collation_index_key on insertconflicttest(key, fruit collate"C"); createuniqueindex both_index_key on insertconflicttest(key, fruit collate"C" text_pattern_ops); createuniqueindex both_index_expr_key on insertconflicttest(key, lower(fruit) collate"C" text_pattern_ops);
-- fails explain (costs off) insertinto insertconflicttest values(0, 'Crowberry') on conflict (key) do nothing; explain (costs off) insertinto insertconflicttest values(0, 'Crowberry') on conflict (fruit) do nothing;
-- succeeds explain (costs off) insertinto insertconflicttest values(0, 'Crowberry') on conflict (key, fruit) do nothing; explain (costs off) insertinto insertconflicttest values(0, 'Crowberry') on conflict (fruit, key, fruit, key) do nothing; explain (costs off) insertinto insertconflicttest values(0, 'Crowberry') on conflict (lower(fruit), key, lower(fruit), key) do nothing; explain (costs off) insertinto insertconflictview values(0, 'Crowberry') on conflict (lower(fruit), key, lower(fruit), key) do nothing; explain (costs off) insertinto insertconflicttest values(0, 'Crowberry') on conflict (key, fruit) do updateset fruit = excluded.fruit whereexists (select1from insertconflicttest ii where ii.key = excluded.key); -- Neither collation nor operator class specifications are required -- -- supplying them merely *limits* matches to indexes with matching opclasses -- used for relevant indexes explain (costs off) insertinto insertconflicttest values(0, 'Crowberry') on conflict (key, fruit text_pattern_ops) do nothing; -- Okay, arbitrates using both index where text_pattern_ops opclass does and -- does not appear. explain (costs off) insertinto insertconflicttest values(0, 'Crowberry') on conflict (key, fruit collate"C") do nothing; -- Okay, but only accepts the single index where both opclass and collation are -- specified explain (costs off) insertinto insertconflicttest values(0, 'Crowberry') on conflict (fruit collate"C" text_pattern_ops, key) do nothing; -- Okay, but only accepts the single index where both opclass and collation are -- specified (plus expression variant) explain (costs off) insertinto insertconflicttest values(0, 'Crowberry') on conflict (lower(fruit) collate"C", key, key) do nothing; -- Attribute appears twice, while not all attributes/expressions on attributes -- appearing within index definition match in terms of both opclass and -- collation. -- -- Works because every attribute in inference specification needs to be -- satisfied once or more by cataloged index attribute, and as always when an -- attribute in the cataloged definition has a non-default opclass/collation, -- it still satisfied some inference attribute lacking any particular -- opclass/collation specification. -- -- The implementation is liberal in accepting inference specifications on the -- assumption that multiple inferred unique indexes will prevent problematic -- cases. It rolls with unique indexes where attributes redundantly appear -- multiple times, too (which is not tested here). explain (costs off) insertinto insertconflicttest values(0, 'Crowberry') on conflict (fruit, key, fruit text_pattern_ops, key) do nothing; explain (costs off) insertinto insertconflicttest values(0, 'Crowberry') on conflict (lower(fruit) collate"C" text_pattern_ops, key, key) do nothing;
-- -- Make sure that cross matching of attribute opclass/collation does not occur -- createuniqueindex cross_match on insertconflicttest(lower(fruit) collate"C", upper(fruit) text_pattern_ops);
-- fails: explain (costs off) insertinto insertconflicttest values(0, 'Crowberry') on conflict (lower(fruit) text_pattern_ops, upper(fruit) collate"C") do nothing; -- works: explain (costs off) insertinto insertconflicttest values(0, 'Crowberry') on conflict (lower(fruit) collate"C", upper(fruit) text_pattern_ops) do nothing;
dropindex cross_match;
-- -- Single key tests -- createuniqueindex key_index on insertconflicttest(key);
-- -- Explain tests -- explain (costs off) insertinto insertconflicttest values (0, 'Bilberry') on conflict (key) do updateset fruit = excluded.fruit; -- Should display qual actually attributable to internal sequential scan: explain (costs off) insertinto insertconflicttest values (0, 'Bilberry') on conflict (key) do updateset fruit = excluded.fruit where insertconflicttest.fruit != 'Cawesh'; -- With EXCLUDED.* expression in scan node: explain (costs off) insertinto insertconflicttest values(0, 'Crowberry') on conflict (key) do updateset fruit = excluded.fruit where excluded.fruit != 'Elderberry'; -- Does the same, but JSON format shows "Conflict Arbiter Index" as JSON array: explain (costs off, format json) insertinto insertconflicttest values (0, 'Bilberry') on conflict (key) do updateset fruit = excluded.fruit where insertconflicttest.fruit != 'Lime' returning *;
-- Fails (no unique index inference specification, required for do update variant): insertinto insertconflicttest values (1, 'Apple') on conflict do updateset fruit = excluded.fruit;
-- inference succeeds: insertinto insertconflicttest values (1, 'Apple') on conflict (key) do updateset fruit = excluded.fruit; insertinto insertconflicttest values (2, 'Orange') on conflict (key, key, key) do updatesetfruit = excluded.fruit;
-- Succeed, since multi-assignment does not involve subquery: insertinto insertconflicttest values (1, 'Apple'), (2, 'Orange') on conflict (key) do updateset (fruit, key) = (excluded.fruit, excluded.key);
-- Give good diagnostic message when EXCLUDED.* spuriously referenced from -- RETURNING: insertinto insertconflicttest values (1, 'Apple') on conflict (key) do updateset fruit = excluded.fruit RETURNING excluded.fruit;
-- Only suggest <table>.* column when inference element misspelled: insertinto insertconflicttest values (1, 'Apple') on conflict (keyy) do updateset fruit = excluded.fruit;
-- Have useful HINT for EXCLUDED.* RTE within UPDATE: insertinto insertconflicttest values (1, 'Apple') on conflict (key) do updateset fruit = excluded.fruitt;
-- inference fails: insertinto insertconflicttest values (3, 'Kiwi') on conflict (key, fruit) do updateset fruit = excluded.fruit; insertinto insertconflicttest values (4, 'Mango') on conflict (fruit, key) do updateset fruit = excluded.fruit; insertinto insertconflicttest values (5, 'Lemon') on conflict (fruit) do updateset fruit = excluded.fruit; insertinto insertconflicttest values (6, 'Passionfruit') on conflict (lower(fruit)) do updateset fruit = excluded.fruit;
-- Check the target relation can be aliased insertinto insertconflicttest AS ict values (6, 'Passionfruit') on conflict (key) do updateset fruit = excluded.fruit; -- ok, no reference to target table insertinto insertconflicttest AS ict values (6, 'Passionfruit') on conflict (key) do updateset fruit = ict.fruit; -- ok, alias insertinto insertconflicttest AS ict values (6, 'Passionfruit') on conflict (key) do updateset fruit = insertconflicttest.fruit; -- error, references aliased away name
-- Check helpful hint when qualifying set column with target table insertinto insertconflicttest values (3, 'Kiwi') on conflict (key, fruit) do updateset insertconflicttest.fruit = 'Mango';
-- inference succeeds: insertinto insertconflicttest values (7, 'Raspberry') on conflict (key, fruit) do updateset fruit = excluded.fruit; insertinto insertconflicttest values (8, 'Lime') on conflict (fruit, key) do updateset fruit = excluded.fruit;
-- inference fails: insertinto insertconflicttest values (9, 'Banana') on conflict (key) do updateset fruit = excluded.fruit; insertinto insertconflicttest values (10, 'Blueberry') on conflict (key, key, key) do updateset fruit = excluded.fruit; insertinto insertconflicttest values (11, 'Cherry') on conflict (key, lower(fruit)) do updateset fruit = excluded.fruit; insertinto insertconflicttest values (12, 'Date') on conflict (lower(fruit), key) do updateset fruit = excluded.fruit;
dropindex comp_key_index;
-- -- Partial index tests, no inference predicate specified -- createuniqueindex part_comp_key_index on insertconflicttest(key, fruit) wherekey < 5; createuniqueindex expr_part_comp_key_index on insertconflicttest(key, lower(fruit)) wherekey < 5;
-- inference fails: insertinto insertconflicttest values (13, 'Grape') on conflict (key, fruit) do updateset fruit = excluded.fruit; insertinto insertconflicttest values (14, 'Raisin') on conflict (fruit, key) do updateset fruit = excluded.fruit; insertinto insertconflicttest values (15, 'Cranberry') on conflict (key) do updateset fruit = excluded.fruit; insertinto insertconflicttest values (16, 'Melon') on conflict (key, key, key) do updatesetfruit = excluded.fruit; insertinto insertconflicttest values (17, 'Mulberry') on conflict (key, lower(fruit)) do updateset fruit = excluded.fruit; insertinto insertconflicttest values (18, 'Pineapple') on conflict (lower(fruit), key) do updateset fruit = excluded.fruit;
-- -- Expression index tests -- createuniqueindex expr_key_index on insertconflicttest(lower(fruit));
-- inference succeeds: insertinto insertconflicttest values (20, 'Quince') on conflict (lower(fruit)) do updateset fruit = excluded.fruit; insertinto insertconflicttest values (21, 'Pomegranate') on conflict (lower(fruit), lower(fruit)) do updateset fruit = excluded.fruit;
-- inference fails: insertinto insertconflicttest values (22, 'Apricot') on conflict (upper(fruit)) do updateset fruit = excluded.fruit; insertinto insertconflicttest values (23, 'Blackberry') on conflict (fruit) do updateset fruit = excluded.fruit;
dropindex expr_key_index;
-- -- Expression index tests (with regular column) -- createuniqueindex expr_comp_key_index on insertconflicttest(key, lower(fruit)); createuniqueindex tricky_expr_comp_key_index on insertconflicttest(key, lower(fruit), upper(fruit));
-- inference succeeds: insertinto insertconflicttest values (24, 'Plum') on conflict (key, lower(fruit)) do updateset fruit = excluded.fruit; insertinto insertconflicttest values (25, 'Peach') on conflict (lower(fruit), key) do updateset fruit = excluded.fruit; -- Should not infer "tricky_expr_comp_key_index" index: explain (costs off) insertinto insertconflicttest values (26, 'Fig') on conflict (lower(fruit), key, lower(fruit), key) do updateset fruit = excluded.fruit;
-- inference fails: insertinto insertconflicttest values (27, 'Prune') on conflict (key, upper(fruit)) do updateset fruit = excluded.fruit; insertinto insertconflicttest values (28, 'Redcurrant') on conflict (fruit, key) do updateset fruit = excluded.fruit; insertinto insertconflicttest values (29, 'Nectarine') on conflict (key) do updateset fruit = excluded.fruit;
-- -- Non-spurious duplicate violation tests -- createuniqueindex key_index on insertconflicttest(key); createuniqueindex fruit_index on insertconflicttest(fruit);
-- succeeds, since UPDATE happens to update "fruit" to existing value: insertinto insertconflicttest values (26, 'Fig') on conflict (key) do updateset fruit = excluded.fruit; -- fails, since UPDATE is to row with key value 26, and we're updating "fruit" -- to a value that happens to exist in another row ('peach'): insertinto insertconflicttest values (26, 'Peach') on conflict (key) do updateset fruit = excluded.fruit; -- succeeds, since "key" isn't repeated/referenced in UPDATE, and "fruit" -- arbitrates that statement updates existing "Fig" row: insertinto insertconflicttest values (25, 'Fig') on conflict (fruit) do updateset fruit = excluded.fruit;
dropindex key_index; dropindex fruit_index;
-- -- Test partial unique index inference -- createuniqueindex partial_key_index on insertconflicttest(key) where fruit like'%berry';
-- Succeeds insertinto insertconflicttest values (23, 'Blackberry') on conflict (key) where fruit like'%berry' do updateset fruit = excluded.fruit; insertinto insertconflicttest as t values (23, 'Blackberry') on conflict (key) where fruit like'%berry'and t.fruit = 'inconsequential' do nothing; insertinto insertconflictview as t values (23, 'Blackberry') on conflict (key) where fruit like'%berry'and t.fruit = 'inconsequential' do nothing;
-- fails insertinto insertconflicttest values (23, 'Blackberry') on conflict (key) do updateset fruit = excluded.fruit; insertinto insertconflicttest values (23, 'Blackberry') on conflict (key) where fruit like'%berry'or fruit = 'consequential' do nothing; insertinto insertconflicttest values (23, 'Blackberry') on conflict (fruit) where fruit like'%berry' do updateset fruit = excluded.fruit;
dropindex partial_key_index;
-- -- Test that wholerow references to ON CONFLICT's EXCLUDED work -- createuniqueindex plain on insertconflicttest(key);
-- Succeeds, updates existing row: insertinto insertconflicttest as i values (23, 'Jackfruit') on conflict (key) do updateset fruit = excluded.fruit where i.* != excluded.* returning *; -- No update this time, though: insertinto insertconflicttest as i values (23, 'Jackfruit') on conflict (key) do updateset fruit = excluded.fruit where i.* != excluded.* returning *; -- Predicate changed to require match rather than non-match, so updates once more: insertinto insertconflicttest as i values (23, 'Jackfruit') on conflict (key) do updateset fruit = excluded.fruit where i.* = excluded.* returning *; -- Assign: insertinto insertconflicttest as i values (23, 'Avocado') on conflict (key) do updateset fruit = excluded.*::text
returning *; -- deparse whole row var in WHERE and SET clauses: explain (costs off) insertinto insertconflicttest as i values (23, 'Avocado') on conflict (key) do updateset fruit = excluded.fruit where excluded.* isnull; explain (costs off) insertinto insertconflicttest as i values (23, 'Avocado') on conflict (key) do updateset fruit = excluded.*::text;
dropindex plain;
-- Cleanup drop view insertconflictview; droptable insertconflicttest;
-- -- Verify that EXCLUDED does not allow system column references. These -- do not make sense because EXCLUDED isn't an already stored tuple -- (and thus doesn't have a ctid etc). -- createtable syscolconflicttest(keyint4, data text); insertinto syscolconflicttest values (1); insertinto syscolconflicttest values (1) on conflict (key) do updateset data = excluded.ctid::text; droptable syscolconflicttest;
-- -- Previous tests all managed to not test any expressions requiring -- planner preprocessing ... -- createtable insertconflict (a bigint, b bigint);
createuniqueindex insertconflicti1 on insertconflict(coalesce(a, 0));
createuniqueindex insertconflicti2 on insertconflict(b) where coalesce(a, 1) > 0;
insertinto insertconflict values (1, 2) on conflict (coalesce(a, 0)) do nothing;
insertinto insertconflict values (1, 2) on conflict (b) where coalesce(a, 1) > 0 do nothing;
insertinto insertconflict values (1, 2) on conflict (b) where coalesce(a, 1) > 1 do nothing;
droptable insertconflict;
-- -- test insertion through view --
createtable insertconflict (f1 intprimarykey, f2 text); create view insertconflictv as select * from insertconflict with cascaded checkoption;
insertinto insertconflictv values (1,'foo') on conflict (f1) do updateset f2 = excluded.f2; select * from insertconflict; insertinto insertconflictv values (1,'bar') on conflict (f1) do updateset f2 = excluded.f2; select * from insertconflict;
drop view insertconflictv; droptable insertconflict;
-- ****************************************************************** -- * * -- * Test inheritance (example taken from tutorial) * -- * * -- ****************************************************************** createtable cities (
name text,
population float8,
altitude int-- (in ft)
);
createtable capitals (
state char(2)
) inherits (cities);
-- Create unique indexes. Due to a general limitation of inheritance, -- uniqueness is only enforced per-relation. Unique index inference -- specification will do the right thing, though. createuniqueindex cities_names_unique on cities (name); createuniqueindex capitals_names_unique on capitals (name);
-- Tests proper for inheritance: select * from capitals;
-- Succeeds: insertinto cities values ('Las Vegas', 2.583E+5, 2174) on conflict do nothing; insertinto capitals values ('Sacramento', 4664.E+5, 30, 'CA') on conflict (name) do updateset population = excluded.population; -- Wrong "Sacramento", so do nothing: insertinto capitals values ('Sacramento', 50, 2267, 'NE') on conflict (name) do nothing; select * from capitals; insertinto cities values ('Las Vegas', 5.83E+5, 2001) on conflict (name) do updateset population = excluded.population, altitude = excluded.altitude; select tableoid::regclass, * from cities; insertinto capitals values ('Las Vegas', 5.83E+5, 2222, 'NV') on conflict (name) do updateset population = excluded.population; -- Capitals will contain new capital, Las Vegas: select * from capitals; -- Cities contains two instances of "Las Vegas", since unique constraints don't -- work across inheritance: select tableoid::regclass, * from cities; -- This only affects "cities" version of "Las Vegas": insertinto cities values ('Las Vegas', 5.86E+5, 2223) on conflict (name) do updateset population = excluded.population, altitude = excluded.altitude; select tableoid::regclass, * from cities;
-- clean up droptable capitals; droptable cities;
-- Make sure a table named excluded is handled properly createtable excluded(keyintprimarykey, data text); insertinto excluded values(1, '1'); -- error, ambiguous insertinto excluded values(1, '2') on conflict (key) do updateset data = excluded.data RETURNING *; -- ok, aliased insertinto excluded AS target values(1, '2') on conflict (key) do updateset data = excluded.data RETURNING *; -- ok, aliased insertinto excluded AS target values(1, '2') on conflict (key) do updateset data = target.data RETURNING *; -- make sure excluded isn't a problem in returning clause insertinto excluded values(1, '2') on conflict (key) do updateset data = 3 RETURNING excluded.*;
-- clean up droptable excluded;
-- check that references to columns after dropped columns are handled correctly createtable dropcol(keyintprimarykey, drop1 int, keep1 text, drop2 numeric, keep2 float); insertinto dropcol(key, drop1, keep1, drop2, keep2) values(1, 1, '1', '1', 1); -- set using excluded insertinto dropcol(key, drop1, keep1, drop2, keep2) values(1, 2, '2', '2', 2) on conflict(key)
do updateset drop1 = excluded.drop1, keep1 = excluded.keep1, drop2 = excluded.drop2, keep2 = excluded.keep2 where excluded.drop1 isnotnulland excluded.keep1 isnotnulland excluded.drop2 isnotnulland excluded.keep2 isnotnull and dropcol.drop1 isnotnulland dropcol.keep1 isnotnulland dropcol.drop2 isnotnulland dropcol.keep2 isnotnull
returning *;
; -- set using existing table insertinto dropcol(key, drop1, keep1, drop2, keep2) values(1, 3, '3', '3', 3) on conflict(key)
do updateset drop1 = dropcol.drop1, keep1 = dropcol.keep1, drop2 = dropcol.drop2, keep2 = dropcol.keep2
returning *;
; altertable dropcol dropcolumn drop1, dropcolumn drop2; -- set using excluded insertinto dropcol(key, keep1, keep2) values(1, '4', 4) on conflict(key)
do updateset keep1 = excluded.keep1, keep2 = excluded.keep2 where excluded.keep1 isnotnulland excluded.keep2 isnotnull and dropcol.keep1 isnotnulland dropcol.keep2 isnotnull
returning *;
; -- set using existing table insertinto dropcol(key, keep1, keep2) values(1, '5', 5) on conflict(key)
do updateset keep1 = dropcol.keep1, keep2 = dropcol.keep2
returning *;
;
DROPTABLE dropcol;
-- check handling of regular btree constraint along with gist constraint
createtable twoconstraints (f1 intunique, f2 box,
exclude using gist(f2 with &&)); insertinto twoconstraints values(1, '((0,0),(1,1))'); insertinto twoconstraints values(1, '((2,2),(3,3))'); -- fail on f1 insertinto twoconstraints values(2, '((0,0),(1,2))'); -- fail on f2 insertinto twoconstraints values(2, '((0,0),(1,2))') on conflict onconstraint twoconstraints_f1_key do nothing; -- fail on f2 insertinto twoconstraints values(2, '((0,0),(1,2))') on conflict onconstraint twoconstraints_f2_excl do nothing; -- do nothing select * from twoconstraints; droptable twoconstraints;
-- check handling of self-conflicts at various isolation levels
begin transaction isolation level read committed; insertinto selfconflict values (1,1), (1,2) on conflict do nothing; commit;
begin transaction isolation level repeatable read; insertinto selfconflict values (2,1), (2,2) on conflict do nothing; commit;
begin transaction isolation level serializable; insertinto selfconflict values (3,1), (3,2) on conflict do nothing; commit;
begin transaction isolation level read committed; insertinto selfconflict values (4,1), (4,2) on conflict(f1) do updateset f2 = 0; commit;
begin transaction isolation level repeatable read; insertinto selfconflict values (5,1), (5,2) on conflict(f1) do updateset f2 = 0; commit;
begin transaction isolation level serializable; insertinto selfconflict values (6,1), (6,2) on conflict(f1) do updateset f2 = 0; commit;
select * from selfconflict;
droptable selfconflict;
-- check ON CONFLICT handling with partitioned tables createtable parted_conflict_test (a intunique, b char) partition by list (a); createtable parted_conflict_test_1 partition of parted_conflict_test (b unique) forvaluesin (1, 2);
-- no indexes required here insertinto parted_conflict_test values (1, 'a') on conflict do nothing;
-- index on a required, which does exist in parent insertinto parted_conflict_test values (1, 'a') on conflict (a) do nothing; insertinto parted_conflict_test values (1, 'a') on conflict (a) do updateset b = excluded.b;
-- targeting partition directly will work insertinto parted_conflict_test_1 values (1, 'a') on conflict (a) do nothing; insertinto parted_conflict_test_1 values (1, 'b') on conflict (a) do updateset b = excluded.b;
-- index on b required, which doesn't exist in parent insertinto parted_conflict_test values (2, 'b') on conflict (b) do updateset a = excluded.a;
-- targeting partition directly will work insertinto parted_conflict_test_1 values (2, 'b') on conflict (b) do updateset a = excluded.a;
-- should see (2, 'b') select * from parted_conflict_test orderby a;
-- now check that DO UPDATE works correctly for target partition with -- different attribute numbers createtable parted_conflict_test_2 (b char, a intunique); altertable parted_conflict_test attach partition parted_conflict_test_2 forvaluesin (3);
truncate parted_conflict_test; insertinto parted_conflict_test values (3, 'a') on conflict (a) do updateset b = excluded.b; insertinto parted_conflict_test values (3, 'b') on conflict (a) do updateset b = excluded.b;
-- should see (3, 'b') select * from parted_conflict_test orderby a;
-- case where parent will have a dropped column, but the partition won't altertable parted_conflict_test drop b, add b char; createtable parted_conflict_test_3 partition of parted_conflict_test forvaluesin (4);
truncate parted_conflict_test; insertinto parted_conflict_test (a, b) values (4, 'a') on conflict (a) do updateset b = excluded.b; insertinto parted_conflict_test (a, b) values (4, 'b') on conflict (a) do updateset b = excluded.b where parted_conflict_test.b = 'a';
-- should see (4, 'b') select * from parted_conflict_test orderby a;
-- case with multi-level partitioning createtable parted_conflict_test_4 partition of parted_conflict_test forvaluesin (5) partition by list (a); createtable parted_conflict_test_4_1 partition of parted_conflict_test_4 forvaluesin (5);
truncate parted_conflict_test; insertinto parted_conflict_test (a, b) values (5, 'a') on conflict (a) do updateset b = excluded.b; insertinto parted_conflict_test (a, b) values (5, 'b') on conflict (a) do updateset b = excluded.b where parted_conflict_test.b = 'a';
-- should see (5, 'b') select * from parted_conflict_test orderby a;
-- test with multiple rows
truncate parted_conflict_test; insertinto parted_conflict_test (a, b) values (1, 'a'), (2, 'a'), (4, 'a') on conflict (a) do updateset b = excluded.b where excluded.b = 'b'; insertinto parted_conflict_test (a, b) values (1, 'b'), (2, 'c'), (4, 'b') on conflict (a) do updateset b = excluded.b where excluded.b = 'b';
-- should see (1, 'b'), (2, 'a'), (4, 'b') select * from parted_conflict_test orderby a;
droptable parted_conflict_test;
-- test behavior of inserting a conflicting tuple into an intermediate -- partitioning level createtable parted_conflict (a intprimarykey, b text) partition by range (a); createtable parted_conflict_1 partition of parted_conflict forvaluesfrom (0) to (1000) partition by range (a); createtable parted_conflict_1_1 partition of parted_conflict_1 forvaluesfrom (0) to (500); insertinto parted_conflict values (40, 'forty'); insertinto parted_conflict_1 values (40, 'cuarenta') on conflict (a) do updateset b = excluded.b; droptable parted_conflict;
-- same thing, but this time try to use an index that's created not in the -- partition createtable parted_conflict (a int, b text) partition by range (a); createtable parted_conflict_1 partition of parted_conflict forvaluesfrom (0) to (1000) partition by range (a); createtable parted_conflict_1_1 partition of parted_conflict_1 forvaluesfrom (0) to (500); createuniqueindexon only parted_conflict_1 (a); createuniqueindexon only parted_conflict (a); alterindex parted_conflict_a_idx attach partition parted_conflict_1_a_idx; insertinto parted_conflict values (40, 'forty'); insertinto parted_conflict_1 values (40, 'cuarenta') on conflict (a) do updateset b = excluded.b; droptable parted_conflict;
-- test whole-row Vars in ON CONFLICT expressions createtable parted_conflict (a int, b text, c int) partition by range (a); createtable parted_conflict_1 (drp text, c int, a int, b text); altertable parted_conflict_1 dropcolumn drp; createuniqueindexon parted_conflict (a, b); altertable parted_conflict attach partition parted_conflict_1 forvaluesfrom (0) to (1000);
truncate parted_conflict; insertinto parted_conflict values (50, 'cincuenta', 1); insertinto parted_conflict values (50, 'cincuenta', 2) on conflict (a, b) do updateset (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 orderby a;
-- test with statement level triggers createorreplace function parted_conflict_update_func() returns triggeras $$ declare
r record;
begin for r inselect * from inserted loop
raise notice 'a = %, b = %, c = %', r.a, r.b, r.c;
end loop; return new;
end;
$$ language plpgsql;
createtrigger parted_conflict_update
after updateon parted_conflict
referencing new tableas inserted foreach statement
execute procedure parted_conflict_update_func();
truncate parted_conflict;
insertinto parted_conflict values (0, 'cero', 1);
insertinto parted_conflict values(0, 'cero', 1) on conflict (a,b) do updateset c = parted_conflict.c + 1;
droptable parted_conflict; drop function parted_conflict_update_func();
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.41 Sekunden
(vorverarbeitet am 2026-08-08)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.