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,27 @@
# name: test/sql/constraints/check/check_struct.test
# description: CHECK constraint on structs
# group: [check]
statement ok
CREATE TABLE tbl(t ROW(t INTEGER) CHECK(t.t=42));
statement error
INSERT INTO tbl VALUES ({'t': 43})
----
statement ok
INSERT INTO tbl VALUES ({'t': 42})
statement ok
DROP TABLE tbl;
# we can also do this while referencing the table name
statement ok
CREATE TABLE tbl(t ROW(t INTEGER) CHECK(tbl.t.t=42));
statement error
INSERT INTO tbl VALUES ({'t': 43})
----
statement ok
INSERT INTO tbl VALUES ({'t': 42})

View File

@@ -0,0 +1,74 @@
# name: test/sql/constraints/check/test_check.test
# description: CHECK constraint
# group: [check]
statement ok
CREATE TABLE integers(i INTEGER CHECK(i < 5))
statement ok
INSERT INTO integers VALUES (3)
statement error
INSERT INTO integers VALUES (7)
----
statement ok
INSERT INTO integers VALUES (NULL)
query I
SELECT * FROM integers
----
3
NULL
statement ok
DROP TABLE integers;
statement ok
CREATE TABLE integers(i INTEGER CHECK(i + j < 10), j INTEGER)
statement ok
INSERT INTO integers VALUES (3, 3)
statement error
INSERT INTO integers VALUES (5, 5)
----
statement error
INSERT INTO integers VALUES (3, 3), (5, 5)
----
query II
SELECT * FROM integers
----
3 3
statement error
CREATE TABLE indirect_subq(
i INTEGER,
CHECK (i > (2 * (SELECT(1))))
);
----
statement error
CREATE TABLE integers2(i INTEGER CHECK(i > (SELECT 42)), j INTEGER)
----
statement error
CREATE TABLE integers2(i INTEGER CHECK(i > SUM(j)), j INTEGER)
----
statement error
CREATE TABLE integers3(i INTEGER CHECK(k < 10), j INTEGER)
----
statement error
CREATE TABLE integers3(i INTEGER CHECK(integers3.k < 10), j INTEGER)
----
statement error
CREATE TABLE integers3(i INTEGER CHECK(integers2.i < 10), j INTEGER)
----
statement ok
CREATE TABLE integers4(i INTEGER CHECK(integers4.i < 10), j INTEGER)

View File

@@ -0,0 +1,108 @@
# name: test/sql/constraints/foreignkey/fk_4309.test
# description: Issue #4309: Test deleting from a parent table with multiple foreign key constraints.
# group: [foreignkey]
# fks:
# d -> a
# e -> b
# f -> c
statement ok
CREATE TABLE tf_1 (
a integer, b integer, c integer,
PRIMARY KEY (a),
UNIQUE (b),
UNIQUE (c)
);
statement ok
CREATE TABLE tf_2 (
d integer, e integer, f integer,
FOREIGN KEY (d) REFERENCES tf_1 (a),
FOREIGN KEY (e) REFERENCES tf_1 (b),
FOREIGN KEY (f) REFERENCES tf_1 (c)
);
# key "1" does not exist yet
statement error
INSERT INTO tf_2 VALUES (1, 1, 1);
----
<REGEX>:Constraint Error.*Violates foreign key constraint.*does not exist in the referenced table.*
# insert key (1, 1, 1)
statement ok
INSERT INTO tf_1 VALUES (1, 1, 1);
# all these fail (all three need to match)
statement error
INSERT INTO tf_2 VALUES (2, 1, 1);
----
<REGEX>:Constraint Error.*Violates foreign key constraint.*does not exist in the referenced table.*
statement error
INSERT INTO tf_2 VALUES (1, 2, 1);
----
<REGEX>:Constraint Error.*Violates foreign key constraint.*does not exist in the referenced table.*
statement error
INSERT INTO tf_2 VALUES (1, 1, 2);
----
<REGEX>:Constraint Error.*Violates foreign key constraint.*does not exist in the referenced table.*
# this succeeds
statement ok
INSERT INTO tf_2 VALUES (1, 1, 1);
# now insert (2, NULL, NULL)
statement ok
INSERT INTO tf_1 VALUES (2, NULL, NULL);
# insert a dependency
statement ok
INSERT INTO tf_2 VALUES (2, NULL, NULL);
# we should not be able to delete this key now
statement error
DELETE FROM tf_1 WHERE a = 2;
----
<REGEX>:Constraint Error.*Violates foreign key constraint.*still referenced by a foreign key in a different table.*
# delete everything with a|b = 2
statement ok
DELETE FROM tf_2 WHERE d=2;
statement ok
DELETE FROM tf_1 WHERE a=2;
# insert (2, 3, NULL)
statement ok
INSERT INTO tf_1 VALUES (2, 3, NULL);
# this is fine
statement ok
INSERT INTO tf_2 VALUES (1, 3, 1);
# this should (still) not work
statement error
DELETE FROM tf_1 WHERE a = 2;
----
<REGEX>:Constraint Error.*Violates foreign key constraint.*still referenced by a foreign key in a different table.*
# delete everything with a|b = 2
statement ok
DELETE FROM tf_2 WHERE d=2 OR e=3;
statement ok
DELETE FROM tf_1 WHERE a=2;
# insert (2, NULL, 4)
statement ok
INSERT INTO tf_1 VALUES (2, NULL, 4);
statement ok
INSERT INTO tf_2 VALUES (1, 1, 4);
statement error
DELETE FROM tf_1 WHERE a = 2;
----
<REGEX>:Constraint Error.*Violates foreign key constraint.*still referenced by a foreign key in a different table.*

View File

@@ -0,0 +1,15 @@
# name: test/sql/constraints/foreignkey/fk_4365.test
# description: Issue #4365: Multiple NOT NULL constraints in duckdb_constraints()
# group: [foreignkey]
statement ok
create table x (c1 integer, primary key (c1));
# This should not add a second NOT NULL constraint, because it already exists
statement ok
create table y (c1 integer, foreign key (c1) references x (c1));
query I
select count(*) from duckdb_constraints() where constraint_type = 'NOT NULL';
----
1

View File

@@ -0,0 +1,26 @@
# name: test/sql/constraints/foreignkey/fk_case_insensitivity.test
# description: Issue #7119/#7120: foreign key case insensitivity
# group: [foreignkey]
# issue 7119
statement ok
create table a (a int not null, constraint pk_a primary key (A));
statement ok
create table b (a int references a (a));
statement ok
drop table b;
statement ok
drop table a;
# issue 7120
statement ok
create table a (i int primary key);
statement ok
create table b (i int references A (i));
statement ok
create table c (i int primary key, j int references C (i));

View File

@@ -0,0 +1,49 @@
# name: test/sql/constraints/foreignkey/fk_implicit_primary_key.test
# description: Issue #7118: implicitly link to primary key
# group: [foreignkey]
statement ok
create table a (i int primary key);
statement ok
create table b (i int references a);
statement error
insert into b values (1)
----
does not exist in the referenced table
statement ok
insert into a values (1);
statement ok
insert into b values (1)
# other tests
statement ok
drop table b;
statement ok
drop table a;
# what if a does not have a primary key
statement ok
create table a (i int);
statement error
create table b (i int references a);
----
there is no primary key for referenced table
statement ok
drop table a
# what if there is a column count mismatch
statement ok
create table a (i int, j int, primary key(i,j));
statement error
create table b (i int references a);
----
number of referencing

View File

@@ -0,0 +1,110 @@
# name: test/sql/constraints/foreignkey/foreign_key_matching_columns.test
# description: Issue #3505: foreign key support without an explicit column name
# group: [foreignkey]
# non-existant reference
statement error
CREATE TABLE routes (
route_id TEXT PRIMARY KEY,
agency_id TEXT,
FOREIGN KEY (agency_id) REFERENCES agency
);
----
statement ok
CREATE TABLE agency (
agency_id TEXT PRIMARY KEY,
agency_name TEXT UNIQUE NOT NULL
);
# column count mismatch
statement error
CREATE TABLE routes (
route_id TEXT PRIMARY KEY,
agency_id TEXT,
FOREIGN KEY (route_id, agency_id) REFERENCES agency
);
----
statement ok
CREATE TABLE routes (
route_id TEXT PRIMARY KEY,
agency_id TEXT,
FOREIGN KEY (agency_id) REFERENCES agency
);
# verify foreign key functionality
statement error
INSERT INTO routes VALUES (1, 1);
----
statement ok
INSERT INTO agency VALUES (1, 1);
statement ok
INSERT INTO routes VALUES (1, 1);
# now without a primary key
statement error
DROP TABLE agency;
----
statement ok
DROP TABLE routes;
statement ok
DROP TABLE agency;
statement ok
CREATE TABLE agency (
agency_id TEXT,
agency_name TEXT NOT NULL
);
statement error
CREATE TABLE routes (
route_id TEXT PRIMARY KEY,
agency_id TEXT,
FOREIGN KEY (agency_id) REFERENCES agency
);
----
# self-referential primary key
statement ok
CREATE TABLE routes (
route_id TEXT PRIMARY KEY,
agency_id TEXT,
FOREIGN KEY (agency_id) REFERENCES routes
);
statement ok
INSERT INTO routes VALUES (1, NULL);
statement error
INSERT INTO routes VALUES (2, 2);
----
statement ok
INSERT INTO routes VALUES (2, 1);
# multi-column primary key constraint
statement ok
DROP TABLE routes;
statement ok
DROP TABLE agency;
statement ok
CREATE TABLE agency (
agency_id TEXT,
agency_id_2 TEXT,
agency_name TEXT NOT NULL,
PRIMARY KEY (agency_id, agency_id_2)
);
statement ok
CREATE TABLE routes (
route_id TEXT PRIMARY KEY,
agency_id TEXT,
FOREIGN KEY (route_id, agency_id) REFERENCES agency
);

View File

