mirror of https://github.com/sqlite/sqlite
Add further test cases to e_fkey.test.
FossilOrigin-Name: d61cc0e1a1e8b4bf49016d3d14554f9c20f86f6b
This commit is contained in:
parent
2f01f465f3
commit
e506deb255
12
manifest
12
manifest
|
@ -1,5 +1,5 @@
|
|||
C Add\stests\sto\se_fkey.test.
|
||||
D 2009-10-10T15:49:49
|
||||
C Add\sfurther\stest\scases\sto\se_fkey.test.
|
||||
D 2009-10-12T08:41:50
|
||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||
F Makefile.in 4ca3f1dd6efa2075bcb27f4dc43eef749877740d
|
||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||
|
@ -319,7 +319,7 @@ F test/descidx2.test 1310ed1326cdfed4ea2c55169631579f082d174f
|
|||
F test/descidx3.test 3394ad4d089335cac743c36a14129d6d931c316f
|
||||
F test/diskfull.test 0cede7ef9d8f415d9d3944005c76be7589bb5ebb
|
||||
F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376
|
||||
F test/e_fkey.test 4eed4c548dce094df9979b5f2c054e33fbce83e3
|
||||
F test/e_fkey.test f9fcab098eefc9eefe8624b730a48611dfeeface
|
||||
F test/enc.test e54531cd6bf941ee6760be041dff19a104c7acea
|
||||
F test/enc2.test 6d91a5286f59add0cfcbb2d0da913b76f2242398
|
||||
F test/enc3.test 5c550d59ff31dccdba5d1a02ae11c7047d77c041
|
||||
|
@ -756,7 +756,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
|||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||
P 89c548acf4691bad3d90400026267d4c6a55cde1
|
||||
R 7de7b5a6379d79285bcb46eab489900a
|
||||
P 5ec07feea47e727824b8b48236b5cce80539a455
|
||||
R ec48fda10fcfca9f54309367518982c3
|
||||
U dan
|
||||
Z 8b7ccd9ba2e7265c9f40169de47aa9c5
|
||||
Z 4e3c8e06ad003cd47ba138558d63cec3
|
||||
|
|
|
@ -1 +1 @@
|
|||
5ec07feea47e727824b8b48236b5cce80539a455
|
||||
d61cc0e1a1e8b4bf49016d3d14554f9c20f86f6b
|
398
test/e_fkey.test
398
test/e_fkey.test
|
@ -23,6 +23,352 @@ execsql "PRAGMA foreign_keys = ON"
|
|||
### SECTION 1: Introduction to Foreign Key Constraints
|
||||
###########################################################################
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# /* EV: R-04042-24825 */
|
||||
#
|
||||
# Verify that the syntax in the first example in section 1 is valid.
|
||||
#
|
||||
do_test e_fkey-38.1 {
|
||||
execsql {
|
||||
CREATE TABLE artist(
|
||||
artistid INTEGER PRIMARY KEY,
|
||||
artistname TEXT
|
||||
);
|
||||
CREATE TABLE track(
|
||||
trackid INTEGER,
|
||||
trackname TEXT,
|
||||
trackartist INTEGER,
|
||||
FOREIGN KEY(trackartist) REFERENCES artist(artistid)
|
||||
);
|
||||
}
|
||||
} {}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# /* EV: R-61362-32087 */
|
||||
#
|
||||
# Attempting to insert a row into the 'track' table that corresponds
|
||||
# to no row in the 'artist' table fails.
|
||||
#
|
||||
do_test e_fkey-39.1 {
|
||||
catchsql { INSERT INTO track VALUES(1, 'track 1', 1) }
|
||||
} {1 {foreign key constraint failed}}
|
||||
do_test e_fkey-39.2 {
|
||||
execsql { INSERT INTO artist VALUES(2, 'artist 1') }
|
||||
catchsql { INSERT INTO track VALUES(1, 'track 1', 1) }
|
||||
} {1 {foreign key constraint failed}}
|
||||
do_test e_fkey-39.2 {
|
||||
execsql { INSERT INTO track VALUES(1, 'track 1', 2) }
|
||||
} {}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# /* EV: R-24401-52400 */
|
||||
#
|
||||
# Attempting to delete a row from the 'artist' table while there are
|
||||
# dependent rows in the track table also fails.
|
||||
#
|
||||
do_test e_fkey-40.1 {
|
||||
catchsql { DELETE FROM artist WHERE artistid = 2 }
|
||||
} {1 {foreign key constraint failed}}
|
||||
do_test e_fkey-40.2 {
|
||||
execsql {
|
||||
DELETE FROM track WHERE trackartist = 2;
|
||||
DELETE FROM artist WHERE artistid = 2;
|
||||
}
|
||||
} {}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# /* EV: R-23980-48859 */
|
||||
#
|
||||
# If the foreign key column (trackartist) in table 'track' is set to NULL,
|
||||
# there is no requirement for a matching row in the 'artist' table.
|
||||
#
|
||||
do_test e_fkey-41.1 {
|
||||
execsql {
|
||||
INSERT INTO track VALUES(1, 'track 1', NULL);
|
||||
INSERT INTO track VALUES(2, 'track 2', NULL);
|
||||
}
|
||||
} {}
|
||||
do_test e_fkey-41.2 {
|
||||
execsql { SELECT * FROM artist }
|
||||
} {}
|
||||
do_test e_fkey-41.3 {
|
||||
# Setting the trackid to a non-NULL value fails, of course.
|
||||
catchsql { UPDATE track SET trackartist = 5 WHERE trackid = 1 }
|
||||
} {1 {foreign key constraint failed}}
|
||||
do_test e_fkey-41.4 {
|
||||
execsql {
|
||||
INSERT INTO artist VALUES(5, 'artist 5');
|
||||
UPDATE track SET trackartist = 5 WHERE trackid = 1;
|
||||
}
|
||||
catchsql { DELETE FROM artist WHERE artistid = 5}
|
||||
} {1 {foreign key constraint failed}}
|
||||
do_test e_fkey-41.5 {
|
||||
execsql {
|
||||
UPDATE track SET trackartist = NULL WHERE trackid = 1;
|
||||
DELETE FROM artist WHERE artistid = 5;
|
||||
}
|
||||
} {}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# /* EV: R-52486-21352 */
|
||||
#
|
||||
# Test that the following is true fo all rows in the track table:
|
||||
#
|
||||
# trackartist IS NULL OR
|
||||
# EXISTS(SELECT 1 FROM artist WHERE artistid=trackartist)
|
||||
#
|
||||
|
||||
# This procedure executes a test case to check that statement
|
||||
# R-52486-21352 is true after executing the SQL statement passed.
|
||||
# as the second argument.
|
||||
proc test_r52486_21352 {tn sql} {
|
||||
set res [catchsql $sql]
|
||||
set results {
|
||||
{0 {}}
|
||||
{1 {PRIMARY KEY must be unique}}
|
||||
{1 {foreign key constraint failed}}
|
||||
}
|
||||
if {[lsearch $results $res]<0} {
|
||||
error $res
|
||||
}
|
||||
|
||||
do_test e_fkey-42.$tn {
|
||||
execsql {
|
||||
SELECT count(*) FROM track WHERE NOT (
|
||||
trackartist IS NULL OR
|
||||
EXISTS(SELECT 1 FROM artist WHERE artistid=trackartist)
|
||||
)
|
||||
}
|
||||
} {0}
|
||||
}
|
||||
|
||||
# Execute a series of random INSERT, UPDATE and DELETE operations
|
||||
# (some of which may fail due to FK or PK constraint violations) on
|
||||
# the two tables in the example schema. Test that R-52486-21352
|
||||
# is true after executing each operation.
|
||||
#
|
||||
set Template {
|
||||
{INSERT INTO track VALUES($t, 'track $t', $a)}
|
||||
{DELETE FROM track WHERE trackid = $t}
|
||||
{UPDATE track SET trackartist = $a WHERE trackid = $t}
|
||||
{INSERT INTO artist VALUES($a, 'artist $a')}
|
||||
{DELETE FROM artist WHERE artistid = $a}
|
||||
{UPDATE artist SET artistid = $a2 WHERE artistid = $a}
|
||||
}
|
||||
for {set i 0} {$i < 500} {incr i} {
|
||||
set a [expr int(rand()*10)]
|
||||
set a2 [expr int(rand()*10)]
|
||||
set t [expr int(rand()*50)]
|
||||
set sql [subst [lindex $Template [expr int(rand()*6)]]]
|
||||
|
||||
test_r52486_21352 $i $sql
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# /* EV: R-42412-59321 */
|
||||
#
|
||||
# Check that a NOT NULL constraint can be added to the example schema
|
||||
# to prohibit NULL child keys from being inserted.
|
||||
#
|
||||
drop_all_tables
|
||||
do_test e_fkey-48.1 {
|
||||
execsql {
|
||||
CREATE TABLE artist(
|
||||
artistid INTEGER PRIMARY KEY,
|
||||
artistname TEXT
|
||||
);
|
||||
CREATE TABLE track(
|
||||
trackid INTEGER,
|
||||
trackname TEXT,
|
||||
trackartist INTEGER NOT NULL,
|
||||
FOREIGN KEY(trackartist) REFERENCES artist(artistid)
|
||||
);
|
||||
}
|
||||
} {}
|
||||
do_test e_fkey-48.2 {
|
||||
catchsql { INSERT INTO track VALUES(14, 'Mr. Bojangles', NULL) }
|
||||
} {1 {track.trackartist may not be NULL}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# /* EV: R-01991-24099 */
|
||||
#
|
||||
# Test an example from foreignkeys.html.
|
||||
#
|
||||
drop_all_tables
|
||||
do_test e_fkey-43.1 {
|
||||
execsql {
|
||||
CREATE TABLE artist(
|
||||
artistid INTEGER PRIMARY KEY,
|
||||
artistname TEXT
|
||||
);
|
||||
CREATE TABLE track(
|
||||
trackid INTEGER,
|
||||
trackname TEXT,
|
||||
trackartist INTEGER,
|
||||
FOREIGN KEY(trackartist) REFERENCES artist(artistid)
|
||||
);
|
||||
INSERT INTO artist VALUES(1, 'Dean Martin');
|
||||
INSERT INTO artist VALUES(2, 'Frank Sinatra');
|
||||
INSERT INTO track VALUES(11, 'That''s Amore', 1);
|
||||
INSERT INTO track VALUES(12, 'Christmas Blues', 1);
|
||||
INSERT INTO track VALUES(13, 'My Way', 2);
|
||||
}
|
||||
} {}
|
||||
do_test e_fkey-43.2 {
|
||||
catchsql { INSERT INTO track VALUES(14, 'Mr. Bojangles', 3) }
|
||||
} {1 {foreign key constraint failed}}
|
||||
do_test e_fkey-43.3 {
|
||||
execsql { INSERT INTO track VALUES(14, 'Mr. Bojangles', NULL) }
|
||||
} {}
|
||||
do_test e_fkey-43.4 {
|
||||
catchsql {
|
||||
UPDATE track SET trackartist = 3 WHERE trackname = 'Mr. Bojangles';
|
||||
}
|
||||
} {1 {foreign key constraint failed}}
|
||||
do_test e_fkey-43.5 {
|
||||
execsql {
|
||||
INSERT INTO artist VALUES(3, 'Sammy Davis Jr.');
|
||||
UPDATE track SET trackartist = 3 WHERE trackname = 'Mr. Bojangles';
|
||||
INSERT INTO track VALUES(15, 'Boogie Woogie', 3);
|
||||
}
|
||||
} {}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# /* EV: R-22377-02546 */
|
||||
#
|
||||
# Test the second example from the first section of foreignkeys.html.
|
||||
#
|
||||
do_test e_fkey-44.1 {
|
||||
catchsql {
|
||||
DELETE FROM artist WHERE artistname = 'Frank Sinatra';
|
||||
}
|
||||
} {1 {foreign key constraint failed}}
|
||||
do_test e_fkey-44.2 {
|
||||
execsql {
|
||||
DELETE FROM track WHERE trackname = 'My Way';
|
||||
DELETE FROM artist WHERE artistname = 'Frank Sinatra';
|
||||
}
|
||||
} {}
|
||||
do_test e_fkey-44.3 {
|
||||
catchsql {
|
||||
UPDATE artist SET artistid=4 WHERE artistname = 'Dean Martin';
|
||||
}
|
||||
} {1 {foreign key constraint failed}}
|
||||
do_test e_fkey-44.4 {
|
||||
execsql {
|
||||
DELETE FROM track WHERE trackname IN('That''s Amore', 'Christmas Blues');
|
||||
UPDATE artist SET artistid=4 WHERE artistname = 'Dean Martin';
|
||||
}
|
||||
} {}
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# /* EV: R-56032-24923 */
|
||||
#
|
||||
# Test that a foreign key constraint is satisifed if "for each row in the child
|
||||
# table either one or more of the child key columns are NULL, or there exists a
|
||||
# row in the parent table for which each parent key column contains a value
|
||||
# equal to the value in its associated child key column".
|
||||
#
|
||||
# /* EV: R-57765-12380 */
|
||||
#
|
||||
# Test also that the comparison rules are used when testing if there
|
||||
# is a matching row in the parent table of a foreign key constraint.
|
||||
#
|
||||
drop_all_tables
|
||||
do_test e_fkey-45.1 {
|
||||
execsql {
|
||||
CREATE TABLE par(p PRIMARY KEY);
|
||||
CREATE TABLE chi(c REFERENCES par);
|
||||
|
||||
INSERT INTO par VALUES(1);
|
||||
INSERT INTO par VALUES('1');
|
||||
INSERT INTO par VALUES(X'31');
|
||||
SELECT typeof(p) FROM par;
|
||||
}
|
||||
} {integer text blob}
|
||||
|
||||
proc test_efkey_45 {tn isError sql} {
|
||||
do_test e_fkey-45.$tn.1 "
|
||||
catchsql {$sql}
|
||||
" [lindex {{0 {}} {1 {foreign key constraint failed}}} $isError]
|
||||
|
||||
do_test e_fkey-45.$tn.2 {
|
||||
execsql {
|
||||
SELECT * FROM chi WHERE c IS NOT NULL AND c NOT IN (SELECT p FROM par)
|
||||
}
|
||||
} {}
|
||||
}
|
||||
|
||||
test_efkey_45 1 0 "INSERT INTO chi VALUES(1)"
|
||||
test_efkey_45 2 1 "INSERT INTO chi VALUES('1.0')"
|
||||
test_efkey_45 3 0 "INSERT INTO chi VALUES('1')"
|
||||
test_efkey_45 4 1 "DELETE FROM par WHERE p = '1'"
|
||||
test_efkey_45 5 0 "DELETE FROM chi WHERE c = '1'"
|
||||
test_efkey_45 6 0 "DELETE FROM par WHERE p = '1'"
|
||||
test_efkey_45 7 1 "INSERT INTO chi VALUES('1')"
|
||||
test_efkey_45 8 0 "INSERT INTO chi VALUES(X'31')"
|
||||
test_efkey_45 9 1 "INSERT INTO chi VALUES(X'32')"
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# /* EV: R-15796-47513 */
|
||||
#
|
||||
# Specifically, test that when comparing child and parent key values the
|
||||
# default collation sequence of the parent key column is used.
|
||||
#
|
||||
drop_all_tables
|
||||
do_test e_fkey-46.1 {
|
||||
execsql {
|
||||
CREATE TABLE t1(a COLLATE nocase PRIMARY KEY);
|
||||
CREATE TABLE t2(b REFERENCES t1);
|
||||
}
|
||||
} {}
|
||||
do_test e_fkey-46.2 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES('oNe');
|
||||
INSERT INTO t2 VALUES('one');
|
||||
INSERT INTO t2 VALUES('ONE');
|
||||
UPDATE t2 SET b = 'OnE';
|
||||
UPDATE t1 SET a = 'ONE';
|
||||
}
|
||||
} {}
|
||||
do_test e_fkey-46.3 {
|
||||
catchsql { UPDATE t2 SET b = 'two' WHERE rowid = 1 }
|
||||
} {1 {foreign key constraint failed}}
|
||||
do_test e_fkey-46.4 {
|
||||
catchsql { DELETE FROM t1 WHERE rowid = 1 }
|
||||
} {1 {foreign key constraint failed}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# /* EV: R-04240-13860 */
|
||||
#
|
||||
# Specifically, test that when comparing child and parent key values the
|
||||
# affinity of the parent key column is applied to the child key value
|
||||
# before the comparison takes place.
|
||||
#
|
||||
drop_all_tables
|
||||
do_test e_fkey-47.1 {
|
||||
execsql {
|
||||
CREATE TABLE t1(a NUMERIC PRIMARY KEY);
|
||||
CREATE TABLE t2(b TEXT REFERENCES t1);
|
||||
}
|
||||
} {}
|
||||
do_test e_fkey-47.2 {
|
||||
execsql {
|
||||
INSERT INTO t1 VALUES(1);
|
||||
INSERT INTO t1 VALUES(2);
|
||||
INSERT INTO t1 VALUES('three');
|
||||
INSERT INTO t2 VALUES('2.0');
|
||||
SELECT b, typeof(b) FROM t2;
|
||||
}
|
||||
} {2.0 text}
|
||||
do_test e_fkey-47.3 {
|
||||
execsql { SELECT typeof(a) FROM t1 }
|
||||
} {integer integer text}
|
||||
do_test e_fkey-47.4 {
|
||||
catchsql { DELETE FROM t1 WHERE rowid = 2 }
|
||||
} {1 {foreign key constraint failed}}
|
||||
|
||||
###########################################################################
|
||||
### SECTION 2: Enabling Foreign Key Support
|
||||
###########################################################################
|
||||
|
@ -35,12 +381,64 @@ execsql "PRAGMA foreign_keys = ON"
|
|||
### SECTION 4.1: Composite Foreign Key Constraints
|
||||
###########################################################################
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# /* EV: R-56396-15644 */
|
||||
#
|
||||
# Test the example schema in the "Composite Foreign Key Constraints"
|
||||
# section.
|
||||
#
|
||||
do_test e_fkey-36.1 {
|
||||
execsql {
|
||||
CREATE TABLE album(
|
||||
albumartist TEXT,
|
||||
albumname TEXT,
|
||||
albumcover BINARY,
|
||||
PRIMARY KEY(albumartist, albumname)
|
||||
);
|
||||
CREATE TABLE song(
|
||||
songid INTEGER,
|
||||
songartist TEXT,
|
||||
songalbum TEXT,
|
||||
songname TEXT,
|
||||
FOREIGN KEY(songartist, songalbum) REFERENCES album(albumartist,albumname)
|
||||
);
|
||||
}
|
||||
} {}
|
||||
|
||||
do_test e_fkey-36.2 {
|
||||
execsql {
|
||||
INSERT INTO album VALUES('Elvis Presley', 'Elvis'' Christmas Album', NULL);
|
||||
INSERT INTO song VALUES(
|
||||
1, 'Elvis Presley', 'Elvis'' Christmas Album', 'Here Comes Santa Clause'
|
||||
);
|
||||
}
|
||||
} {}
|
||||
do_test e_fkey-36.3 {
|
||||
catchsql {
|
||||
INSERT INTO song VALUES(2, 'Elvis Presley', 'Elvis Is Back!', 'Fever');
|
||||
}
|
||||
} {1 {foreign key constraint failed}}
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# /* EV: R-33626-48418 */
|
||||
#
|
||||
# Check that if any of the child key columns in the above schema are NULL,
|
||||
# there is no requirement for a corresponding parent key.
|
||||
#
|
||||
do_test e_fkey-37.1 {
|
||||
execsql {
|
||||
INSERT INTO song VALUES(2, 'Elvis Presley', NULL, 'Fever');
|
||||
INSERT INTO song VALUES(3, NULL, 'Elvis Is Back', 'Soldier Boy');
|
||||
}
|
||||
} {}
|
||||
|
||||
###########################################################################
|
||||
### SECTION 4.2: Deferred Foreign Key Constraints
|
||||
###########################################################################
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Note: R-35290-16460 is tested below.
|
||||
#
|
||||
# TODO: R-30323-21917
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue