should be it

This commit is contained in:
2025-10-24 19:21:19 -05:00
parent a4b23fc57c
commit f09560c7b1
14047 changed files with 3161551 additions and 1 deletions

View File

@@ -0,0 +1,109 @@
# name: test/sql/upsert/postgres/composite_key.test
# group: [postgres]
statement ok
pragma enable_verification;
# insert...on conflict do unique index inference
statement ok
create table insertconflicttest(
key int4,
fruit text,
other int4,
unique (key, fruit)
);
# fails
statement error
insert into insertconflicttest values(0, 'Crowberry', 0) on conflict (key) do nothing;
----
statement error
insert into insertconflicttest values(0, 'Crowberry', 0) on conflict (fruit) do nothing;
----
# succeeds
statement ok
insert into insertconflicttest values(0, 'Crowberry', 0) on conflict (key, fruit) do nothing;
statement ok
insert into insertconflicttest values(0, 'Crowberry', 0) on conflict (fruit, key, fruit, key) do nothing;
## -- We explicitly don't support a subquery in the WHERE clause currently -- ##
statement error
insert into insertconflicttest
values (0, 'Crowberry', 0) on conflict (key, fruit) do update set other = 1 where exists (select 1 from insertconflicttest ii where ii.key = excluded.key);
----
DO UPDATE SET clause cannot contain a subquery
# inference succeeds:
statement ok
insert into insertconflicttest values (7, 'Raspberry', 0) on conflict (key, fruit) do update set other = 1
statement ok
insert into insertconflicttest values (8, 'Lime', 0) on conflict (fruit, key) do update set other = 1
# inference fails:
statement error
insert into insertconflicttest values (9, 'Banana', 0) on conflict (key) do update set other = 1
----
statement error
insert into insertconflicttest values (10, 'Blueberry', 0) on conflict (key, key, key) do update set other = 1
----
## -- This fails on postgres for some reason? -- ##
statement ok
insert into insertconflicttest values (11, 'Cherry', 0) on conflict (key, fruit) do update set other = 1
## -- This fails on postgres for some reason? -- ##
statement ok
insert into insertconflicttest values (12, 'Date', 0) on conflict (fruit, key) do update set other = 1
# Partial index tests, no inference predicate specified
statement error
create unique index part_comp_key_index on insertconflicttest(key, fruit) where key < 5;
----
Creating partial indexes is not supported currently
statement error
create unique index expr_part_comp_key_index on insertconflicttest(key, fruit) where key < 5;
----
Creating partial indexes is not supported currently
# Expression index tests
statement ok
create unique index expr_key_index on insertconflicttest(fruit);
# inference succeeds:
statement ok
insert into insertconflicttest values (20, 'Quince', 0) on conflict (fruit) do update set other = 1
statement ok
insert into insertconflicttest values (21, 'Pomegranate', 0) on conflict (fruit, fruit) do update set other = 1
# Expression index tests (with regular column)
statement ok
create unique index expr_comp_key_index on insertconflicttest(key, fruit);
statement ok
create unique index tricky_expr_comp_key_index on insertconflicttest(key, fruit, fruit);
# inference succeeds:
statement ok
insert into insertconflicttest values (24, 'Plum', 0) on conflict (key, fruit) do update set other = 1
statement ok
insert into insertconflicttest values (25, 'Peach', 0) on conflict (fruit, key) do update set other = 1
# Should not infer "tricky_expr_comp_key_index" index:
statement ok
insert into insertconflicttest values (26, 'Fig', 0) on conflict (fruit, key, fruit, key) do update set other = 1

View File

@@ -0,0 +1,56 @@
# name: test/sql/upsert/postgres/non_spurious_duplicate_violation.test
# group: [postgres]
statement ok
pragma enable_verification;
# insert...on conflict do unique index inference
statement ok
create table insertconflicttest(
key int4,
fruit text,
other int4,
unique (key),
unique (fruit)
);
statement ok
insert into insertconflicttest values (25, 'Fig', 0) on conflict (fruit) do update set other = 1
# Succeeds
statement ok
insert into insertconflicttest values (23, 'Blackberry', 0) on conflict (key) do update set other = 1 where fruit like '%berry'
# Test that wholerow references to ON CONFLICT's EXCLUDED work
# Succeeds, updates existing row:
statement ok
insert into insertconflicttest as i values (23, 'Jackfruit', 0) on conflict (key) do update set other = 1
# No update this time, though:
statement ok
insert into insertconflicttest as i values (23, 'Jackfruit', 0) on conflict (key) do update set other = 1
# Predicate changed to require match rather than non-match, so updates once more:
statement ok
insert into insertconflicttest as i values (23, 'Jackfruit', 0) on conflict (key) do update set other = 1
# Assign:
statement ok
insert into insertconflicttest as i values (23, 'Avocado', 0) on conflict (key) do update set other = 1
# deparse whole row var in WHERE and SET clauses:
statement ok
insert into insertconflicttest as i values (23, 'Avocado', 0) on conflict (key) do update set other = 1
statement ok
insert into insertconflicttest as i values (23, 'Avocado', 0) on conflict (key) do update set other = 1
# Cleanup
statement ok
drop table insertconflicttest;