@@ -0,0 +1,49 @@
# name: test/sql/constraints/foreignkey/test_action.test
# description: Test non-default foreign key actions
# group: [foreignkey]
statement ok
CREATE TABLE t1(id INTEGER PRIMARY KEY);
# this is fine
statement ok
CREATE TABLE t2(id INTEGER PRIMARY KEY, t1_id INTEGER, FOREIGN KEY (t1_id) REFERENCES t1(id));
statement ok
CREATE TABLE t3(id INTEGER PRIMARY KEY, t1_id INTEGER, FOREIGN KEY (t1_id) REFERENCES t1(id) ON UPDATE NO ACTION);
statement ok
CREATE TABLE t4(id INTEGER PRIMARY KEY, t1_id INTEGER, FOREIGN KEY (t1_id) REFERENCES t1(id) ON DELETE NO ACTION);
statement ok
CREATE TABLE t5(id INTEGER PRIMARY KEY, t1_id INTEGER, FOREIGN KEY (t1_id) REFERENCES t1(id) ON UPDATE RESTRICT);
statement ok
CREATE TABLE t6(id INTEGER PRIMARY KEY, t1_id INTEGER, FOREIGN KEY (t1_id) REFERENCES t1(id) ON DELETE RESTRICT);
# this is not
statement error
CREATE TABLE t7(id INTEGER PRIMARY KEY, t1_id INTEGER, FOREIGN KEY (t1_id) REFERENCES t1(id) ON UPDATE CASCADE);
----
statement error
CREATE TABLE t8(id INTEGER PRIMARY KEY, t1_id INTEGER, FOREIGN KEY (t1_id) REFERENCES t1(id) ON DELETE CASCADE);
----
statement error
CREATE TABLE t9(id INTEGER PRIMARY KEY, t1_id INTEGER, FOREIGN KEY (t1_id) REFERENCES t1(id) ON UPDATE SET DEFAULT);
----
statement error
CREATE TABLE t10(id INTEGER PRIMARY KEY, t1_id INTEGER, FOREIGN KEY (t1_id) REFERENCES t1(id) ON DELETE SET DEFAULT);
----
statement error
CREATE TABLE t11(id INTEGER PRIMARY KEY, t1_id INTEGER, FOREIGN KEY (t1_id) REFERENCES t1(id) ON UPDATE SET NULL);
----
statement error
CREATE TABLE t12(id INTEGER PRIMARY KEY, t1_id INTEGER, FOREIGN KEY (t1_id) REFERENCES t1(id) ON DELETE SET NULL);
----

View File

@@ -0,0 +1,36 @@
# name: test/sql/constraints/foreignkey/test_fk_alter.test
# group: [foreignkey]
statement ok
CREATE TABLE departments (
department_id INTEGER PRIMARY KEY,
department_name VARCHAR(100) NOT NULL
);
statement ok
CREATE TABLE employees (
employee_id INTEGER PRIMARY KEY,
employee_name VARCHAR(100) NOT NULL,
department_id INT REFERENCES departments(department_id)
);
statement error
drop table departments
----
Catalog Error: Could not drop the table because this table is main key table of the table "employees"
# FIXME: we would need to update the foreign key constraint of the tables that are referencing 'employees'
# to fix this, propagating an alter down.
# (or use Postgres's solution of using oids to add a layer of indirection so we dont need to do cleanup whenever a rename is done)
statement error
ALTER TABLE departments RENAME TO old_departments
----
Dependency Error: Cannot alter entry "departments" because there are entries that depend on it.
statement error
drop table departments
----
Catalog Error: Could not drop the table because this table is main key table of the table "employees"
statement ok
ALTER TABLE employees RENAME TO old_employees

View File

@@ -0,0 +1,96 @@
# name: test/sql/constraints/foreignkey/test_fk_chain.test
# description: tests involving longer chains of foreign key tables
# group: [foreignkey]
statement ok
CREATE TABLE t1(i1 INTEGER UNIQUE)
statement ok
INSERT INTO t1 VALUES (1), (2), (3), (4)
statement ok
CREATE TABLE t2(i2 INTEGER PRIMARY KEY, FOREIGN KEY (i2) REFERENCES t1(i1))
statement ok
INSERT INTO t2 VALUES (1), (2), (3)
statement ok
CREATE TABLE t3(i3 INTEGER UNIQUE, FOREIGN KEY (i3) REFERENCES t2(i2))
statement ok
INSERT INTO t3 VALUES (1), (2)
statement ok
CREATE TABLE t4(i4 INTEGER, FOREIGN KEY (i4) REFERENCES t3(i3))
statement ok
INSERT INTO t4 VALUES (1)
# insert
statement error
INSERT INTO t2 VALUES (5)
----
statement error
INSERT INTO t3 VALUES (4)
----
statement error
INSERT INTO t4 VALUES (3)
----
statement ok
INSERT INTO t2 VALUES (4)
statement ok
INSERT INTO t3 VALUES (3)
statement ok
INSERT INTO t4 VALUES (2)
# delete
statement error
DELETE FROM t1 WHERE i1=4
----
statement error
DELETE FROM t2 WHERE i2=3
----
statement error
DELETE FROM t3 WHERE i3=2
----
statement ok
DELETE FROM t2 WHERE i2=4
statement ok
DELETE FROM t3 WHERE i3=3
statement ok
DELETE FROM t4 WHERE i4=2
# drop table
statement error
DROP TABLE t1;
----
statement error
DROP TABLE t2;
----
statement error
DROP TABLE t3;
----
statement ok
DROP TABLE t4;
statement ok
DROP TABLE t3;
statement ok
DROP TABLE t2;
statement ok
DROP TABLE t1;

View File

@@ -0,0 +1,45 @@
# name: test/sql/constraints/foreignkey/test_fk_concurrency_conflicts.test
# description: FOREIGN KEY and concurency
# group: [foreignkey]
statement ok con1
CREATE TABLE pk_integers(i INTEGER PRIMARY KEY)
statement ok con1
INSERT INTO pk_integers VALUES (1), (2), (3)
statement ok con1
BEGIN TRANSACTION
statement ok con1
CREATE TABLE fk_integers(j INTEGER, FOREIGN KEY (j) REFERENCES pk_integers(i))
statement ok con1
INSERT INTO fk_integers VALUES (1)
statement error con2
DROP TABLE fk_integers
----
statement ok con1
DROP TABLE fk_integers
statement error con2
CREATE TABLE fk_integers(j INTEGER, FOREIGN KEY (j) REFERENCES pk_integers(i))
----
statement ok con1
ROLLBACK
statement ok con1
CREATE TABLE fk_integers(j INTEGER, FOREIGN KEY (j) REFERENCES pk_integers(i))
statement ok con1
INSERT INTO fk_integers VALUES (1), (2)
statement error con1
INSERT INTO fk_integers VALUES (4), (5)
----
statement ok con2
CREATE TABLE fk_integers_another(j INTEGER, FOREIGN KEY (j) REFERENCES pk_integers(i))

View File

@@ -0,0 +1,42 @@
# name: test/sql/constraints/foreignkey/test_fk_create_type.test
# group: [foreignkey]
# Create a custom type
statement ok
create type custom_type as integer;
statement ok
create table parent (
id custom_type primary key
);
# Use the type alias in both the primary key table and the foreign key table
statement ok
create table child (
parent custom_type references parent
);
statement ok
drop table child;
# Also works with just 'integer'
statement ok
create table child (
parent integer references parent
);
statement ok
drop table child;
statement ok
create type another_custom_type as integer;
# And even with a different type alias that also resolves to 'integer'
statement ok
create table child (
parent another_custom_type references parent
);

View File

@@ -0,0 +1,20 @@
# name: test/sql/constraints/foreignkey/test_fk_cross_schema.test
# description: Test foreign key constraint across different schemas
# group: [foreignkey]
statement ok
CREATE SCHEMA s1
statement ok
CREATE SCHEMA s2
statement ok
CREATE TABLE s1.pk_integers(i INTEGER PRIMARY KEY)
statement ok
INSERT INTO s1.pk_integers VALUES (1), (2), (3)
statement error
CREATE TABLE s2.fk_integers(j INTEGER, FOREIGN KEY (j) REFERENCES s1.pk_intexgers(i))
----
<REGEX>:.*Catalog Error.*does not exist.*

View File

@@ -0,0 +1,52 @@
# name: test/sql/constraints/foreignkey/test_fk_eager_constraint_checking.test
# description: Test over-eager constraint checking for foreign keys.
# group: [foreignkey]
statement ok
SET storage_compatibility_version = 'v0.10.3';
statement ok
ATTACH '__TEST_DIR__/test_fk_eager.db' AS fk_db;
statement ok
USE fk_db;
# We need a PK table with a column not supporting in-place updates.
statement ok
CREATE TABLE tbl_pk (i INT PRIMARY KEY, payload STRUCT(v VARCHAR, i INTEGER[]));
# Let's insert two rows.
statement ok
INSERT INTO tbl_pk VALUES (1, {'v': 'hello', 'i': [42]}), (2, {'v': 'world', 'i': [43]});
# Now, we need a FK table.
statement ok
CREATE TABLE tbl_fk (i INT REFERENCES tbl_pk(i));
# Let's insert rows so that has the FK table has a nested leaf with more than two row IDs.
statement ok
INSERT INTO tbl_fk VALUES (1), (1), (1);
statement ok
ATTACH '__TEST_DIR__/test_other_fk_eager.db' AS other_fk_db;
statement ok
USE other_fk_db;
# We also want the old LEAF representation serialized.
statement ok
CHECKPOINT fk_db;
statement ok
DETACH fk_db;
statement ok
ATTACH '__TEST_DIR__/test_fk_eager.db' AS fk_db;
# Now, we try to update the PK table.
# The over-eager constraint checking fix is not yet supported for FKs, thus, we throw a constraint violation.
statement error
UPDATE fk_db.tbl_pk SET payload = {'v': 'new hello', 'i': [7]} WHERE i = 1;
----
<REGEX>:Constraint Error.*Violates foreign key constraint because.*

View File

@@ -0,0 +1,69 @@
# name: test/sql/constraints/foreignkey/test_fk_export.test
# description: Test export database with foreign key constraint
# group: [foreignkey]
statement ok
CREATE TABLE pk_integers(i INTEGER PRIMARY KEY)
statement ok
CREATE TABLE fk_integers(j INTEGER, FOREIGN KEY (j) REFERENCES pk_integers(i))
statement ok
INSERT INTO pk_integers VALUES (1), (2), (3)
statement ok
INSERT INTO fk_integers VALUES (1), (2)
# now export the db
statement ok
EXPORT DATABASE '__TEST_DIR__/fk_constraint'
statement ok
DROP TABLE fk_integers;
statement ok
DROP TABLE pk_integers;
statement ok
IMPORT DATABASE '__TEST_DIR__/fk_constraint'
# check foreign key constraint
statement error
INSERT INTO fk_integers VALUES (4)
----
statement ok
INSERT INTO fk_integers VALUES (3)
statement error
DELETE FROM pk_integers WHERE i=3
----
statement ok
DELETE FROM fk_integers WHERE j=3
statement ok
DELETE FROM pk_integers WHERE i=3
statement error
UPDATE pk_integers SET i=5 WHERE i=2
----
statement error
UPDATE fk_integers SET i=4 WHERE j=2
----
statement error
UPDATE fk_integers SET i=4 WHERE j=2
----
statement error
DROP TABLE pk_integers;
----
statement ok
DROP TABLE fk_integers;
statement ok
DROP TABLE pk_integers;

View File

