1e7a94d81Sdan# 2009 September 15 286d68295Sshane# 386d68295Sshane# The author disclaims copyright to this source code. In place of 486d68295Sshane# a legal notice, here is a blessing: 586d68295Sshane# 686d68295Sshane# May you do good and not evil. 786d68295Sshane# May you find forgiveness for yourself and forgive others. 886d68295Sshane# May you share freely, never taking more than you give. 986d68295Sshane# 1086d68295Sshane#*********************************************************************** 1186d68295Sshane# This file implements regression tests for SQLite library. 1286d68295Sshane# 1386d68295Sshane# This file implements tests for foreign keys. 1486d68295Sshane# 1586d68295Sshane 1686d68295Sshaneset testdir [file dirname $argv0] 1786d68295Sshanesource $testdir/tester.tcl 1886d68295Sshane 19856ef1a5Sdanifcapable {!foreignkey||!trigger} { 2086d68295Sshane finish_test 2186d68295Sshane return 2286d68295Sshane} 2386d68295Sshane 24b328debcSdanset testprefix fkey3 25b328debcSdan 2686d68295Sshane# Create a table and some data to work with. 2786d68295Sshane# 2886d68295Sshanedo_test fkey3-1.1 { 2986d68295Sshane execsql { 3086d68295Sshane PRAGMA foreign_keys=ON; 3186d68295Sshane CREATE TABLE t1(x INTEGER PRIMARY KEY); 3286d68295Sshane INSERT INTO t1 VALUES(100); 3386d68295Sshane INSERT INTO t1 VALUES(101); 3486d68295Sshane CREATE TABLE t2(y INTEGER REFERENCES t1 (x)); 3586d68295Sshane INSERT INTO t2 VALUES(100); 3686d68295Sshane INSERT INTO t2 VALUES(101); 3786d68295Sshane SELECT 1, x FROM t1; 3886d68295Sshane SELECT 2, y FROM t2; 3986d68295Sshane } 4086d68295Sshane} {1 100 1 101 2 100 2 101} 4186d68295Sshane 4286d68295Sshanedo_test fkey3-1.2 { 4386d68295Sshane catchsql { 4486d68295Sshane DELETE FROM t1 WHERE x=100; 4586d68295Sshane } 46*f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}} 4786d68295Sshane 4886d68295Sshanedo_test fkey3-1.3 { 4986d68295Sshane catchsql { 5086d68295Sshane DROP TABLE t1; 5186d68295Sshane } 52*f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}} 5386d68295Sshane 54d66c8309Sdando_test fkey3-1.4 { 55d66c8309Sdan execsql { 56d66c8309Sdan DROP TABLE t2; 57d66c8309Sdan } 58d66c8309Sdan} {} 59d66c8309Sdan 60d66c8309Sdando_test fkey3-1.5 { 61d66c8309Sdan execsql { 62d66c8309Sdan DROP TABLE t1; 63d66c8309Sdan } 64d66c8309Sdan} {} 65d66c8309Sdan 66d66c8309Sdando_test fkey3-2.1 { 67d66c8309Sdan execsql { 68d66c8309Sdan PRAGMA foreign_keys=ON; 69d66c8309Sdan CREATE TABLE t1(x INTEGER PRIMARY KEY); 70d66c8309Sdan INSERT INTO t1 VALUES(100); 71d66c8309Sdan INSERT INTO t1 VALUES(101); 72d66c8309Sdan CREATE TABLE t2(y INTEGER PRIMARY KEY REFERENCES t1 (x) ON UPDATE SET NULL); 73d66c8309Sdan } 74d66c8309Sdan execsql { 75d66c8309Sdan INSERT INTO t2 VALUES(100); 76d66c8309Sdan INSERT INTO t2 VALUES(101); 77d66c8309Sdan SELECT 1, x FROM t1; 78d66c8309Sdan SELECT 2, y FROM t2; 79d66c8309Sdan } 80d66c8309Sdan} {1 100 1 101 2 100 2 101} 81d66c8309Sdan 82b328debcSdan 83b328debcSdan#------------------------------------------------------------------------- 84b328debcSdan# The following tests - fkey-3.* - test some edge cases to do with 85b328debcSdan# inserting rows into tables that have foreign keys where the parent 86b328debcSdan# table is the same as the child table. Especially cases where the 87b328debcSdan# new row being inserted matches itself. 88b328debcSdan# 89b328debcSdando_execsql_test 3.1.1 { 90b328debcSdan CREATE TABLE t3(a, b, c, d, 91b328debcSdan UNIQUE(a, b), 92b328debcSdan FOREIGN KEY(c, d) REFERENCES t3(a, b) 93b328debcSdan ); 94b328debcSdan INSERT INTO t3 VALUES(1, 2, 1, 2); 95b328debcSdan} {} 96b328debcSdando_catchsql_test 3.1.2 { 97b328debcSdan INSERT INTO t3 VALUES(NULL, 2, 5, 2); 98*f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}} 99b328debcSdando_catchsql_test 3.1.3 { 100b328debcSdan INSERT INTO t3 VALUES(NULL, 3, 5, 2); 101*f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}} 102b328debcSdan 103b328debcSdando_execsql_test 3.2.1 { 104b328debcSdan CREATE TABLE t4(a UNIQUE, b REFERENCES t4(a)); 105b328debcSdan} 106b328debcSdando_catchsql_test 3.2.2 { 107b328debcSdan INSERT INTO t4 VALUES(NULL, 1); 108*f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}} 109b328debcSdan 110b328debcSdando_execsql_test 3.3.1 { 111b328debcSdan CREATE TABLE t5(a INTEGER PRIMARY KEY, b REFERENCES t5(a)); 112b328debcSdan INSERT INTO t5 VALUES(NULL, 1); 113b328debcSdan} {} 114b328debcSdando_catchsql_test 3.3.2 { 115b328debcSdan INSERT INTO t5 VALUES(NULL, 3); 116*f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}} 117b328debcSdan 118b328debcSdando_execsql_test 3.4.1 { 119b328debcSdan CREATE TABLE t6(a INTEGER PRIMARY KEY, b, c, d, 120b328debcSdan FOREIGN KEY(c, d) REFERENCES t6(a, b) 121b328debcSdan ); 122b328debcSdan CREATE UNIQUE INDEX t6i ON t6(b, a); 123b328debcSdan} 124b328debcSdando_execsql_test 3.4.2 { INSERT INTO t6 VALUES(NULL, 'a', 1, 'a'); } {} 125b328debcSdando_execsql_test 3.4.3 { INSERT INTO t6 VALUES(2, 'a', 2, 'a'); } {} 126b328debcSdando_execsql_test 3.4.4 { INSERT INTO t6 VALUES(NULL, 'a', 1, 'a'); } {} 127b328debcSdando_execsql_test 3.4.5 { INSERT INTO t6 VALUES(5, 'a', 2, 'a'); } {} 128b328debcSdando_catchsql_test 3.4.6 { 129b328debcSdan INSERT INTO t6 VALUES(NULL, 'a', 65, 'a'); 130*f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}} 131b328debcSdan 132b328debcSdando_execsql_test 3.4.7 { 133b328debcSdan INSERT INTO t6 VALUES(100, 'one', 100, 'one'); 134b328debcSdan DELETE FROM t6 WHERE a = 100; 135b328debcSdan} 136b328debcSdando_execsql_test 3.4.8 { 137b328debcSdan INSERT INTO t6 VALUES(100, 'one', 100, 'one'); 138b328debcSdan UPDATE t6 SET c = 1, d = 'a' WHERE a = 100; 139b328debcSdan DELETE FROM t6 WHERE a = 100; 140b328debcSdan} 141b328debcSdan 142b328debcSdando_execsql_test 3.5.1 { 143b328debcSdan CREATE TABLE t7(a, b, c, d INTEGER PRIMARY KEY, 144b328debcSdan FOREIGN KEY(c, d) REFERENCES t7(a, b) 145b328debcSdan ); 146b328debcSdan CREATE UNIQUE INDEX t7i ON t7(a, b); 147b328debcSdan} 148b328debcSdando_execsql_test 3.5.2 { INSERT INTO t7 VALUES('x', 1, 'x', NULL) } {} 149b328debcSdando_execsql_test 3.5.3 { INSERT INTO t7 VALUES('x', 2, 'x', 2) } {} 150b328debcSdando_catchsql_test 3.5.4 { 151b328debcSdan INSERT INTO t7 VALUES('x', 450, 'x', NULL); 152*f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}} 153b328debcSdando_catchsql_test 3.5.5 { 154b328debcSdan INSERT INTO t7 VALUES('x', 450, 'x', 451); 155*f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}} 156b328debcSdan 1577006c18eSdan 1587006c18eSdando_execsql_test 3.6.1 { 1597006c18eSdan CREATE TABLE t8(a, b, c, d, e, FOREIGN KEY(c, d) REFERENCES t8(a, b)); 1607006c18eSdan CREATE UNIQUE INDEX t8i1 ON t8(a, b); 1617006c18eSdan CREATE UNIQUE INDEX t8i2 ON t8(c); 1627006c18eSdan INSERT INTO t8 VALUES(1, 1, 1, 1, 1); 1637006c18eSdan} 1647006c18eSdando_catchsql_test 3.6.2 { 1657006c18eSdan UPDATE t8 SET d = 2; 166*f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}} 1677006c18eSdando_execsql_test 3.6.3 { UPDATE t8 SET d = 1; } 1687006c18eSdando_execsql_test 3.6.4 { UPDATE t8 SET e = 2; } 1697006c18eSdan 1707006c18eSdando_catchsql_test 3.6.5 { 1717006c18eSdan CREATE TABLE TestTable ( 1727006c18eSdan id INTEGER PRIMARY KEY, 1737006c18eSdan name text, 1747006c18eSdan source_id integer not null, 1757006c18eSdan parent_id integer, 1767006c18eSdan 1777006c18eSdan foreign key(source_id, parent_id) references TestTable(source_id, id) 1787006c18eSdan ); 1797006c18eSdan CREATE UNIQUE INDEX testindex on TestTable(source_id, id); 1807006c18eSdan PRAGMA foreign_keys=1; 1817006c18eSdan INSERT INTO TestTable VALUES (1, 'parent', 1, null); 1827006c18eSdan INSERT INTO TestTable VALUES (2, 'child', 1, 1); 1837006c18eSdan UPDATE TestTable SET parent_id=1000 where id=2; 184*f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}} 1857006c18eSdan 18686d68295Sshanefinish_test 187