View File

@@ -0,0 +1,207 @@
# name: test/sql/upsert/postgres/planner_preprocessing.test
# group: [postgres]
statement ok
pragma enable_verification;
# ******************************************************************
# * *
# * Test inheritance (example taken from tutorial) *
# * *
# ******************************************************************
statement ok
create table cities (
name text,
population float8,
altitude int,
unique (name)
);
statement ok
create table capitals (
name text,
population float8,
altitude int,
state char(2),
unique (name)
);
# 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.
# prepopulate the tables.
statement ok
insert into cities values ('San Francisco', 7.24E+5, 63);
statement ok
insert into cities values ('Las Vegas', 2.583E+5, 2174);
statement ok
insert into cities values ('Mariposa', 1200, 1953);
statement ok
insert into capitals values ('Sacramento', 3.694E+5, 30, 'CA');
statement ok
insert into capitals values ('Madison', 1.913E+5, 845, 'WI');
# Tests proper for inheritance:
query IIII
select * from capitals;
----
Sacramento 369400.0 30 CA
Madison 191300.0 845 WI
# Succeeds:
statement ok
insert into cities values ('Las Vegas', 2.583E+5, 2174) on conflict do nothing;
statement ok
insert into capitals values ('Sacramento', 4664.E+5, 30, 'CA') on conflict (name) do update set population = excluded.population;
# Wrong "Sacramento", so do nothing:
statement ok
insert into capitals values ('Sacramento', 50, 2267, 'NE') on conflict (name) do nothing;
query IIII
select * from capitals;
----
Sacramento 466400000.0 30 CA
Madison 191300.0 845 WI
statement ok
insert into cities values ('Las Vegas', 5.83E+5, 2001) on conflict (name) do update set population = excluded.population, altitude = excluded.altitude;
query IIII
select rowid, * from cities;
----
0 San Francisco 724000.0 63
1 Las Vegas 583000.0 2001
2 Mariposa 1200.0 1953
statement ok
insert into capitals values ('Las Vegas', 5.83E+5, 2222, 'NV') on conflict (name) do update set population = excluded.population;
# Capitals will contain new capital, Las Vegas:
query IIII
select * from capitals;
----
Sacramento 466400000.0 30 CA
Madison 191300.0 845 WI
Las Vegas 583000.0 2222 NV
# Cities contains two instances of "Las Vegas", since unique constraints don't
# work across inheritance:
query IIII
select rowid, * from cities;
----
0 San Francisco 724000.0 63
1 Las Vegas 583000.0 2001
2 Mariposa 1200.0 1953
# This only affects "cities" version of "Las Vegas":
statement ok
insert into cities values ('Las Vegas', 5.86E+5, 2223) on conflict (name) do update set population = excluded.population, altitude = excluded.altitude;
select rowid, * from cities;
# clean up
statement ok
drop table capitals;
statement ok
drop table cities;
# Make sure a table named excluded is handled properly
statement ok
create table excluded(key int primary key, data text);
statement ok
insert into excluded values(1, '1');
# error, ambiguous
statement error
insert into excluded values(1, '2') on conflict (key) do update set data = excluded.data RETURNING *;
----
# ok, aliased
statement ok
insert into excluded AS target values(1, '2') on conflict (key) do update set data = excluded.data RETURNING *;
# ok, aliased
statement ok
insert into excluded AS target values(1, '2') on conflict (key) do update set data = target.data RETURNING *;
## -- We don't support excluded in RETURNING, also, this is ambiguous??? -- ##
# make sure excluded isn't a problem in returning clause
statement error
insert into excluded values(1, '2') on conflict (key) do update set data = 3 RETURNING excluded.*;
----
Ambiguous reference to table "excluded"
# clean up
statement ok
drop table excluded;
# check that references to columns after dropped columns are handled correctly
statement ok
create table dropcol(key int primary key, drop1 int, keep1 text, drop2 numeric, keep2 float);
statement ok
insert into dropcol(key, drop1, keep1, drop2, keep2) values(1, 1, '1', '1', 1);
# set using excluded
statement ok
insert into dropcol(key, drop1, keep1, drop2, keep2) values(1, 2, '2', '2', 2) on conflict(key)
do update set drop1 = excluded.drop1, keep1 = excluded.keep1, drop2 = excluded.drop2, keep2 = excluded.keep2
where excluded.drop1 is not null and excluded.keep1 is not null and excluded.drop2 is not null and excluded.keep2 is not null
and dropcol.drop1 is not null and dropcol.keep1 is not null and dropcol.drop2 is not null and dropcol.keep2 is not null
returning *;
;
# set using existing table
statement ok
insert into dropcol(key, drop1, keep1, drop2, keep2) values(1, 3, '3', '3', 3) on conflict(key)
do update set drop1 = dropcol.drop1, keep1 = dropcol.keep1, drop2 = dropcol.drop2, keep2 = dropcol.keep2
returning *;
;
statement ok
alter table dropcol
drop column drop1;
statement ok
alter table dropcol
drop column drop2;
# set using excluded
statement ok
insert into dropcol(key, keep1, keep2) values(1, '4', 4) on conflict(key)
do update set keep1 = excluded.keep1, keep2 = excluded.keep2
where excluded.keep1 is not null and excluded.keep2 is not null
and dropcol.keep1 is not null and dropcol.keep2 is not null
returning *;
;
# set using existing table
statement ok
insert into dropcol(key, keep1, keep2) values(1, '5', 5) on conflict(key)
do update set keep1 = dropcol.keep1, keep2 = dropcol.keep2
returning *;
;
statement ok
DROP TABLE dropcol;