@@ -0,0 +1,181 @@
# name: test/sql/constraints/foreignkey/test_fk_multiple.test
# description: Test multiple foreign key constraint
# group: [foreignkey]
# Create a table with a primary key
statement ok
CREATE TABLE pkt1(
i1 INTEGER PRIMARY KEY CHECK(i1 < 3),
j1 INTEGER UNIQUE
);
# Create another table with a primary key
statement ok
CREATE TABLE pkt2(
i2 INTEGER PRIMARY KEY,
j2 INTEGER UNIQUE CHECK (j2 > 1000)
);
# Reference both of the previous tables with foreign keys in this table
statement ok
CREATE TABLE fkt1(
k1 INTEGER,
l1 INTEGER,
FOREIGN KEY(k1) REFERENCES pkt1(i1),
FOREIGN KEY(l1) REFERENCES pkt2(i2)
);
# Reference both of the primary key tables again
statement ok
CREATE TABLE fkt2(
k2 INTEGER,
l2 INTEGER,
FOREIGN KEY(k2) REFERENCES pkt1(j1),
FOREIGN KEY(l2) REFERENCES pkt2(j2)
);
# ensure the constraints are being correctly copied
statement error
INSERT INTO pkt1 VALUES (3, 11);
----
statement error
INSERT INTO pkt2 VALUES (101, 1000);
----
# test multiple foreign key constraints
statement ok
INSERT INTO pkt1 VALUES (1, 11), (2, 12);
statement ok
INSERT INTO pkt2 VALUES (101, 1001), (102, 1002);
statement error
INSERT INTO fkt1 VALUES (3, 101);
----
statement error
INSERT INTO fkt1 VALUES (2, 103);
----
statement ok
INSERT INTO fkt1 VALUES (1, 102), (2, 101);
statement error
INSERT INTO fkt2 VALUES (13, 1002);
----
statement error
INSERT INTO fkt1 VALUES (12, 1003);
----
statement ok
INSERT INTO fkt2 VALUES (12, 1001), (11, 1002);
statement error
DELETE FROM pkt1 WHERE i1=1
----
statement error
DELETE FROM pkt2 WHERE i2=102
----
statement ok
DELETE FROM fkt1 WHERE k1=1
statement error
DELETE FROM pkt1 WHERE i1=1
----
statement ok
DELETE FROM fkt2 WHERE k2=11
statement ok
DELETE FROM pkt1 WHERE i1=1
query II
SELECT * FROM pkt1;
----
2 12
query II
SELECT * FROM pkt2;
----
101 1001
102 1002
query II
SELECT * FROM fkt1;
----
2 101
query II
SELECT * FROM fkt2;
----
12 1001
statement error
UPDATE pkt1 SET i1=3, j1=13 WHERE i1=2;
----
statement error
UPDATE pkt2 SET i2=103, j2=1003 WHERE i2=101;
----
statement ok
UPDATE pkt2 SET i2=103, j2=1003 WHERE i2=102;
statement ok
DELETE FROM fkt1 WHERE k1=2
statement ok
DELETE FROM fkt2 WHERE k2=12
statement ok
UPDATE pkt1 SET i1=1, j1=11 WHERE i1=2;
statement ok
UPDATE pkt2 SET i2=104, j2=1004 WHERE i2=101;
query II
SELECT * FROM pkt1;
----
1 11
query II
SELECT * FROM pkt2;
----
103 1003
104 1004
statement error
DROP TABLE pkt1
----
Could not drop the table because this table is main key table of the table "fkt1"
statement error
DROP TABLE pkt2
----
Could not drop the table because this table is main key table of the table "fkt1"
statement ok
DROP TABLE fkt2
statement error
DROP TABLE pkt1
----
Could not drop the table because this table is main key table of the table "fkt1"
statement error
DROP TABLE pkt2
----
Could not drop the table because this table is main key table of the table "fkt1"
statement ok
DROP TABLE fkt1
statement ok
DROP TABLE pkt1
statement ok
DROP TABLE pkt2

View File

@@ -0,0 +1,14 @@
# name: test/sql/constraints/foreignkey/test_fk_on_view_error.test
# description: Test throwing a binder exception when creating a FK on a VIEW
# group: [foreignkey]
statement ok
CREATE TABLE vdata AS SELECT * FROM (VALUES ('v2',)) v(id);
statement ok
CREATE VIEW v AS SELECT * FROM vdata;
statement error
CREATE TABLE t(v_id TEXT, FOREIGN KEY (v_id) REFERENCES v(id));
----
<REGEX>:Binder Error.*cannot reference a VIEW with a FOREIGN KEY.*

View File

@@ -0,0 +1,64 @@
# name: test/sql/constraints/foreignkey/test_fk_rollback.test
# description: FOREIGN KEY and rollback
# group: [foreignkey]
statement ok
CREATE TABLE pk_integers(i INTEGER PRIMARY KEY)
statement ok
INSERT INTO pk_integers VALUES (1);
statement ok
BEGIN TRANSACTION
statement ok
CREATE TABLE fk_integers(j INTEGER, FOREIGN KEY (j) REFERENCES pk_integers(i))
# can't delete the primary table because of dependency
statement error
DROP TABLE pk_integers
----
<REGEX>:.*Catalog Error.*Could not drop the table.*
statement ok
ROLLBACK
# can delete the primary table because no exist dependency
statement ok
DROP TABLE pk_integers
statement ok
CREATE TABLE pk_integers(i INTEGER PRIMARY KEY)
statement ok
INSERT INTO pk_integers VALUES (1), (2);
statement ok
CREATE TABLE fk_integers(j INTEGER, FOREIGN KEY (j) REFERENCES pk_integers(i))
statement ok
INSERT INTO fk_integers VALUES (2);
statement ok
BEGIN TRANSACTION
statement ok
DROP TABLE fk_integers
statement ok
ROLLBACK
statement error
DELETE FROM pk_integers WHERE i=2;
----
<REGEX>:.*Constraint Error: Violates foreign key constraint.*
statement error
INSERT INTO fk_integers VALUES (3);
----
<REGEX>:.*Constraint Error: Violates foreign key constraint.*
statement error
DROP TABLE pk_integers
----
<REGEX>:.*Catalog Error.*Could not drop the table.*

View File

@@ -0,0 +1,136 @@
# name: test/sql/constraints/foreignkey/test_fk_self_referencing.test
# description: Test self referencing foreign key constraint
# group: [foreignkey]
statement error
CREATE TABLE employee(
id INTEGER PRIMARY KEY,
managerid INTEGER,
name VARCHAR,
FOREIGN KEY(managerid) REFERENCES employee(emp_id));
----
<REGEX>:Binder Error.*does not have a column named.*
statement ok
CREATE TABLE employee(
id INTEGER PRIMARY KEY,
managerid INTEGER,
name VARCHAR,
FOREIGN KEY(managerid) REFERENCES employee(id));
statement ok
INSERT INTO employee VALUES (1, NULL, 'Smith'), (2, NULL, 'Jhon'), (3, NULL, 'Romeo');
statement error
INSERT INTO employee VALUES (4, 4, 'Mark');
----
<REGEX>:Constraint Error.*Violates foreign key constraint.*
statement ok
INSERT INTO employee VALUES (4, 2, 'Mark');
# The value (4, 2, 'Mark') references employee number 2.
# Thus, we cannot update 2 to 5.
statement error
UPDATE employee SET id = 5 WHERE id = 2;
----
<REGEX>:Constraint Error.*Violates foreign key constraint.*
# The value (4, 2, 'Mark') references employee number 2.
# Thus, we cannot delete 2.
statement error
DELETE FROM employee WHERE id = 2;
----
<REGEX>:Constraint Error.*Violates foreign key constraint.*
statement ok
DELETE FROM employee WHERE id = 4;
query IIT
SELECT * FROM employee ORDER BY ALL;
----
1 NULL Smith
2 NULL Jhon
3 NULL Romeo
statement ok
UPDATE employee SET name = 'Juliet' WHERE id = 3;
query IIT
SELECT * FROM employee ORDER BY ALL;
----
1 NULL Smith
2 NULL Jhon
3 NULL Juliet
# Primary key violation.
statement error
UPDATE employee SET id = 2 WHERE id = 3;
----
<REGEX>:Constraint Error.*violates primary key constraint.*
statement ok
UPDATE employee SET id = 4 WHERE id = 3;
query IIT
SELECT * FROM employee ORDER BY ALL;
----
1 NULL Smith
2 NULL Jhon
4 NULL Juliet
# No manager with id 5.
statement error
UPDATE employee SET managerid = 5 WHERE id = 4;
----
<REGEX>:Constraint Error.*Violates foreign key constraint.*
statement ok
UPDATE employee SET managerid = 2 WHERE id = 4;
query IIT
SELECT * FROM employee ORDER BY ALL;
----
1 NULL Smith
2 NULL Jhon
4 2 Juliet
statement ok
UPDATE employee SET id = 5, managerid = 2 WHERE id = 4;
query IIT
SELECT * FROM employee WHERE managerid = 2;
----
5 2 Juliet
statement error
ALTER TABLE employee RENAME COLUMN managerid TO managerid_new;
----
<REGEX>:Catalog Error.*is involved in the foreign key constraint.*
statement ok
ALTER TABLE employee RENAME COLUMN name TO name_new;
statement error
ALTER TABLE employee ALTER COLUMN id SET DATA TYPE TEXT;
----
<REGEX>:Binder Error.*Cannot change the type of a column that has a UNIQUE or PRIMARY KEY constraint specified.*
statement ok
ALTER TABLE employee ALTER COLUMN name_new SET DATA TYPE TEXT;
statement error
ALTER TABLE employee DROP COLUMN id;
----
<REGEX>:Catalog Error.*there is a UNIQUE constraint that depends on it.*
statement error
ALTER TABLE employee DROP COLUMN managerid;
----
<REGEX>:Catalog Error.*there is a FOREIGN KEY constraint that depends on it.*
statement ok
ALTER TABLE employee DROP COLUMN name_new;
statement ok
DROP TABLE employee;

View File

