AryaWu/sqlite
0
1# 2001 September 152#3# The author disclaims copyright to this source code. In place of4# a legal notice, here is a blessing:5#6# May you do good and not evil.7# May you find forgiveness for yourself and forgive others.8# May you share freely, never taking more than you give.9#10#***********************************************************************11# This file implements regression tests for SQLite library.12#13# This file implements tests for foreign keys.14#15 16set testdir [file dirname $argv0]17source $testdir/tester.tcl18set testprefix fkey819 20ifcapable {!foreignkey} {21 finish_test22 return23}24do_execsql_test 1.0 { PRAGMA foreign_keys = 1; }25 26 27foreach {tn use_stmt sql schema} {28 1 1 "DELETE FROM p1" {29 CREATE TABLE p1(a PRIMARY KEY);30 CREATE TABLE c1(b REFERENCES p1);31 }32 33 2.1 0 "DELETE FROM p1" {34 CREATE TABLE p1(a PRIMARY KEY);35 CREATE TABLE c1(b REFERENCES p1 ON DELETE CASCADE);36 }37 2.2 0 "DELETE FROM p1" {38 CREATE TABLE p1(a PRIMARY KEY);39 CREATE TABLE c1(b REFERENCES p1 ON DELETE SET NULL);40 }41 2.3 1 "DELETE FROM p1" {42 CREATE TABLE p1(a PRIMARY KEY);43 CREATE TABLE c1(b REFERENCES p1 ON DELETE SET DEFAULT);44 }45 46 3 1 "DELETE FROM p1" {47 CREATE TABLE p1(a PRIMARY KEY);48 CREATE TABLE c1(b REFERENCES p1 ON DELETE CASCADE);49 CREATE TRIGGER ct1 AFTER DELETE ON c1 BEGIN50 INSERT INTO p1 VALUES('x');51 END;52 }53 54 4 1 "DELETE FROM p1" {55 CREATE TABLE p1(a PRIMARY KEY);56 CREATE TABLE c1(b REFERENCES p1 ON DELETE CASCADE, c PRIMARY KEY);57 CREATE TABLE cc1(d REFERENCES c1);58 }59 60 5.1 0 "DELETE FROM p1" {61 CREATE TABLE p1(a PRIMARY KEY);62 CREATE TABLE c1(b REFERENCES p1 ON DELETE CASCADE, c PRIMARY KEY);63 CREATE TABLE cc1(d REFERENCES c1 ON DELETE CASCADE);64 }65 5.2 0 "DELETE FROM p1" {66 CREATE TABLE p1(a PRIMARY KEY);67 CREATE TABLE c1(b REFERENCES p1 ON DELETE CASCADE, c PRIMARY KEY);68 CREATE TABLE cc1(d REFERENCES c1 ON DELETE SET NULL);69 }70 5.3 1 "DELETE FROM p1" {71 CREATE TABLE p1(a PRIMARY KEY);72 CREATE TABLE c1(b REFERENCES p1 ON DELETE CASCADE, c PRIMARY KEY);73 CREATE TABLE cc1(d REFERENCES c1 ON DELETE SET DEFAULT);74 }75 76 6.1 1 "UPDATE p1 SET a = ?" {77 CREATE TABLE p1(a PRIMARY KEY);78 CREATE TABLE c1(b REFERENCES p1 ON UPDATE SET NULL, c);79 }80 6.2 0 "UPDATE OR IGNORE p1 SET a = ?" {81 CREATE TABLE p1(a PRIMARY KEY);82 CREATE TABLE c1(b REFERENCES p1 ON UPDATE SET NULL, c);83 }84 6.3 1 "UPDATE OR IGNORE p1 SET a = ?" {85 CREATE TABLE p1(a PRIMARY KEY);86 CREATE TABLE c1(b REFERENCES p1 ON UPDATE CASCADE, c);87 }88 6.4 1 "UPDATE OR IGNORE p1 SET a = ?" {89 CREATE TABLE p1(a PRIMARY KEY);90 CREATE TABLE c1(b NOT NULL REFERENCES p1 ON UPDATE SET NULL, c);91 }92 93} {94 drop_all_tables95 do_test 1.$tn {96 execsql $schema97 set stmt [sqlite3_prepare_v2 db $sql -1 dummy]98 set ret [uses_stmt_journal $stmt]99 sqlite3_finalize $stmt100 set ret101 } $use_stmt102}103 104#-------------------------------------------------------------------------105# The following tests check that foreign key constaint counters are106# correctly updated for any implicit DELETE operations that occur107# when a REPLACE command is executed against a WITHOUT ROWID table108# that has no triggers or auxiliary indexes.109#110reset_db111do_execsql_test 2.1.0 {112 PRAGMA foreign_keys = on;113 CREATE TABLE p1(a PRIMARY KEY, b) WITHOUT ROWID;114 CREATE TABLE c1(x REFERENCES p1 DEFERRABLE INITIALLY DEFERRED);115 116 INSERT INTO p1 VALUES(1, 'one');117 INSERT INTO p1 VALUES(2, 'two');118 INSERT INTO c1 VALUES(1);119 INSERT INTO c1 VALUES(2);120}121 122do_catchsql_test 2.1.2 {123 BEGIN;124 DELETE FROM p1 WHERE a=1;125 INSERT OR REPLACE INTO p1 VALUES(2, 'two');126 COMMIT;127} {1 {FOREIGN KEY constraint failed}}128 129reset_db130do_execsql_test 2.2.0 {131 PRAGMA foreign_keys = on;132 CREATE TABLE p2(a PRIMARY KEY, b);133 CREATE TABLE c2(134 x PRIMARY KEY,135 y REFERENCES p2 DEFERRABLE INITIALLY DEFERRED136 ) WITHOUT ROWID;137}138 139do_catchsql_test 2.2.1 {140 BEGIN;141 INSERT INTO c2 VALUES(13, 13);142 INSERT OR REPLACE INTO c2 VALUES(13, 13);143 DELETE FROM c2;144 COMMIT;145} {0 {}}146 147reset_db148do_execsql_test 2.3.0 {149 PRAGMA foreign_keys = on;150 CREATE TABLE p3(a PRIMARY KEY, b) WITHOUT ROWID;151 CREATE TABLE c3(x REFERENCES p3);152 153 INSERT INTO p3 VALUES(1, 'one');154 INSERT INTO p3 VALUES(2, 'two');155 INSERT INTO c3 VALUES(1);156 INSERT INTO c3 VALUES(2);157 158 CREATE TRIGGER p3d AFTER DELETE ON p3 WHEN old.a=1 BEGIN159 INSERT OR REPLACE INTO p3 VALUES(2, 'three');160 END;161}162 163do_catchsql_test 2.3.1 {164 DELETE FROM p3 WHERE a=1165} {1 {FOREIGN KEY constraint failed}}166 167 168do_execsql_test 3.0 {169 PRAGMA foreign_keys=ON;170 CREATE TABLE t2(171 a PRIMARY KEY, b, c, d, e,172 FOREIGN KEY(b, c) REFERENCES t2(d, e)173 ) WITHOUT ROWID;174 CREATE UNIQUE INDEX idx ON t2(d, e);175 176 INSERT INTO t2 VALUES(1, 'one', 'one', 'one', 'one'); -- row is parent of self177 INSERT INTO t2 VALUES(2, 'one', 'one', 'one', NULL); -- parent is row 1178}179 180do_catchsql_test 3.1 {181 DELETE FROM t2 WHERE a=1;182} {1 {FOREIGN KEY constraint failed}}183 184do_execsql_test 4.0 {185 CREATE TABLE t1 (186 c1 PRIMARY KEY,187 c2 NUMERIC,188 FOREIGN KEY(c1) REFERENCES t1(c2)189 ) WITHOUT ROWID ;190 CREATE INDEX t1c1 ON t1(c1);191 CREATE UNIQUE INDEX t1c1unique ON t1(c2);192}193do_catchsql_test 4.1 {194 INSERT OR REPLACE INTO t1 VALUES(10000, 20000);195} {1 {FOREIGN KEY constraint failed}}196do_execsql_test 4.2 {197 INSERT OR REPLACE INTO t1 VALUES(20000, 20000);198}199 200#-------------------------------------------------------------------------201reset_db202do_execsql_test 5.0 {203 PRAGMA foreign_keys = true;204 CREATE TABLE parent(205 p TEXT PRIMARY KEY206 );207 CREATE TABLE child(208 c INTEGER UNIQUE, 209 FOREIGN KEY(c) REFERENCES parent(p) DEFERRABLE INITIALLY DEFERRED210 );211 BEGIN;212 INSERT INTO child VALUES(123);213 INSERT INTO parent VALUES('123');214 COMMIT;215}216do_execsql_test 5.1 {217 PRAGMA integrity_check;218} {ok}219 220do_execsql_test 5.2 {221 INSERT INTO parent VALUES(1200);222 BEGIN;223 INSERT INTO child VALUES(456);224 UPDATE parent SET p = '456' WHERE p=1200;225 COMMIT;226}227do_execsql_test 5.3 {228 PRAGMA integrity_check;229} {ok}230 231#-------------------------------------------------------------------------232reset_db233forcedelete test.db2234do_execsql_test 6.1 {235 PRAGMA foreign_keys = on;236 CREATE TABLE c1(b);237 INSERT INTO c1 VALUES(123);238}239 240do_execsql_test 6.2 {241 ATTACH 'test.db2' AS aux;242 CREATE TABLE aux.p1(a INTEGER PRIMARY KEY);243 CREATE TABLE aux.c1(b REFERENCES p1(a) ON DELETE RESTRICT);244 245 INSERT INTO aux.p1 VALUES(123);246}247 248do_execsql_test 6.3 {249 DELETE FROM aux.p1 WHERE a=123;250}251 252 253finish_test254 