View File

@@ -0,0 +1,111 @@
# name: test/sql/upsert/postgres/single_key.test
# group: [postgres]
statement ok
pragma enable_verification;
# insert...on conflict do unique index inference
statement ok
create table insertconflicttest(
key int4,
fruit text,
unique (key)
);
# Explain tests
statement ok
insert into insertconflicttest values (0, 'Bilberry') on conflict (key) do update set fruit = excluded.fruit;
# Should display qual actually attributable to internal sequential scan:
statement ok
insert into insertconflicttest values (0, 'Bilberry') on conflict (key) do update set fruit = excluded.fruit where insertconflicttest.fruit != 'Cawesh';
# With EXCLUDED.* expression in scan node:
statement ok
insert into insertconflicttest values(0, 'Crowberry') on conflict (key) do update set fruit = excluded.fruit where excluded.fruit != 'Elderberry';
# Does the same, but JSON format shows "Conflict Arbiter Index" as JSON array:
statement ok
insert into insertconflicttest values (0, 'Bilberry') on conflict (key) do update set fruit = excluded.fruit where insertconflicttest.fruit != 'Lime' returning *;
# Fails (no unique index inference specification, required for do update variant):
## -- We accept this because there is only 1 Index on the table -- ##
statement ok
insert into insertconflicttest values (1, 'Apple') on conflict do update set fruit = excluded.fruit;
# inference succeeds:
statement ok
insert into insertconflicttest values (1, 'Apple') on conflict (key) do update set fruit = excluded.fruit;
statement ok
insert into insertconflicttest values (2, 'Orange') on conflict (key, key, key) do update set fruit = excluded.fruit;
# Succeed, since multi-assignment does not involve subquery:
statement ok
INSERT INTO insertconflicttest VALUES (1, 'Apple'), (2, 'Orange')
ON CONFLICT (key) DO UPDATE SET fruit = excluded.fruit, key = excluded.key;
# Give good diagnostic message when EXCLUDED.* spuriously referenced from
# RETURNING:
## -- We don't support 'excluded' qualified columns in the RETURNING clause yet -- ##
statement error
insert into insertconflicttest values (1, 'Apple') on conflict (key) do update set fruit = excluded.fruit RETURNING excluded.fruit;
----
<REGEX>:.*Not implemented Error.*not supported in the RETURNING clause yet.*
# Only suggest <table>.* column when inference element misspelled:
statement error
insert into insertconflicttest values (1, 'Apple') on conflict (keyy) do update set fruit = excluded.fruit;
----
<REGEX>:.*Binder Error.*Table "insertconflicttest" does not have a column.*
# Have useful HINT for EXCLUDED.* RTE within UPDATE:
statement error
insert into insertconflicttest values (1, 'Apple') on conflict (key) do update set fruit = excluded.fruitt;
----
<REGEX>:.*Binder Error.*does not have a column named "fruitt".*
# inference fails:
statement error
insert into insertconflicttest values (3, 'Kiwi') on conflict (key, fruit) do update set fruit = excluded.fruit;
----
<REGEX>:.*Binder Error.*not referenced by a UNIQUE/PRIMARY KEY CONSTRAINT or INDEX.*
statement error
insert into insertconflicttest values (4, 'Mango') on conflict (fruit, key) do update set fruit = excluded.fruit;
----
<REGEX>:.*Binder Error.*not referenced by a UNIQUE/PRIMARY KEY CONSTRAINT or INDEX.*
statement error
insert into insertconflicttest values (5, 'Lemon') on conflict (fruit) do update set fruit = excluded.fruit;
----
<REGEX>:.*Binder Error.*not referenced by a UNIQUE/PRIMARY KEY CONSTRAINT or INDEX.*
statement error
insert into insertconflicttest values (6, 'Passionfruit') on conflict (fruit) do update set fruit = excluded.fruit;
----
<REGEX>:.*Binder Error.*not referenced by a UNIQUE/PRIMARY KEY CONSTRAINT or INDEX.*
# Check the target relation can be aliased
statement ok
insert into insertconflicttest AS ict values (6, 'Passionfruit') on conflict (key) do update set fruit = excluded.fruit;
# ok, no reference to target table
statement ok
insert into insertconflicttest AS ict values (6, 'Passionfruit') on conflict (key) do update set fruit = ict.fruit;
# ok, alias
# error, references aliased away name
statement error
insert into insertconflicttest AS ict values (6, 'Passionfruit') on conflict (key) do update set fruit = insertconflicttest.fruit;
----
<REGEX>:.*Binder Error.*Referenced table.*not found.*