@@ -0,0 +1,273 @@
# name: test/sql/constraints/foreignkey/test_fk_temporary.test
# description: Test foreign key constraint
# group: [foreignkey]
statement ok
CREATE TEMPORARY TABLE album (artistid INTEGER, albumname TEXT, albumcover TEXT, UNIQUE (artistid, albumname));
statement ok
INSERT INTO album VALUES (1, 'A', 'A_cover'), (2, 'B', 'B_cover'), (3, 'C', 'C_cover'), (4, 'D', 'D_cover');
statement ok
CREATE TEMPORARY TABLE song (songid INTEGER, songartist INTEGER, songalbum TEXT, songname TEXT,
FOREIGN KEY (songartist, songalbum) REFERENCES album (artistid, albumname));
# Any row we insert into the foreign key table must exist in primary key table.
statement error
INSERT INTO song VALUES (11, 1, 'A', 'A_song'), (12, 2, 'E', 'B_song'), (13, 3, 'C', 'C_song');
----
<REGEX>:Constraint Error.*Violates foreign key constraint.*
statement error
INSERT INTO song VALUES (11, 1, 'A', 'A_song'), (12, 5, 'D', 'B_song'), (13, 3, 'C', 'C_song');
----
<REGEX>:Constraint Error.*Violates foreign key constraint.*
statement ok
INSERT INTO song VALUES (11, 1, 'A', 'A_song'), (12, 2, 'B', 'B_song'), (13, 3, 'C', 'C_song');
# Any row we delete from the primary key table must not exist in the foreign key table.
statement error
DELETE FROM album WHERE albumname = 'C';
----
<REGEX>:Constraint Error.*Violates foreign key constraint.*
statement ok
DELETE FROM album WHERE albumname = 'D';
query ITT
SELECT * FROM album ORDER BY ALL;
----
1 A A_cover
2 B B_cover
3 C C_cover
# Any row we update in the foreign key table must exist in the primary key table.
statement error
UPDATE song SET songartist = 5, songalbum = 'A' WHERE songname = 'B_song';
----
<REGEX>:Constraint Error.*Violates foreign key constraint.*
statement ok
UPDATE song SET songartist = 1, songalbum = 'A' WHERE songname = 'B_song';
query ITT
SELECT * FROM album ORDER BY ALL;
----
1 A A_cover
2 B B_cover
3 C C_cover
query IITT
SELECT * FROM song ORDER BY ALL;
----
11 1 A A_song
12 1 A B_song
13 3 C C_song
# Any row that is updated from the table with primary key must not exist in the table has foreign key (constraint)
statement error
UPDATE album SET albumname='B' WHERE albumcover='C_cover';
----
statement error
UPDATE song SET songalbum='E' WHERE albumcover='C_song';
----
statement ok
UPDATE album SET artistid=5, albumname='D' WHERE albumcover='B_cover';
query ITT
SELECT * FROM album;
----
1 A A_cover
3 C C_cover
5 D B_cover
# perform an update on a column that is NOT part of the primary key in the main table
statement ok
UPDATE album SET albumcover='C_cover_new' WHERE artistid=3;
# perform an update on a column that is NOT part of the foreign key in the referencing table
statement ok
UPDATE song SET songname='C_song_new' WHERE songartist=3;
query ITT
SELECT * FROM album;
----
1 A A_cover
3 C C_cover_new
5 D B_cover
query IITT
SELECT * FROM song;
----
11 1 A A_song
13 3 C C_song_new
12 1 A B_song
# Cannot rename the columns that are involved in the foreign key constraint
statement error
ALTER TABLE album RENAME COLUMN albumname TO albumname_new;
----
statement error
ALTER TABLE song RENAME COLUMN songalbum TO songalbum_new;
----
statement ok
ALTER TABLE song RENAME COLUMN songname TO songname_new;
# Cannot change type of the columns that are involved in the foreign key constraint
statement error
ALTER TABLE song ALTER COLUMN songartist SET DATA TYPE TEXT;
----
statement error
ALTER TABLE album ALTER COLUMN artistid SET DATA TYPE TEXT;
----
statement ok
ALTER TABLE song ALTER COLUMN songname_new SET DATA TYPE VARCHAR;
# Cannot drop the columns that are involved in the foreign key constraint because of dependency
statement error
ALTER TABLE album DROP COLUMN artistid;
----
statement ok
ALTER TABLE song DROP COLUMN songname_new;
# Can't drop the table with primary key corresponding with foreign key until exists the table has foreign key
statement error
DROP TABLE album;
----
statement ok
DROP TABLE song;
statement ok
ALTER TABLE album RENAME COLUMN albumname TO albumname_new;
statement ok
ALTER TABLE album ALTER COLUMN albumcover SET DATA TYPE VARCHAR;
statement ok
ALTER TABLE album DROP COLUMN albumcover;
statement ok
DROP TABLE album;
# multiple columns and indices
statement ok
CREATE TABLE pkt(i INTEGER UNIQUE, k INTEGER UNIQUE)
statement ok
INSERT INTO pkt VALUES (1, 11), (2, 12), (3, 13)
statement ok
CREATE TABLE fkt(j INTEGER, l INTEGER UNIQUE, FOREIGN KEY (j) REFERENCES pkt(i))
statement ok
CREATE INDEX k_index ON pkt(k)
statement ok
CREATE INDEX l_index ON fkt(l)
statement ok
INSERT INTO fkt VALUES (1, 101), (2, 102)
statement error
INSERT INTO fkt VALUES (4, 104)
----
statement ok
INSERT INTO fkt VALUES (3, 103)
statement error
DELETE FROM pkt WHERE k=13
----
statement ok
DELETE FROM fkt WHERE l=103
statement ok
DELETE FROM pkt WHERE k=13
statement error
UPDATE pkt SET i=5 WHERE k=12
----
statement error
UPDATE fkt SET i=4 WHERE l=102
----
statement error
UPDATE fkt SET i=4 WHERE l=102
----
statement ok
DROP INDEX k_index
statement ok
DROP INDEX l_index
statement error
DROP TABLE pkt;
----
statement ok
DROP TABLE fkt;
statement ok
DROP TABLE pkt;
# for tables that do not live in the current schema search path
statement ok
CREATE SCHEMA s1
statement ok
CREATE TABLE s1.pkt(i INTEGER PRIMARY KEY)
statement ok
CREATE TABLE s1.fkt(j INTEGER, FOREIGN KEY (j) REFERENCES s1.pkt(i))
statement ok
INSERT INTO s1.pkt VALUES (1), (2), (3), (4), (5)
statement ok
INSERT INTO s1.fkt VALUES (2), (3)
statement error
INSERT INTO s1.fkt VALUES (6)
----
statement ok
INSERT INTO s1.fkt VALUES (1)
statement error
DELETE FROM s1.pkt WHERE i=2
----
statement ok
DELETE FROM s1.pkt WHERE i=5
statement error
DROP TABLE s1.pkt;
----
statement ok
DROP TABLE s1.fkt;
statement ok
DROP TABLE s1.pkt;
# insert NULL into the foreign key column
statement ok
CREATE TABLE pkt(i INTEGER UNIQUE)
statement ok
CREATE TABLE fkt(j INTEGER, FOREIGN KEY (j) REFERENCES pkt(i))
statement ok
INSERT INTO fkt VALUES (NULL)

View File

@@ -0,0 +1,137 @@
# name: test/sql/constraints/foreignkey/test_fk_tpch.test_slow
# description: enable foreign keys in the TPC-H schema
# group: [foreignkey]
require tpch
statement ok
CALL dbgen(sf=0.1, suffix='_original');
statement ok
CREATE TABLE region ( R_REGIONKEY INTEGER NOT NULL PRIMARY KEY,
R_NAME CHAR(25) NOT NULL,
R_COMMENT VARCHAR(152));
statement ok
CREATE TABLE part ( P_PARTKEY INTEGER NOT NULL PRIMARY KEY,
P_NAME VARCHAR(55) NOT NULL,
P_MFGR CHAR(25) NOT NULL,
P_BRAND CHAR(10) NOT NULL,
P_TYPE VARCHAR(25) NOT NULL,
P_SIZE INTEGER NOT NULL,
P_CONTAINER CHAR(10) NOT NULL,
P_RETAILPRICE DECIMAL(15,2) NOT NULL,
P_COMMENT VARCHAR(23) NOT NULL );
statement ok
CREATE TABLE nation ( N_NATIONKEY INTEGER NOT NULL PRIMARY KEY,
N_NAME CHAR(25) NOT NULL,
N_REGIONKEY INTEGER NOT NULL,
N_COMMENT VARCHAR(152),
FOREIGN KEY (N_REGIONKEY) REFERENCES region(R_REGIONKEY));
statement ok
CREATE TABLE supplier ( S_SUPPKEY INTEGER NOT NULL PRIMARY KEY,
S_NAME CHAR(25) NOT NULL,
S_ADDRESS VARCHAR(40) NOT NULL,
S_NATIONKEY INTEGER NOT NULL,
S_PHONE CHAR(15) NOT NULL,
S_ACCTBAL DECIMAL(15,2) NOT NULL,
S_COMMENT VARCHAR(101) NOT NULL,
FOREIGN KEY (S_NATIONKEY) REFERENCES nation(N_NATIONKEY));
statement ok
CREATE TABLE partsupp ( PS_PARTKEY INTEGER NOT NULL,
PS_SUPPKEY INTEGER NOT NULL,
PS_AVAILQTY INTEGER NOT NULL,
PS_SUPPLYCOST DECIMAL(15,2) NOT NULL,
PS_COMMENT VARCHAR(199) NOT NULL,
PRIMARY KEY(PS_PARTKEY, PS_SUPPKEY),
FOREIGN KEY (PS_SUPPKEY) REFERENCES supplier(S_SUPPKEY),
FOREIGN KEY (PS_PARTKEY) REFERENCES part(P_PARTKEY));
statement ok
CREATE TABLE customer ( C_CUSTKEY INTEGER NOT NULL PRIMARY KEY,
C_NAME VARCHAR(25) NOT NULL,
C_ADDRESS VARCHAR(40) NOT NULL,
C_NATIONKEY INTEGER NOT NULL,
C_PHONE CHAR(15) NOT NULL,
C_ACCTBAL DECIMAL(15,2) NOT NULL,
C_MKTSEGMENT CHAR(10) NOT NULL,
C_COMMENT VARCHAR(117) NOT NULL,
FOREIGN KEY (C_NATIONKEY) REFERENCES nation(N_NATIONKEY));
statement ok
CREATE TABLE orders ( O_ORDERKEY INTEGER NOT NULL PRIMARY KEY,
O_CUSTKEY INTEGER NOT NULL,
O_ORDERSTATUS CHAR(1) NOT NULL,
O_TOTALPRICE DECIMAL(15,2) NOT NULL,
O_ORDERDATE DATE NOT NULL,
O_ORDERPRIORITY CHAR(15) NOT NULL,
O_CLERK CHAR(15) NOT NULL,
O_SHIPPRIORITY INTEGER NOT NULL,
O_COMMENT VARCHAR(79) NOT NULL,
FOREIGN KEY (O_CUSTKEY) REFERENCES customer(C_CUSTKEY));
statement ok
CREATE TABLE lineitem ( L_ORDERKEY INTEGER NOT NULL,
L_PARTKEY INTEGER NOT NULL,
L_SUPPKEY INTEGER NOT NULL,
L_LINENUMBER INTEGER NOT NULL,
L_QUANTITY DECIMAL(15,2) NOT NULL,
L_EXTENDEDPRICE DECIMAL(15,2) NOT NULL,
L_DISCOUNT DECIMAL(15,2) NOT NULL,
L_TAX DECIMAL(15,2) NOT NULL,
L_RETURNFLAG CHAR(1) NOT NULL,
L_LINESTATUS CHAR(1) NOT NULL,
L_SHIPDATE DATE NOT NULL,
L_COMMITDATE DATE NOT NULL,
L_RECEIPTDATE DATE NOT NULL,
L_SHIPINSTRUCT CHAR(25) NOT NULL,
L_SHIPMODE CHAR(10) NOT NULL,
L_COMMENT VARCHAR(44) NOT NULL,
PRIMARY KEY(L_ORDERKEY, L_LINENUMBER),
FOREIGN KEY (L_ORDERKEY) REFERENCES orders(O_ORDERKEY),
FOREIGN KEY (L_PARTKEY, L_SUPPKEY) REFERENCES partsupp(PS_PARTKEY, PS_SUPPKEY));
statement ok
INSERT INTO region SELECT * FROM region_original
statement ok
INSERT INTO part SELECT * FROM part_original
statement ok
INSERT INTO nation SELECT * FROM nation_original
statement ok
INSERT INTO supplier SELECT * FROM supplier_original
statement ok
INSERT INTO partsupp SELECT * FROM partsupp_original
statement ok
INSERT INTO customer SELECT * FROM customer_original
statement ok
INSERT INTO orders SELECT * FROM orders_original
statement ok
INSERT INTO lineitem SELECT * FROM lineitem_original
loop i 1 9
query I
PRAGMA tpch(${i})
----
<FILE>:extension/tpch/dbgen/answers/sf0.1/q0${i}.csv
endloop
loop i 10 23
query I
PRAGMA tpch(${i})
----
<FILE>:extension/tpch/dbgen/answers/sf0.1/q${i}.csv
endloop

View File

@@ -0,0 +1,149 @@
# name: test/sql/constraints/foreignkey/test_fk_transaction.test
# description: Test foreign key in same transaction
# group: [foreignkey]
# Insert a tuple in the main table and the referencing table.
statement ok
CREATE TABLE pkt(i INTEGER PRIMARY KEY)
statement ok
CREATE TABLE fkt(j INTEGER, FOREIGN KEY (j) REFERENCES pkt(i))
statement ok
BEGIN TRANSACTION
statement ok
INSERT INTO pkt VALUES (1)
statement ok
INSERT INTO fkt VALUES (1)
statement ok
ROLLBACK
statement ok
INSERT INTO pkt VALUES (1)
statement ok
BEGIN TRANSACTION
statement ok
INSERT INTO pkt VALUES (2)
statement error
INSERT INTO fkt VALUES (3)
----
<REGEX>:Constraint Error.*Violates foreign key constraint.*
statement ok
ROLLBACK
statement ok
BEGIN TRANSACTION
statement ok
INSERT INTO fkt VALUES (1)
statement error
DELETE FROM pkt WHERE i = 1
----
<REGEX>:Constraint Error.*Violates foreign key constraint.*
statement ok
ROLLBACK
# Delete a tuple in the referencing table and then delete that tuple in the main table.
statement ok
BEGIN TRANSACTION
statement ok
DELETE FROM pkt WHERE i = 1
statement ok
INSERT INTO fkt VALUES (1)
statement ok
ROLLBACK
statement ok
BEGIN TRANSACTION
statement ok
INSERT INTO pkt VALUES (2)
statement ok
INSERT INTO fkt VALUES (1), (2)
statement ok
DELETE FROM fkt WHERE j = 1
statement ok
DELETE FROM pkt WHERE i = 1
statement ok
COMMIT
statement error
DELETE FROM pkt WHERE i = 2
----
<REGEX>:Constraint Error.*Violates foreign key constraint.*
statement ok
DELETE FROM fkt WHERE j = 2
statement ok
DELETE FROM pkt WHERE i = 2
# Insert a tuple in the primary key table, delete it,
# and in the same transaction try to insert that tuple in the foreign key table.
statement ok
INSERT INTO pkt VALUES (3)
statement ok
BEGIN TRANSACTION
statement ok
DELETE FROM pkt WHERE i = 3
statement ok
INSERT INTO fkt VALUES (3)
statement ok
ROLLBACK
statement error
DROP TABLE pkt;
----
<REGEX>:Catalog Error.*table is main key table of the table.*
statement ok
DROP TABLE fkt;
statement ok
DROP TABLE pkt;
# Test with MAX_ROW_ID when deleting a tuple.
statement ok
BEGIN TRANSACTION
statement ok
CREATE TABLE a(i INTEGER PRIMARY KEY)
statement ok
CREATE TABLE b(j INTEGER, FOREIGN KEY (j) REFERENCES a(i))
statement ok
INSERT INTO a VALUES (1), (2)
statement ok
INSERT INTO b VALUES (1), (2)
statement ok
DELETE FROM b
statement ok
DELETE FROM a

View File

@@ -0,0 +1,41 @@
# name: test/sql/constraints/foreignkey/test_fk_with_attached_db.test
# description: Test foreign key constraint with attaching and using a different DB
# group: [foreignkey]
statement ok
SET checkpoint_threshold = '10.0 GB';
statement ok
PRAGMA disable_checkpoint_on_shutdown;
statement ok
ATTACH '__TEST_DIR__/attach_fk_db.db' AS db1;
statement ok
USE db1;
statement ok
CREATE TABLE IF NOT EXISTS t1 (
cache_key VARCHAR PRIMARY KEY,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
);
statement ok
CREATE TABLE IF NOT EXISTS t2 (
cache_key VARCHAR NOT NULL,
dose DOUBLE NOT NULL,
PRIMARY KEY (cache_key, dose),
FOREIGN KEY (cache_key) REFERENCES t1 (cache_key)
);
statement ok
ATTACH ':memory:' AS other;
statement ok
USE other;
statement ok
DETACH db1;
statement ok
ATTACH '__TEST_DIR__/attach_fk_db.db' AS db2;

View File

@@ -0,0 +1,308 @@
# name: test/sql/constraints/foreignkey/test_foreignkey.test
# description: Test foreign key constraint
# group: [foreignkey]
statement ok
CREATE TABLE album(artistid INTEGER, albumname TEXT, albumcover TEXT, UNIQUE (artistid, albumname));
statement ok
INSERT INTO album VALUES (1, 'A', 'A_cover'), (2, 'B', 'B_cover'), (3, 'C', 'C_cover'), (4, 'D', 'D_cover');
# The count of columns are primary keys must be equal with the count of columns are foreign keys
statement error
CREATE TABLE song(songid INTEGER, songartist INTEGER, songalbum TEXT, songname TEXT, FOREIGN KEY(songartist, songalbum) REFERENCES album(artistid));
----
statement error
CREATE TABLE song(songid INTEGER, songartist INTEGER, songalbum TEXT, songname TEXT, FOREIGN KEY(songalbum) REFERENCES album(artistid, albumname));
----
statement error
CREATE TABLE song(songid INTEGER, songartist INTEGER, songalbum TEXT, songname TEXT, FOREIGN KEY(songartist, songalbum) REFERENCES albumlist(artistid, albumname));
----
statement error
CREATE TABLE song(songid INTEGER, songartist INTEGER, songalbum TEXT, songname TEXT, FOREIGN KEY(songartist, songalbum) REFERENCES album(artistid, album_name));
----
statement error
CREATE TABLE song(songid INTEGER, songartist INTEGER, songalbum TEXT, songname TEXT, FOREIGN KEY(songartist, song_album) REFERENCES album(artistid, albumname));
----
statement ok
CREATE TABLE song(songid INTEGER, songartist INTEGER, songalbum TEXT, songname TEXT, FOREIGN KEY(songartist, songalbum) REFERENCES album(artistid, albumname));
# Any row that is inserted into the table with the foreign key must exist in the table with the primary key (constraint)
statement error
INSERT INTO song VALUES (11, 1, 'A', 'A_song'), (12, 2, 'E', 'B_song'), (13, 3, 'C', 'C_song');
----
statement error
INSERT INTO song VALUES (11, 1, 'A', 'A_song'), (12, 5, 'D', 'B_song'), (13, 3, 'C', 'C_song');
----
statement ok
INSERT INTO song VALUES (11, 1, 'A', 'A_song'), (12, 2, 'B', 'B_song'), (13, 3, 'C', 'C_song');
# Any row that is deleted from the table with the primary key must not exist in the table with the foreign key (constraint)
statement error
DELETE FROM album WHERE albumname='C';
----
statement ok
DELETE FROM album WHERE albumname='D';
query ITT
SELECT * FROM album;
----
1 A A_cover
2 B B_cover
3 C C_cover
# Any row that is updated from the table has foreign key must exist in the table with the primary key (constraint)
statement error
UPDATE song SET songartist=5, songalbum='A' WHERE songname='B_song';
----
statement ok
UPDATE song SET songartist=1, songalbum='A' WHERE songname='B_song';
query ITT
SELECT * FROM album;
----
1 A A_cover
2 B B_cover
3 C C_cover
query IITT
SELECT * FROM song;
----
11 1 A A_song
13 3 C C_song
12 1 A B_song
# Any row that is updated from the table with primary key must not exist in the table has foreign key (constraint)
statement error
UPDATE album SET albumname='B' WHERE albumcover='C_cover';
----
statement error
UPDATE song SET songalbum='E' WHERE albumcover='C_song';
----
statement ok
UPDATE album SET artistid=5, albumname='D' WHERE albumcover='B_cover';
query ITT
SELECT * FROM album;
----
1 A A_cover
3 C C_cover
5 D B_cover
# perform an update on a column that is NOT part of the primary key in the main table
statement ok
UPDATE album SET albumcover='C_cover_new' WHERE artistid=3;
# perform an update on a column that is NOT part of the foreign key in the referencing table
statement ok
UPDATE song SET songname='C_song_new' WHERE songartist=3;
query ITT
SELECT * FROM album;
----
1 A A_cover
3 C C_cover_new
5 D B_cover
query IITT
SELECT * FROM song;
----
11 1 A A_song
13 3 C C_song_new
12 1 A B_song
# Cannot rename the columns that are involved in the foreign key constraint
statement error
ALTER TABLE album RENAME COLUMN albumname TO albumname_new;
----
statement error
ALTER TABLE song RENAME COLUMN songalbum TO songalbum_new;
----
statement ok
ALTER TABLE song RENAME COLUMN songname TO songname_new;
# Cannot change type of the columns that are involved in the foreign key constraint
statement error
ALTER TABLE song ALTER COLUMN songartist SET DATA TYPE TEXT;
----
statement error
ALTER TABLE album ALTER COLUMN artistid SET DATA TYPE TEXT;
----
statement ok
ALTER TABLE song ALTER COLUMN songname_new SET DATA TYPE VARCHAR;
# Cannot drop the columns that are involved in the foreign key constraint because of dependency
statement error
ALTER TABLE album DROP COLUMN artistid;
----
statement ok
ALTER TABLE song DROP COLUMN songname_new;
# Can't drop the table with primary key corresponding with foreign key until exists the table has foreign key
statement error
DROP TABLE album;
----
statement ok
DROP TABLE song;
statement ok
ALTER TABLE album RENAME COLUMN albumname TO albumname_new;
statement ok
ALTER TABLE album ALTER COLUMN albumcover SET DATA TYPE VARCHAR;
statement ok
ALTER TABLE album DROP COLUMN albumcover;
statement ok
DROP TABLE album;
# multiple columns and indices
statement ok
CREATE TABLE pkt(i INTEGER UNIQUE, k INTEGER UNIQUE)
statement ok
INSERT INTO pkt VALUES (1, 11), (2, 12), (3, 13)
statement ok
CREATE TABLE fkt(
j INTEGER,
l INTEGER UNIQUE,
FOREIGN KEY (j) REFERENCES pkt(i)
)
statement ok
CREATE INDEX k_index ON pkt(k)
statement ok
CREATE INDEX l_index ON fkt(l)
statement ok
INSERT INTO fkt VALUES (1, 101), (2, 102)
statement error
INSERT INTO fkt VALUES (4, 104)
----
statement ok
INSERT INTO fkt VALUES (3, 103)
statement error
DELETE FROM pkt WHERE k=13
----
statement ok
DELETE FROM fkt WHERE l=103
statement ok
DELETE FROM pkt WHERE k=13
statement error
UPDATE pkt SET i=5 WHERE k=12
----
statement error
UPDATE fkt SET i=4 WHERE l=102
----
statement error
UPDATE fkt SET i=4 WHERE l=102
----
statement ok
DROP INDEX k_index
statement ok
DROP INDEX l_index
statement error
DROP TABLE pkt;
----
statement ok
DROP TABLE fkt;
statement ok
DROP TABLE pkt;
# for tables that do not live in the current schema search path
statement ok
CREATE SCHEMA s1
statement ok
CREATE TABLE s1.pkt(i INTEGER PRIMARY KEY)
statement ok
CREATE TABLE s1.fkt(j INTEGER, FOREIGN KEY (j) REFERENCES s1.pkt(i))
statement ok
INSERT INTO s1.pkt VALUES (1), (2), (3), (4), (5)
statement ok
INSERT INTO s1.fkt VALUES (2), (3)
statement error
INSERT INTO s1.fkt VALUES (6)
----
statement ok
INSERT INTO s1.fkt VALUES (1)
statement error
DELETE FROM s1.pkt WHERE i=2
----
statement ok
DELETE FROM s1.pkt WHERE i=5
statement error
DROP TABLE s1.pkt;
----
statement ok
DROP TABLE s1.fkt;
statement ok
DROP TABLE s1.pkt;
# insert NULL into the foreign key column
statement ok
CREATE TABLE pkt(i INTEGER UNIQUE)
statement ok
CREATE TABLE fkt(j INTEGER, FOREIGN KEY (j) REFERENCES pkt(i))
statement ok
INSERT INTO fkt VALUES (NULL)
# Truncate on self-reference is not yet supported.
statement ok
CREATE TABLE t (id INT PRIMARY KEY, parent INT REFERENCES t (id));
statement ok
INSERT INTO t VALUES (1, NULL);
statement ok
INSERT INTO t VALUES (2, 1), (3, 1);
statement error
TRUNCATE t;
----
Violates foreign key constraint

View File

@@ -0,0 +1,54 @@
# name: test/sql/constraints/primarykey/test_pk_append_many_duplicates.test_slow
# description: Test appending the same value many times to a primary key column
# group: [primarykey]
statement ok
CREATE TABLE integers(i INTEGER PRIMARY KEY);
# insert a bunch of values into the index and query the index
loop val 0 100
query I
SELECT COUNT(*) FROM integers WHERE i = ${val}
----
0
#then we insert $val
statement ok
INSERT INTO integers VALUES (${val});
query I
SELECT COUNT(*) FROM integers WHERE i = ${val}
----
1
endloop
loop val 0 100
# hack: use a complex expression to prevent index lookup
query I
SELECT COUNT(*) FROM integers WHERE i+i = ${val}*2
----
1
query I
SELECT COUNT(*) FROM integers WHERE i = ${val}
----
1
endloop
# now insert the same values: this should fail this time
loop it 0 10
statement error
INSERT INTO integers VALUES ($val)
----
endloop
# now test that the counts are correct
statement ok
SELECT COUNT(*), COUNT(DISTINCT i) FROM integers

View File

@@ -0,0 +1,25 @@
# name: test/sql/constraints/primarykey/test_pk_bool.test
# description: Multi-column boolean PRIMARY KEY constraint
# group: [primarykey]
statement ok
CREATE TABLE integers(i INTEGER, j BOOLEAN, PRIMARY KEY(i, j))
statement ok
INSERT INTO integers VALUES (1, false), (1, true), (2, false)
# duplicate value!
statement error
INSERT INTO integers VALUES (1, false)
----
statement ok
INSERT INTO integers VALUES (2, true)
query IT
SELECT * FROM integers ORDER BY 1, 2
----
1 0
1 1
2 0
2 1

View File

@@ -0,0 +1,38 @@
# name: test/sql/constraints/primarykey/test_pk_col_subset.test
# description: PRIMARY KEY constraint that only covers a subset of the columns
# group: [primarykey]
statement ok
CREATE TABLE numbers(a integer, b integer, c integer, d integer, e integer, PRIMARY KEY(a,b))
# insert two conflicting pairs at the same time
statement error
INSERT INTO numbers VALUES (1,1,1,1,1), (1,1,1,1,1)
----
# insert unique values
statement ok
INSERT INTO numbers VALUES (1,1,1,1,1),(1,2,1,1,1),(2,1,2,1,1),(2,2,2,2,2)
# insert a duplicate value as part of a chain of values
statement error
INSERT INTO numbers VALUES (1,1,1,1,1),(1,5,1,1,4);
----
# now insert just the second value
statement ok
INSERT INTO numbers VALUES (1,5,1,1,4);
# this should work since is not part of primary key
statement ok
UPDATE numbers SET c=1 WHERE c=2
# this should fail since is will cause a duplicate
statement error
UPDATE numbers SET b=1 WHERE b=2
----
# this should work since it won't cause a duplicate
statement ok
UPDATE numbers SET b=3 WHERE b=2

View File

@@ -0,0 +1,83 @@
# name: test/sql/constraints/primarykey/test_pk_concurrency_conflicts.test
# description: PRIMARY KEY and concurency conflicts
# group: [primarykey]
statement ok con1
CREATE TABLE integers(i INTEGER PRIMARY KEY)
statement ok con1
INSERT INTO integers VALUES (1), (2), (3)
# con1 starts a transaction and modifies the second value
statement ok con1
BEGIN TRANSACTION
statement ok con1
UPDATE integers SET i=4 WHERE i=2
# con2 can't update the second value
statement error con2
UPDATE integers SET i=4 WHERE i=2
----
statement error con2
UPDATE integers SET i=5 WHERE i=2
----
# nor can it delete it
statement error con2
DELETE FROM integers WHERE i=2
----
# we tried to set i=5 in con2 but it failed, we can set it in con1 now though
statement ok con1
UPDATE integers SET i=5 WHERE i=3
# rollback con1
statement ok con1
ROLLBACK
# now we can perform the changes in con2
statement ok con2
BEGIN TRANSACTION
statement ok con2
UPDATE integers SET i=4 WHERE i=2
statement ok con2
UPDATE integers SET i=5 WHERE i=3
# check the results, con1 still gets the old results
query I con1
SELECT * FROM integers ORDER BY i
----
1
2
3
query I con2
SELECT * FROM integers ORDER BY i
----
1
4
5
# now commit
statement ok con2
COMMIT
# check the results again, both get the same (new) results now
query I con1
SELECT * FROM integers ORDER BY i
----
1
4
5
query I con2
SELECT * FROM integers ORDER BY i
----
1
4
5

View File

@@ -0,0 +1,32 @@
# name: test/sql/constraints/primarykey/test_pk_many_columns.test
# description: PRIMARY KEY constraint on more than two columns
# group: [primarykey]
statement ok
CREATE TABLE numbers(a integer, b integer, c integer, d integer, e integer, PRIMARY KEY(a,b,c,d,e))
# insert two conflicting pairs at the same time
statement error
INSERT INTO numbers VALUES (1,1,1,1,1), (1,1,1,1,1)
----
<REGEX>:.*Constraint Error.*constraint violation.*
# insert unique values
statement ok
INSERT INTO numbers VALUES (1,1,1,1,1),(1,2,1,1,1),(1,1,2,1,1),(2,2,2,2,2)
# insert a duplicate value as part of a chain of values
statement error
INSERT INTO numbers VALUES (1,1,1,1,1),(1,1,1,1,4);
----
<REGEX>:.*Constraint Error: Duplicate key.*
# now insert just the second value
statement ok
INSERT INTO numbers VALUES (1,1,1,1,4);
# this should fail since will cause a duplicate
statement error
UPDATE numbers SET c=1 WHERE c=2
----
<REGEX>:.*Constraint Error: Duplicate key.*

View File

@@ -0,0 +1,30 @@
# name: test/sql/constraints/primarykey/test_pk_multi_column.test
# description: Multi-column PRIMARY KEY constraint
# group: [primarykey]
statement ok
CREATE TABLE integers(i INTEGER, j VARCHAR, PRIMARY KEY(i, j))
statement ok
INSERT INTO integers VALUES (3, 'hello'), (3, 'world')
query IT
SELECT * FROM integers
----
3 hello
3 world
statement error
INSERT INTO integers VALUES (6, 'bla'), (3, 'hello');
----
statement ok
INSERT INTO integers VALUES (6, 'bla');
query IT
SELECT * FROM integers
----
3 hello
3 world
6 bla

View File

@@ -0,0 +1,34 @@
# name: test/sql/constraints/primarykey/test_pk_multi_string.test
# description: PRIMARY KEY constraint on multiple string columns with overlapping values
# group: [primarykey]
statement ok
CREATE TABLE tst(a varchar, b varchar,PRIMARY KEY(a,b))
# insert two conflicting pairs at the same time
statement error
INSERT INTO tst VALUES ('hell', 'hello'), ('hell','hello')
----
# insert unique values
statement ok
INSERT INTO tst VALUES ('hell', 'hello'), ('hello','hell'), ('hel','hell'), ('hell','hel')
# insert a duplicate value as part of a chain of values
statement error
INSERT INTO tst VALUES ('hell', 'hello'),('hel', 'hello');
----
# now insert just the second value
statement ok
INSERT INTO tst VALUES ('hel', 'hello');
# this should fail since it will cause a duplicate
statement error
UPDATE tst SET b='hello' WHERE b='hel'
----
# this should work since it won't cause a duplicate
statement ok
UPDATE tst SET b='hell' WHERE b='hel'

View File

@@ -0,0 +1,46 @@
# name: test/sql/constraints/primarykey/test_pk_prefix.test_slow
# description: PRIMARY KEY prefix tests with compound indexes.
# group: [primarykey]
statement ok
CREATE TABLE test (a INTEGER, b VARCHAR, PRIMARY KEY(a, b));
loop i 1 300
statement ok
INSERT INTO test VALUES (${i}, 'hello');
endloop
# Try to insert again - this must throw a constraint violation.
loop i 1 300
statement error
INSERT INTO test VALUES (${i}, 'hello');
----
<REGEX>:Constraint Error.*violates primary key constraint.*
endloop
statement ok
UPDATE test SET a = a + 1000;
# Insert the original values again.
loop i 1 300
statement ok
INSERT INTO test VALUES (${i}, 'hello');
endloop
# Increment one more time.
statement ok
UPDATE test SET a = a + 1000;
query II
SELECT MIN(a), MAX(a) FROM test;
----
1001 2299

View File

@@ -0,0 +1,24 @@
# name: test/sql/constraints/primarykey/test_pk_rollback.test
# description: PRIMARY KEY and transactions
# group: [primarykey]
statement ok
CREATE TABLE integers(i INTEGER PRIMARY KEY)
statement ok
BEGIN TRANSACTION
statement ok
INSERT INTO integers VALUES (1);
statement ok
ROLLBACK
statement ok
INSERT INTO integers VALUES (1);
query I
SELECT * FROM integers
----
1

View File

@@ -0,0 +1,51 @@
# name: test/sql/constraints/primarykey/test_pk_string.test
# description: ART FP String Constraint
# group: [primarykey]
statement ok
CREATE TABLE numbers(i varchar PRIMARY KEY, j INTEGER)
# insert two conflicting pairs at the same time
statement error
INSERT INTO numbers VALUES ('1', 4), ('1', 5)
----
<REGEX>:.*Constraint Error.*constraint violation.*
# insert unique values
statement ok
INSERT INTO numbers VALUES ('1', 4), ('2', 5)
query TI
SELECT * FROM numbers
----
1 4
2 5
# insert a duplicate value as part of a chain of values
statement error
INSERT INTO numbers VALUES ('6', 6), ('1', 4);
----
<REGEX>:.*Constraint Error: Duplicate key.*
# now insert just the first value
statement ok
INSERT INTO numbers VALUES ('6', 6);
query TI
SELECT * FROM numbers
----
1 4
2 5
6 6
# insert NULL value in PRIMARY KEY is not allowed
statement error
INSERT INTO numbers VALUES (NULL, 4);
----
<REGEX>:.*Constraint Error.*constraint failed.*
# update NULL is also not allowed
statement error
UPDATE numbers SET i=NULL;
----
<REGEX>:.*Constraint Error.*constraint failed.*

View File

@@ -0,0 +1,76 @@
# name: test/sql/constraints/primarykey/test_pk_update_delete.test
# description: PRIMARY KEY and update/delete
# group: [primarykey]
statement ok
CREATE TABLE test (a INTEGER PRIMARY KEY, b INTEGER);
statement ok
INSERT INTO test VALUES (11, 1), (12, 2), (13, 3)
statement ok
UPDATE test SET b=2 WHERE b=3;
statement error
UPDATE test SET a=a+1 WHERE b=1;
----
statement error
UPDATE test SET a=4;
----
query II
SELECT * FROM test;
----
11 1
12 2
13 2
statement ok
DELETE FROM test WHERE a=11
query II
SELECT * FROM test ORDER BY a;
----
12 2
13 2
statement ok
INSERT INTO test VALUES (11, 1);
query II
SELECT * FROM test ORDER BY a;
----
11 1
12 2
13 2
statement error
INSERT INTO test VALUES (11, 1);
----
query II
SELECT * FROM test ORDER BY a;
----
11 1
12 2
13 2
statement ok
UPDATE test SET a=4 WHERE b=1;
query II
SELECT * FROM test ORDER BY a;
----
4 1
12 2
13 2
statement error
UPDATE test SET a=NULL WHERE b=1;
----
statement error
UPDATE test SET a=NULL;
----

View File

@@ -0,0 +1,52 @@
# name: test/sql/constraints/primarykey/test_pk_updel_local.test
# description: PRIMARY KEY and update/delete in the same transaction
# group: [primarykey]
statement ok
CREATE TABLE integers(i INTEGER PRIMARY KEY)
statement ok
BEGIN TRANSACTION
statement ok
INSERT INTO integers VALUES (1);
statement ok
UPDATE integers SET i=33;
statement ok
ROLLBACK
statement ok
INSERT INTO integers VALUES (1);
statement ok
INSERT INTO integers VALUES (33);
query I
SELECT * FROM integers ORDER BY i
----
1
33
statement ok
DROP TABLE integers
statement ok
CREATE TABLE integers(i INTEGER PRIMARY KEY)
statement ok
INSERT INTO integers VALUES (1);
statement ok
UPDATE integers SET i=33;
statement ok
INSERT INTO integers VALUES (1);
query I
SELECT * FROM integers ORDER BY i
----
1
33

View File

@@ -0,0 +1,110 @@
# name: test/sql/constraints/primarykey/test_pk_updel_multi_column.test
# description: PRIMARY KEY and update/delete on multiple columns
# group: [primarykey]
statement ok
CREATE TABLE test (a INTEGER, b VARCHAR, PRIMARY KEY(a, b));
statement ok
INSERT INTO test VALUES (11, 'hello'), (12, 'world'), (13, 'blablabla');
statement ok
UPDATE test SET b = 'pandas';
query IT
SELECT * FROM test ORDER BY ALL;
----
11 pandas
12 pandas
13 pandas
statement ok
UPDATE test SET a = a + 3;
query IT
SELECT * FROM test ORDER BY ALL;
----
14 pandas
15 pandas
16 pandas
statement error
UPDATE test SET a = 15 WHERE a = 14;
----
<REGEX>:Constraint Error.*violates primary key constraint.*
statement error
UPDATE test SET a = 4;
----
<REGEX>:Constraint Error.*PRIMARY KEY or UNIQUE constraint violation.*
query IT
SELECT * FROM test ORDER BY a;
----
14 pandas
15 pandas
16 pandas
statement ok
UPDATE test SET a = a - 3;
query IT
SELECT * FROM test ORDER BY ALL;
----
11 pandas
12 pandas
13 pandas
statement ok
DELETE FROM test WHERE a = 12;
query IT
SELECT * FROM test ORDER BY a;
----
11 pandas
13 pandas
statement ok
INSERT INTO test VALUES (12, 'pandas');
query IT
SELECT * FROM test ORDER BY a;
----
11 pandas
12 pandas
13 pandas
statement error
INSERT INTO test VALUES (12, 'pandas');
----
<REGEX>:Constraint Error.*violates primary key constraint.*
statement ok
DELETE FROM test WHERE a = 12;
query IT
SELECT * FROM test ORDER BY a;
----
11 pandas
13 pandas
statement ok
INSERT INTO test VALUES (12, 'other pandas');
statement ok
UPDATE test SET a = 4 WHERE a = 42;
statement ok
UPDATE test SET a = 4 WHERE a = 12;
query IT
SELECT * FROM test ORDER BY a;
----
4 other pandas
11 pandas
13 pandas
statement error
UPDATE test SET b = NULL WHERE a = 13;
----
<REGEX>:Constraint Error.*NOT NULL constraint failed.*

View File

@@ -0,0 +1,78 @@
# name: test/sql/constraints/primarykey/test_primary_key.test
# description: Single PRIMARY KEY constraint
# group: [primarykey]
statement ok
CREATE TABLE integers(i INTEGER PRIMARY KEY, j INTEGER)
# insert two conflicting pairs at the same time
statement error
INSERT INTO integers VALUES (3, 4), (3, 5)
----
<REGEX>:.*Constraint Error.*constraint violation.*
# insert unique values
statement ok
INSERT INTO integers VALUES (3, 4), (2, 5)
query II
SELECT * FROM integers
----
3 4
2 5
# insert a duplicate value as part of a chain of values
statement error
INSERT INTO integers VALUES (6, 6), (3, 4);
----
<REGEX>:.*Constraint Error.*violates primary key constraint.*
# now insert just the first value
statement ok
INSERT INTO integers VALUES (6, 6);
query II
SELECT * FROM integers
----
3 4
2 5
6 6
# insert NULL value in PRIMARY KEY is not allowed
statement error
INSERT INTO integers VALUES (NULL, 4);
----
<REGEX>:.*Constraint Error.*constraint failed.*
# update NULL is also not allowed
statement error
UPDATE integers SET i=NULL;
----
<REGEX>:.*Constraint Error.*constraint failed.*
# insert the same value from multiple connections
# NOTE: this tests current behavior
# this can potentially change in the future
statement ok
BEGIN TRANSACTION
statement ok con2
BEGIN TRANSACTION
# insert from first connection succeeds
statement ok
INSERT INTO integers VALUES (7, 8);
# insert from second connection also succeeds
statement ok con2
INSERT INTO integers VALUES (7, 33);
# now committing the first transaction works
statement ok
COMMIT
# but the second transaction results in a conflict
statement error con2
COMMIT
----
<REGEX>:.*TransactionContext Error.*constraint violation.*

View File

@@ -0,0 +1,74 @@
# name: test/sql/constraints/test_constraint_with_updates.test
# description: Test constraints with updates
# group: [constraints]
statement ok
CREATE TABLE integers(i INTEGER, j INTEGER CHECK(i + j < 5), k INTEGER)
statement ok
INSERT INTO integers VALUES (1, 2, 4)
# updating values that are not referenced in the CHECK should just work
statement ok
UPDATE integers SET k=7
# update to a passing value should work
statement ok
UPDATE integers SET i=i, j=3
statement ok
UPDATE integers SET i=i, j=3
# update to a passing value should work
statement error
UPDATE integers SET i=i, i=10
----
statement error
UPDATE integers SET i=i, j=10
----
# now update the value without explicitly mentioning the other column
statement ok
UPDATE integers SET j=2
statement error
UPDATE integers SET j=10
----
# verify that the final result is correct
query III
SELECT * FROM integers
----
1 2 7
statement ok
DROP TABLE integers
# NOT NULL constraint
statement ok
CREATE TABLE integers(i INTEGER NOT NULL, j INTEGER NOT NULL)
# insert a value that passes
statement ok
INSERT INTO integers VALUES (1, 2)
# update to a passing value should work
statement ok
UPDATE integers SET j=3
# now update the value so it doesn't pass
statement error
UPDATE integers SET i=NULL
----
statement error
UPDATE integers SET j=NULL
----
# verify that the final result is correct
query II
SELECT * FROM integers
----
1 3

View File

@@ -0,0 +1,53 @@
# name: test/sql/constraints/test_not_null.test
# description: NOT NULL constraint
# group: [constraints]
statement ok
CREATE TABLE integers(i INTEGER NOT NULL)
statement ok
INSERT INTO integers VALUES (3)
statement error
INSERT INTO integers VALUES (NULL)
----
statement ok
UPDATE integers SET i=4
statement error
UPDATE integers SET i=NULL
----
statement ok
CREATE TABLE integers_with_null(i INTEGER)
statement ok
INSERT INTO integers_with_null VALUES (3), (4), (5), (NULL);
statement error
INSERT INTO integers (i) SELECT * FROM integers_with_null
----
statement ok
INSERT INTO integers (i) SELECT * FROM integers_with_null WHERE i IS NOT NULL
query I
SELECT * FROM integers ORDER BY i
----
3
4
4
5
statement ok
UPDATE integers SET i=4 WHERE i>4
query I
SELECT * FROM integers ORDER BY i
----
3
4
4
4

View File

@@ -0,0 +1,90 @@
# name: test/sql/constraints/unique/test_unique.test
# description: Single UNIQUE constraint
# group: [unique]
statement ok
SET default_null_order='nulls_first';
statement ok
CREATE TABLE integers(i INTEGER UNIQUE, j INTEGER)
# insert unique values
statement ok
INSERT INTO integers VALUES (3, 4), (2, 5)
query II
SELECT * FROM integers
----
3 4
2 5
# insert a duplicate value as part of a chain of values, this should fail
statement error
INSERT INTO integers VALUES (6, 6), (3, 4);
----
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
# but if we try to replace them like this it's going to fail
statement error
UPDATE integers SET i=77 WHERE i IS NULL
----
query II
SELECT * FROM integers ORDER BY i, j
----
NULL 6
NULL 7
2 5
3 4
# we can replace them like this though
statement ok
UPDATE integers SET i=77 WHERE i IS NULL AND j=6
query II
SELECT * FROM integers ORDER BY i, j
----
NULL 7
2 5
3 4
77 6
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement error
INSERT INTO integers VALUES (NULL, 6), (3, 7)
----
statement ok
DROP TABLE integers

View File

@@ -0,0 +1,17 @@
# name: test/sql/constraints/unique/test_unique_error.test
# description: UNIQUE constraint on temporary tables with duplicate data
# group: [unique]
statement ok
CREATE TEMPORARY TABLE integers(i INTEGER, j VARCHAR)
statement ok
INSERT INTO integers VALUES (3, '4'), (2, '4')
statement error
CREATE UNIQUE INDEX uidx ON integers (j)
----
statement ok
DROP TABLE integers

View File

@@ -0,0 +1,92 @@
# name: test/sql/constraints/unique/test_unique_multi_column.test
# description: NULL values and a multi-column UNIQUE constraint
# group: [unique]
statement ok
SET default_null_order='nulls_first';
statement ok
CREATE TEMPORARY TABLE integers(i INTEGER, j INTEGER)
statement ok
CREATE UNIQUE INDEX uidx ON integers (i,j)
statement ok
INSERT INTO integers VALUES (3, 4), (2, 5)
query II
SELECT * FROM integers
----
3 4
2 5
# insert a duplicate value as part of a chain of values, this should fail
statement error
INSERT INTO integers VALUES (6, 6), (3, 4);
----
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 6), (NULL, 7)
statement error
UPDATE integers SET i=77 WHERE i IS NULL
----
query II
SELECT * FROM integers ORDER BY i, j
----
NULL 6
NULL 6
NULL 7
2 5
3 4
statement ok
UPDATE integers SET i=77 WHERE i IS NULL AND j=7
query II
SELECT * FROM integers ORDER BY i, j
----
NULL 6
NULL 6
2 5
3 4
77 7
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement error
INSERT INTO integers VALUES (3, 4)
----
statement ok
DROP TABLE integers

View File

@@ -0,0 +1,74 @@
# name: test/sql/constraints/unique/test_unique_multi_constraint.test
# description: Multiple constraints
# group: [unique]
statement ok
CREATE TABLE integers(i INTEGER PRIMARY KEY, j INTEGER UNIQUE)
# no constraints are violated
statement ok
INSERT INTO integers VALUES (1, 1), (2, 2)
# only the second UNIQUE constraint is violated
statement error
INSERT INTO integers VALUES (3, 3), (4, 1)
----
# no constraints are violated
statement ok
INSERT INTO integers VALUES (3, 3), (4, 4)
# insert many values with a unique constraint violation at the end
statement error
INSERT INTO integers VALUES (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10), (11, 11), (12, 12), (13, 13), (14, 14), (15, 15), (16, 16), (17, 17), (18, 18), (19, 19), (20, 20), (21, 21), (22, 22), (23, 23), (24, 24), (25, 25), (26, 26), (27, 27), (28, 28), (29, 29), (30, 30), (31, 31), (32, 32), (33, 33), (34, 34), (35, 35), (36, 36), (37, 37), (38, 38), (39, 39), (40, 40), (41, 41), (42, 42), (43, 43), (44, 44), (45, 45), (46, 46), (47, 47), (48, 48), (49, 49), (50, 50), (51, 51), (52, 52), (53, 53), (54, 54), (55, 55), (56, 56), (57, 57), (58, 58), (59, 59), (60, 60), (61, 61), (62, 62), (63, 63), (64, 64), (65, 65), (66, 66), (67, 67), (68, 68), (69, 69), (70, 70), (71, 71), (72, 72), (73, 73), (74, 74), (75, 75), (76, 76), (77, 77), (78, 78), (79, 79), (80, 80), (81, 81), (82, 82), (83, 83), (84, 84), (85, 85), (86, 86), (87, 87), (88, 88), (89, 89), (90, 90), (91, 91), (92, 92), (93, 93), (94, 94), (95, 95), (96, 96), (97, 97), (98, 98), (99, 99), (5, 5), (NULL, NULL), (NULL, NULL), (NULL, NULL), (NULL, NULL)
----
query II
SELECT * FROM integers WHERE i > 0 ORDER BY 1
----
1 1
2 2
3 3
4 4
# attempt to append values that were inserted before (but failed)
# should work now
statement ok
INSERT INTO integers VALUES (5, 5), (6, 6)
query II
SELECT * FROM integers WHERE i > 0 ORDER BY 1
----
1 1
2 2
3 3
4 4
5 5
6 6
# now attempt conflicting updates
# conflict on PRIMARY KEY
statement error
UPDATE integers SET i=4, j=100 WHERE i=1
----
# conflict on UNIQUE INDEX
statement error
UPDATE integers SET i=100, j=4 WHERE j=1
----
# we can insert the old tuple normally
statement ok
INSERT INTO integers VALUES (100, 100)
query II
SELECT * FROM integers WHERE i > 0 ORDER BY 1
----
1 1
2 2
3 3
4 4
5 5
6 6
100 100

View File

@@ -0,0 +1,83 @@
# name: test/sql/constraints/unique/test_unique_string.test
# description: UNIQUE constraint on temporary tables with Strings
# group: [unique]
statement ok
CREATE TEMPORARY TABLE integers(i INTEGER, j VARCHAR)
statement ok
CREATE UNIQUE INDEX "uidx" ON "integers" ("j")
statement ok
INSERT INTO integers VALUES (3, '4'), (2, '5')
query IT
SELECT * FROM integers
----
3 4
2 5
statement error
INSERT INTO integers VALUES (6, '6'), (3, '4');
----
statement ok
INSERT INTO integers VALUES (6,NULL), (7,NULL)
statement error
UPDATE integers SET j='77' WHERE j IS NULL
----
query IT
SELECT * FROM integers ORDER BY i, j
----
2 5
3 4
6 NULL
7 NULL
statement ok
UPDATE integers SET j='7777777777777777777777777777' WHERE j IS NULL AND i=6
# we can insert a bunch of null values
statement ok
INSERT INTO integers VALUES (6,NULL), (7,NULL)
statement ok
INSERT INTO integers VALUES (6,NULL), (7,NULL)
statement ok
INSERT INTO integers VALUES (6,NULL), (7,NULL)
statement ok
INSERT INTO integers VALUES (6,NULL), (7,NULL)
statement ok
INSERT INTO integers VALUES (6,NULL), (7,NULL)
statement ok
INSERT INTO integers VALUES (6,NULL), (7,NULL)
statement ok
INSERT INTO integers VALUES (6,NULL), (7,NULL)
statement ok
INSERT INTO integers VALUES (6,NULL), (7,NULL)
statement ok
INSERT INTO integers VALUES (6,NULL), (7,NULL)
statement ok
INSERT INTO integers VALUES (6,NULL), (7,NULL)
statement error
INSERT INTO integers VALUES (3, '4')
----
statement error
INSERT INTO integers VALUES (3, '4')
----
statement ok
DROP TABLE integers

View File

@@ -0,0 +1,92 @@
# name: test/sql/constraints/unique/test_unique_temp.test
# description: UNIQUE constraint on temporary tables
# group: [unique]
statement ok
SET default_null_order='nulls_first';
statement ok
CREATE TEMPORARY TABLE integers(i INTEGER, j INTEGER)
statement ok
CREATE UNIQUE INDEX uidx ON integers (i)
# insert unique values
statement ok
INSERT INTO integers VALUES (3, 4), (2, 5)
query II
SELECT * FROM integers
----
3 4
2 5
# insert a duplicate value as part of a chain of values, this should fail
statement error
INSERT INTO integers VALUES (6, 6), (3, 4);
----
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
# but if we try to replace them like this it's going to fail
statement error
UPDATE integers SET i=77 WHERE i IS NULL
----
query II
SELECT * FROM integers ORDER BY i, j
----
NULL 6
NULL 7
2 5
3 4
# we can replace them like this though
statement ok
UPDATE integers SET i=77 WHERE i IS NULL AND j=6
query II
SELECT * FROM integers ORDER BY i, j
----
NULL 7
2 5
3 4
77 6
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement ok
INSERT INTO integers VALUES (NULL, 6), (NULL, 7)
statement error
INSERT INTO integers VALUES (NULL, 6), (3, 7)
----
statement ok
DROP TABLE integers