3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing:
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.
10 #***********************************************************************
11 # This file implements regression tests for SQLite library.
13 # This file implements tests for foreign keys.
16 set testdir [file dirname $argv0]
17 source $testdir/tester.tcl
19 ifcapable {!foreignkey||!trigger} {
24 #-------------------------------------------------------------------------
27 # fkey2-1.*: Simple tests to check that immediate and deferred foreign key
28 # constraints work when not inside a transaction.
30 # fkey2-2.*: Tests to verify that deferred foreign keys work inside
31 # explicit transactions (i.e that processing really is deferred).
33 # fkey2-3.*: Tests that a statement transaction is rolled back if an
34 # immediate foreign key constraint is violated.
36 # fkey2-4.*: Test that FK actions may recurse even when recursive triggers
39 # fkey2-5.*: Check that if foreign-keys are enabled, it is not possible
40 # to write to an FK column using the incremental blob API.
42 # fkey2-6.*: Test that FK processing is automatically disabled when
45 # fkey2-7.*: Test using an IPK as the key in the child (referencing) table.
47 # fkey2-8.*: Test that enabling/disabling foreign key support while a
48 # transaction is active is not possible.
50 # fkey2-9.*: Test SET DEFAULT actions.
52 # fkey2-10.*: Test errors.
54 # fkey2-11.*: Test CASCADE actions.
56 # fkey2-12.*: Test RESTRICT actions.
58 # fkey2-13.*: Test that FK processing is performed when a row is REPLACED by
59 # an UPDATE or INSERT statement.
61 # fkey2-14.*: Test the ALTER TABLE and DROP TABLE commands.
63 # fkey2-15.*: Test that if there are no (known) outstanding foreign key
64 # constraint violations in the database, inserting into a parent
65 # table or deleting from a child table does not cause SQLite
66 # to check if this has repaired an outstanding violation.
68 # fkey2-16.*: Test that rows that refer to themselves may be inserted,
69 # updated and deleted.
71 # fkey2-17.*: Test that the "count_changes" pragma does not interfere with
72 # FK constraint processing.
74 # fkey2-18.*: Test that the authorization callback is invoked when processing
77 # fkey2-20.*: Test that ON CONFLICT clauses specified as part of statements
78 # do not affect the operation of FK constraints.
80 # fkey2-genfkey.*: Tests that were used with the shell tool .genfkey
81 # command. Recycled to test the built-in implementation.
83 # fkey2-dd08e5.*: Tests to verify that ticket dd08e5a988d00decc4a543daa8d
88 execsql { PRAGMA foreign_keys = on }
90 set FkeySimpleSchema {
91 PRAGMA foreign_keys = on;
92 CREATE TABLE t1(a PRIMARY KEY, b);
93 CREATE TABLE t2(c REFERENCES t1(a) /D/ , d);
95 CREATE TABLE t3(a PRIMARY KEY, b);
96 CREATE TABLE t4(c REFERENCES t3 /D/, d);
98 CREATE TABLE t7(a, b INTEGER PRIMARY KEY);
99 CREATE TABLE t8(c REFERENCES t7 /D/, d);
101 CREATE TABLE t9(a REFERENCES nosuchtable, b);
102 CREATE TABLE t10(a REFERENCES t9(c) /D/, b);
106 set FkeySimpleTests {
107 1.1 "INSERT INTO t2 VALUES(1, 3)" {1 {FOREIGN KEY constraint failed}}
108 1.2 "INSERT INTO t1 VALUES(1, 2)" {0 {}}
109 1.3 "INSERT INTO t2 VALUES(1, 3)" {0 {}}
110 1.4 "INSERT INTO t2 VALUES(2, 4)" {1 {FOREIGN KEY constraint failed}}
111 1.5 "INSERT INTO t2 VALUES(NULL, 4)" {0 {}}
112 1.6 "UPDATE t2 SET c=2 WHERE d=4" {1 {FOREIGN KEY constraint failed}}
113 1.7 "UPDATE t2 SET c=1 WHERE d=4" {0 {}}
114 1.9 "UPDATE t2 SET c=1 WHERE d=4" {0 {}}
115 1.10 "UPDATE t2 SET c=NULL WHERE d=4" {0 {}}
116 1.11 "DELETE FROM t1 WHERE a=1" {1 {FOREIGN KEY constraint failed}}
117 1.12 "UPDATE t1 SET a = 2" {1 {FOREIGN KEY constraint failed}}
118 1.13 "UPDATE t1 SET a = 1" {0 {}}
120 2.1 "INSERT INTO t4 VALUES(1, 3)" {1 {FOREIGN KEY constraint failed}}
121 2.2 "INSERT INTO t3 VALUES(1, 2)" {0 {}}
122 2.3 "INSERT INTO t4 VALUES(1, 3)" {0 {}}
124 4.1 "INSERT INTO t8 VALUES(1, 3)" {1 {FOREIGN KEY constraint failed}}
125 4.2 "INSERT INTO t7 VALUES(2, 1)" {0 {}}
126 4.3 "INSERT INTO t8 VALUES(1, 3)" {0 {}}
127 4.4 "INSERT INTO t8 VALUES(2, 4)" {1 {FOREIGN KEY constraint failed}}
128 4.5 "INSERT INTO t8 VALUES(NULL, 4)" {0 {}}
129 4.6 "UPDATE t8 SET c=2 WHERE d=4" {1 {FOREIGN KEY constraint failed}}
130 4.7 "UPDATE t8 SET c=1 WHERE d=4" {0 {}}
131 4.9 "UPDATE t8 SET c=1 WHERE d=4" {0 {}}
132 4.10 "UPDATE t8 SET c=NULL WHERE d=4" {0 {}}
133 4.11 "DELETE FROM t7 WHERE b=1" {1 {FOREIGN KEY constraint failed}}
134 4.12 "UPDATE t7 SET b = 2" {1 {FOREIGN KEY constraint failed}}
135 4.13 "UPDATE t7 SET b = 1" {0 {}}
136 4.14 "INSERT INTO t8 VALUES('a', 'b')" {1 {FOREIGN KEY constraint failed}}
137 4.15 "UPDATE t7 SET b = 5" {1 {FOREIGN KEY constraint failed}}
138 4.16 "UPDATE t7 SET rowid = 5" {1 {FOREIGN KEY constraint failed}}
139 4.17 "UPDATE t7 SET a = 10" {0 {}}
141 5.1 "INSERT INTO t9 VALUES(1, 3)" {1 {no such table: main.nosuchtable}}
142 5.2 "INSERT INTO t10 VALUES(1, 3)"
143 {1 {foreign key mismatch - "t10" referencing "t9"}}
146 do_test fkey2-1.1.0 {
147 execsql [string map {/D/ {}} $FkeySimpleSchema]
149 foreach {tn zSql res} $FkeySimpleTests {
150 do_test fkey2-1.1.$tn.1 { catchsql $zSql } $res
151 do_test fkey2-1.1.$tn.2 { execsql {PRAGMA foreign_key_check(t1)} } {}
152 do_test fkey2-1.1.$tn.3 { execsql {PRAGMA foreign_key_check(t2)} } {}
153 do_test fkey2-1.1.$tn.4 { execsql {PRAGMA foreign_key_check(t3)} } {}
154 do_test fkey2-1.1.$tn.5 { execsql {PRAGMA foreign_key_check(t4)} } {}
155 do_test fkey2-1.1.$tn.6 { execsql {PRAGMA foreign_key_check(t7)} } {}
156 do_test fkey2-1.1.$tn.7 { execsql {PRAGMA foreign_key_check(t8)} } {}
160 do_test fkey2-1.2.0 {
161 execsql [string map {/D/ {DEFERRABLE INITIALLY DEFERRED}} $FkeySimpleSchema]
163 foreach {tn zSql res} $FkeySimpleTests {
164 do_test fkey2-1.2.$tn { catchsql $zSql } $res
165 do_test fkey2-1.2.$tn.2 { execsql {PRAGMA foreign_key_check(t1)} } {}
166 do_test fkey2-1.2.$tn.3 { execsql {PRAGMA foreign_key_check(t2)} } {}
167 do_test fkey2-1.2.$tn.4 { execsql {PRAGMA foreign_key_check(t3)} } {}
168 do_test fkey2-1.2.$tn.5 { execsql {PRAGMA foreign_key_check(t4)} } {}
169 do_test fkey2-1.2.$tn.6 { execsql {PRAGMA foreign_key_check(t7)} } {}
170 do_test fkey2-1.2.$tn.7 { execsql {PRAGMA foreign_key_check(t8)} } {}
174 do_test fkey2-1.3.0 {
175 execsql [string map {/D/ {}} $FkeySimpleSchema]
176 execsql { PRAGMA count_changes = 1 }
178 foreach {tn zSql res} $FkeySimpleTests {
179 if {$res == "0 {}"} { set res {0 1} }
180 do_test fkey2-1.3.$tn { catchsql $zSql } $res
181 do_test fkey2-1.3.$tn.2 { execsql {PRAGMA foreign_key_check(t1)} } {}
182 do_test fkey2-1.3.$tn.3 { execsql {PRAGMA foreign_key_check(t2)} } {}
183 do_test fkey2-1.3.$tn.4 { execsql {PRAGMA foreign_key_check(t3)} } {}
184 do_test fkey2-1.3.$tn.5 { execsql {PRAGMA foreign_key_check(t4)} } {}
185 do_test fkey2-1.3.$tn.6 { execsql {PRAGMA foreign_key_check(t7)} } {}
186 do_test fkey2-1.3.$tn.7 { execsql {PRAGMA foreign_key_check(t8)} } {}
188 execsql { PRAGMA count_changes = 0 }
191 do_test fkey2-1.4.0 {
192 execsql [string map {/D/ {}} $FkeySimpleSchema]
193 execsql { PRAGMA count_changes = 1 }
195 foreach {tn zSql res} $FkeySimpleTests {
196 if {$res == "0 {}"} { set res {0 1} }
198 do_test fkey2-1.4.$tn { catchsql $zSql } $res
201 execsql { PRAGMA count_changes = 0 }
204 # Special test: When the parent key is an IPK, make sure the affinity of
205 # the IPK is not applied to the child key value before it is inserted
206 # into the child table.
207 do_test fkey2-1.5.1 {
209 CREATE TABLE i(i INTEGER PRIMARY KEY);
210 CREATE TABLE j(j REFERENCES i);
211 INSERT INTO i VALUES(35);
212 INSERT INTO j VALUES('35.0');
213 SELECT j, typeof(j) FROM j;
216 do_test fkey2-1.5.2 {
217 catchsql { DELETE FROM i }
218 } {1 {FOREIGN KEY constraint failed}}
220 # Same test using a regular primary key with integer affinity.
222 do_test fkey2-1.6.1 {
224 CREATE TABLE i(i INT UNIQUE);
225 CREATE TABLE j(j REFERENCES i(i));
226 INSERT INTO i VALUES('35.0');
227 INSERT INTO j VALUES('35.0');
228 SELECT j, typeof(j) FROM j;
229 SELECT i, typeof(i) FROM i;
231 } {35.0 text 35 integer}
232 do_test fkey2-1.6.2 {
233 catchsql { DELETE FROM i }
234 } {1 {FOREIGN KEY constraint failed}}
236 # Use a collation sequence on the parent key.
238 do_test fkey2-1.7.1 {
240 CREATE TABLE i(i TEXT COLLATE nocase PRIMARY KEY);
241 CREATE TABLE j(j TEXT COLLATE binary REFERENCES i(i));
242 INSERT INTO i VALUES('SQLite');
243 INSERT INTO j VALUES('sqlite');
245 catchsql { DELETE FROM i }
246 } {1 {FOREIGN KEY constraint failed}}
248 # Use the parent key collation even if it is default and the child key
249 # has an explicit value.
251 do_test fkey2-1.7.2 {
253 CREATE TABLE i(i TEXT PRIMARY KEY); -- Colseq is "BINARY"
254 CREATE TABLE j(j TEXT COLLATE nocase REFERENCES i(i));
255 INSERT INTO i VALUES('SQLite');
257 catchsql { INSERT INTO j VALUES('sqlite') }
258 } {1 {FOREIGN KEY constraint failed}}
259 do_test fkey2-1.7.3 {
261 INSERT INTO i VALUES('sqlite');
262 INSERT INTO j VALUES('sqlite');
263 DELETE FROM i WHERE i = 'SQLite';
265 catchsql { DELETE FROM i WHERE i = 'sqlite' }
266 } {1 {FOREIGN KEY constraint failed}}
268 #-------------------------------------------------------------------------
269 # This section (test cases fkey2-2.*) contains tests to check that the
270 # deferred foreign key constraint logic works.
272 proc fkey2-2-test {tn nocommit sql {res {}}} {
274 set expected {1 {FOREIGN KEY constraint failed}}
276 set expected [list 0 $res]
278 do_test fkey2-2.$tn [list catchsql $sql] $expected
280 do_test fkey2-2.${tn}c {
282 } {1 {FOREIGN KEY constraint failed}}
289 parent REFERENCES node DEFERRABLE INITIALLY DEFERRED
293 parent REFERENCES node DEFERRABLE INITIALLY DEFERRED
297 fkey2-2-test 1 0 "INSERT INTO node VALUES(1, 0)" FKV
298 fkey2-2-test 2 0 "BEGIN"
299 fkey2-2-test 3 1 "INSERT INTO node VALUES(1, 0)"
300 fkey2-2-test 4 0 "UPDATE node SET parent = NULL"
301 fkey2-2-test 5 0 "COMMIT"
302 fkey2-2-test 6 0 "SELECT * FROM node" {1 {}}
304 fkey2-2-test 7 0 "BEGIN"
305 fkey2-2-test 8 1 "INSERT INTO leaf VALUES('a', 2)"
306 fkey2-2-test 9 1 "INSERT INTO node VALUES(2, 0)"
307 fkey2-2-test 10 0 "UPDATE node SET parent = 1 WHERE nodeid = 2"
308 fkey2-2-test 11 0 "COMMIT"
309 fkey2-2-test 12 0 "SELECT * FROM node" {1 {} 2 1}
310 fkey2-2-test 13 0 "SELECT * FROM leaf" {a 2}
312 fkey2-2-test 14 0 "BEGIN"
313 fkey2-2-test 15 1 "DELETE FROM node WHERE nodeid = 2"
314 fkey2-2-test 16 0 "INSERT INTO node VALUES(2, NULL)"
315 fkey2-2-test 17 0 "COMMIT"
316 fkey2-2-test 18 0 "SELECT * FROM node" {1 {} 2 {}}
317 fkey2-2-test 19 0 "SELECT * FROM leaf" {a 2}
319 fkey2-2-test 20 0 "BEGIN"
320 fkey2-2-test 21 0 "INSERT INTO leaf VALUES('b', 1)"
321 fkey2-2-test 22 0 "SAVEPOINT save"
322 fkey2-2-test 23 0 "DELETE FROM node WHERE nodeid = 1"
323 fkey2-2-test 24 0 "ROLLBACK TO save"
324 fkey2-2-test 25 0 "COMMIT"
325 fkey2-2-test 26 0 "SELECT * FROM node" {1 {} 2 {}}
326 fkey2-2-test 27 0 "SELECT * FROM leaf" {a 2 b 1}
328 fkey2-2-test 28 0 "BEGIN"
329 fkey2-2-test 29 0 "INSERT INTO leaf VALUES('c', 1)"
330 fkey2-2-test 30 0 "SAVEPOINT save"
331 fkey2-2-test 31 0 "DELETE FROM node WHERE nodeid = 1"
332 fkey2-2-test 32 1 "RELEASE save"
333 fkey2-2-test 33 1 "DELETE FROM leaf WHERE cellid = 'b'"
334 fkey2-2-test 34 0 "DELETE FROM leaf WHERE cellid = 'c'"
335 fkey2-2-test 35 0 "COMMIT"
336 fkey2-2-test 36 0 "SELECT * FROM node" {2 {}}
337 fkey2-2-test 37 0 "SELECT * FROM leaf" {a 2}
339 fkey2-2-test 38 0 "SAVEPOINT outer"
340 fkey2-2-test 39 1 "INSERT INTO leaf VALUES('d', 3)"
341 fkey2-2-test 40 1 "RELEASE outer" FKV
342 fkey2-2-test 41 1 "INSERT INTO leaf VALUES('e', 3)"
343 fkey2-2-test 42 0 "INSERT INTO node VALUES(3, 2)"
344 fkey2-2-test 43 0 "RELEASE outer"
346 fkey2-2-test 44 0 "SAVEPOINT outer"
347 fkey2-2-test 45 1 "DELETE FROM node WHERE nodeid=3"
348 fkey2-2-test 47 0 "INSERT INTO node VALUES(3, 2)"
349 fkey2-2-test 48 0 "ROLLBACK TO outer"
350 fkey2-2-test 49 0 "RELEASE outer"
352 fkey2-2-test 50 0 "SAVEPOINT outer"
353 fkey2-2-test 51 1 "INSERT INTO leaf VALUES('f', 4)"
354 fkey2-2-test 52 1 "SAVEPOINT inner"
355 fkey2-2-test 53 1 "INSERT INTO leaf VALUES('g', 4)"
356 fkey2-2-test 54 1 "RELEASE outer" FKV
357 fkey2-2-test 55 1 "ROLLBACK TO inner"
358 fkey2-2-test 56 0 "COMMIT" FKV
359 fkey2-2-test 57 0 "INSERT INTO node VALUES(4, NULL)"
360 fkey2-2-test 58 0 "RELEASE outer"
361 fkey2-2-test 59 0 "SELECT * FROM node" {2 {} 3 2 4 {}}
362 fkey2-2-test 60 0 "SELECT * FROM leaf" {a 2 d 3 e 3 f 4}
364 # The following set of tests check that if a statement that affects
365 # multiple rows violates some foreign key constraints, then strikes a
366 # constraint that causes the statement-transaction to be rolled back,
367 # the deferred constraint counter is correctly reset to the value it
368 # had before the statement-transaction was opened.
370 fkey2-2-test 61 0 "BEGIN"
371 fkey2-2-test 62 0 "DELETE FROM leaf"
372 fkey2-2-test 63 0 "DELETE FROM node"
373 fkey2-2-test 64 1 "INSERT INTO leaf VALUES('a', 1)"
374 fkey2-2-test 65 1 "INSERT INTO leaf VALUES('b', 2)"
375 fkey2-2-test 66 1 "INSERT INTO leaf VALUES('c', 1)"
376 do_test fkey2-2-test-67 {
377 catchsql "INSERT INTO node SELECT parent, 3 FROM leaf"
378 } {1 {UNIQUE constraint failed: node.nodeid}}
379 fkey2-2-test 68 0 "COMMIT" FKV
380 fkey2-2-test 69 1 "INSERT INTO node VALUES(1, NULL)"
381 fkey2-2-test 70 0 "INSERT INTO node VALUES(2, NULL)"
382 fkey2-2-test 71 0 "COMMIT"
384 fkey2-2-test 72 0 "BEGIN"
385 fkey2-2-test 73 1 "DELETE FROM node"
386 fkey2-2-test 74 0 "INSERT INTO node(nodeid) SELECT DISTINCT parent FROM leaf"
387 fkey2-2-test 75 0 "COMMIT"
389 #-------------------------------------------------------------------------
390 # Test cases fkey2-3.* test that a program that executes foreign key
391 # actions (CASCADE, SET DEFAULT, SET NULL etc.) or tests FK constraints
392 # opens a statement transaction if required.
394 # fkey2-3.1.*: Test UPDATE statements.
395 # fkey2-3.2.*: Test DELETE statements.
398 do_test fkey2-3.1.1 {
400 CREATE TABLE ab(a PRIMARY KEY, b);
402 c PRIMARY KEY REFERENCES ab ON UPDATE CASCADE ON DELETE CASCADE,
406 e REFERENCES cd ON UPDATE CASCADE,
411 do_test fkey2-3.1.2 {
413 INSERT INTO ab VALUES(1, 'b');
414 INSERT INTO cd VALUES(1, 'd');
415 INSERT INTO ef VALUES(1, 'e');
418 do_test fkey2-3.1.3 {
419 catchsql { UPDATE ab SET a = 5 }
420 } {1 {CHECK constraint failed: ef}}
421 do_test fkey2-3.1.4 {
422 execsql { SELECT * FROM ab }
424 do_test fkey2-3.1.4 {
426 catchsql { UPDATE ab SET a = 5 }
427 } {1 {CHECK constraint failed: ef}}
428 do_test fkey2-3.1.5 {
430 execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef }
433 do_test fkey2-3.2.1 {
435 catchsql { DELETE FROM ab }
436 } {1 {FOREIGN KEY constraint failed}}
437 do_test fkey2-3.2.2 {
439 execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef }
442 #-------------------------------------------------------------------------
443 # Test cases fkey2-4.* test that recursive foreign key actions
444 # (i.e. CASCADE) are allowed even if recursive triggers are disabled.
451 parent REFERENCES t1 ON DELETE CASCADE
453 CREATE TABLE t2(node PRIMARY KEY, parent);
454 CREATE TRIGGER t2t AFTER DELETE ON t2 BEGIN
455 DELETE FROM t2 WHERE parent = old.node;
457 INSERT INTO t1 VALUES(1, NULL);
458 INSERT INTO t1 VALUES(2, 1);
459 INSERT INTO t1 VALUES(3, 1);
460 INSERT INTO t1 VALUES(4, 2);
461 INSERT INTO t1 VALUES(5, 2);
462 INSERT INTO t1 VALUES(6, 3);
463 INSERT INTO t1 VALUES(7, 3);
464 INSERT INTO t2 SELECT * FROM t1;
468 execsql { PRAGMA recursive_triggers = off }
471 DELETE FROM t1 WHERE node = 1;
477 DELETE FROM t2 WHERE node = 1;
483 execsql { PRAGMA recursive_triggers = on }
486 DELETE FROM t1 WHERE node = 1;
492 DELETE FROM t2 WHERE node = 1;
498 #-------------------------------------------------------------------------
499 # Test cases fkey2-5.* verify that the incremental blob API may not
500 # write to a foreign key column while foreign-keys are enabled.
506 CREATE TABLE t1(a PRIMARY KEY, b);
507 CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1(a));
508 INSERT INTO t1 VALUES('hello', 'world');
509 INSERT INTO t2 VALUES('key', 'hello');
513 set rc [catch { set fd [db incrblob t2 b 1] } msg]
515 } {1 {cannot open foreign key column for writing}}
517 set rc [catch { set fd [db incrblob -readonly t2 b 1] } msg]
522 execsql { PRAGMA foreign_keys = off }
523 set rc [catch { set fd [db incrblob t2 b 1] } msg]
528 execsql { PRAGMA foreign_keys = on }
536 CREATE TABLE t1(a REFERENCES t2(c), b);
537 CREATE TABLE t2(c UNIQUE, b);
538 INSERT INTO t2 VALUES(1, 2);
539 INSERT INTO t1 VALUES(1, 2);
545 #-------------------------------------------------------------------------
546 # Test that it is possible to use an INTEGER PRIMARY KEY as the child key
547 # of a foreign constraint.
552 CREATE TABLE t1(a PRIMARY KEY, b);
553 CREATE TABLE t2(c INTEGER PRIMARY KEY REFERENCES t1, b);
557 catchsql { INSERT INTO t2 VALUES(1, 'A'); }
558 } {1 {FOREIGN KEY constraint failed}}
561 INSERT INTO t1 VALUES(1, 2);
562 INSERT INTO t1 VALUES(2, 3);
563 INSERT INTO t2 VALUES(1, 'A');
567 execsql { UPDATE t2 SET c = 2 }
570 catchsql { UPDATE t2 SET c = 3 }
571 } {1 {FOREIGN KEY constraint failed}}
573 catchsql { DELETE FROM t1 WHERE a = 2 }
574 } {1 {FOREIGN KEY constraint failed}}
576 execsql { DELETE FROM t1 WHERE a = 1 }
579 catchsql { UPDATE t1 SET a = 3 }
580 } {1 {FOREIGN KEY constraint failed}}
582 catchsql { UPDATE t2 SET rowid = 3 }
583 } {1 {FOREIGN KEY constraint failed}}
585 #-------------------------------------------------------------------------
586 # Test that it is not possible to enable/disable FK support while a
587 # transaction is open.
590 proc fkey2-8-test {tn zSql value} {
591 do_test fkey-2.8.$tn.1 [list execsql $zSql] {}
592 do_test fkey-2.8.$tn.2 { execsql "PRAGMA foreign_keys" } $value
594 fkey2-8-test 1 { PRAGMA foreign_keys = 0 } 0
595 fkey2-8-test 2 { PRAGMA foreign_keys = 1 } 1
596 fkey2-8-test 3 { BEGIN } 1
597 fkey2-8-test 4 { PRAGMA foreign_keys = 0 } 1
598 fkey2-8-test 5 { COMMIT } 1
599 fkey2-8-test 6 { PRAGMA foreign_keys = 0 } 0
600 fkey2-8-test 7 { BEGIN } 0
601 fkey2-8-test 8 { PRAGMA foreign_keys = 1 } 0
602 fkey2-8-test 9 { COMMIT } 0
603 fkey2-8-test 10 { PRAGMA foreign_keys = 1 } 1
604 fkey2-8-test 11 { PRAGMA foreign_keys = off } 0
605 fkey2-8-test 12 { PRAGMA foreign_keys = on } 1
606 fkey2-8-test 13 { PRAGMA foreign_keys = no } 0
607 fkey2-8-test 14 { PRAGMA foreign_keys = yes } 1
608 fkey2-8-test 15 { PRAGMA foreign_keys = false } 0
609 fkey2-8-test 16 { PRAGMA foreign_keys = true } 1
611 #-------------------------------------------------------------------------
612 # The following tests, fkey2-9.*, test SET DEFAULT actions.
615 do_test fkey2-9.1.1 {
617 CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
619 c INTEGER PRIMARY KEY,
620 d INTEGER DEFAULT 1 REFERENCES t1 ON DELETE SET DEFAULT
625 do_test fkey2-9.1.2 {
627 INSERT INTO t1 VALUES(1, 'one');
628 INSERT INTO t1 VALUES(2, 'two');
629 INSERT INTO t2 VALUES(1, 2);
631 DELETE FROM t1 WHERE a = 2;
635 do_test fkey2-9.1.3 {
637 INSERT INTO t1 VALUES(2, 'two');
639 DELETE FROM t1 WHERE a = 1;
643 do_test fkey2-9.1.4 {
644 execsql { SELECT * FROM t1 }
646 do_test fkey2-9.1.5 {
647 catchsql { DELETE FROM t1 }
648 } {1 {FOREIGN KEY constraint failed}}
650 do_test fkey2-9.2.1 {
652 CREATE TABLE pp(a, b, c, PRIMARY KEY(b, c));
653 CREATE TABLE cc(d DEFAULT 3, e DEFAULT 1, f DEFAULT 2,
654 FOREIGN KEY(f, d) REFERENCES pp
655 ON UPDATE SET DEFAULT
658 INSERT INTO pp VALUES(1, 2, 3);
659 INSERT INTO pp VALUES(4, 5, 6);
660 INSERT INTO pp VALUES(7, 8, 9);
663 do_test fkey2-9.2.2 {
665 INSERT INTO cc VALUES(6, 'A', 5);
666 INSERT INTO cc VALUES(6, 'B', 5);
667 INSERT INTO cc VALUES(9, 'A', 8);
668 INSERT INTO cc VALUES(9, 'B', 8);
669 UPDATE pp SET b = 1 WHERE a = 7;
672 } {6 A 5 6 B 5 3 A 2 3 B 2}
673 do_test fkey2-9.2.3 {
675 DELETE FROM pp WHERE a = 4;
678 } {{} A {} {} B {} 3 A 2 3 B 2}
679 do_execsql_test fkey2-9.3.0 {
680 CREATE TABLE t3(x PRIMARY KEY REFERENCES t3 ON DELETE SET NULL);
681 INSERT INTO t3(x) VALUES(12345);
685 #-------------------------------------------------------------------------
686 # The following tests, fkey2-10.*, test "foreign key mismatch" and
691 CREATE TABLE p(a PRIMARY KEY, b);
692 CREATE TABLE c(x REFERENCES p(c));
694 CREATE TABLE c(x REFERENCES v(y));
695 CREATE VIEW v AS SELECT x AS y FROM c;
697 CREATE TABLE p(a, b, PRIMARY KEY(a, b));
698 CREATE TABLE c(x REFERENCES p);
700 CREATE TABLE p(a COLLATE binary, b);
701 CREATE UNIQUE INDEX i ON p(a COLLATE nocase);
702 CREATE TABLE c(x REFERENCES p(a));
705 do_test fkey2-10.1.[incr tn] {
707 catchsql { INSERT INTO c DEFAULT VALUES }
708 } {/1 {foreign key mismatch - "c" referencing "."}/}
711 # "rowid" cannot be used as part of a child or parent key definition
712 # unless it happens to be the name of an explicitly declared column.
714 do_test fkey2-10.2.1 {
717 CREATE TABLE t1(a PRIMARY KEY, b);
718 CREATE TABLE t2(c, d, FOREIGN KEY(rowid) REFERENCES t1(a));
720 } {1 {unknown column "rowid" in foreign key definition}}
721 do_test fkey2-10.2.2 {
724 CREATE TABLE t1(a PRIMARY KEY, b);
725 CREATE TABLE t2(rowid, d, FOREIGN KEY(rowid) REFERENCES t1(a));
728 do_test fkey2-10.2.1 {
731 CREATE TABLE t1(a, b);
732 CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(rowid));
733 INSERT INTO t1(rowid, a, b) VALUES(1, 1, 1);
734 INSERT INTO t2 VALUES(1, 1);
736 } {1 {foreign key mismatch - "t2" referencing "t1"}}
737 do_test fkey2-10.2.2 {
740 CREATE TABLE t1(rowid PRIMARY KEY, b);
741 CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(rowid));
742 INSERT INTO t1(rowid, b) VALUES(1, 1);
743 INSERT INTO t2 VALUES(1, 1);
748 #-------------------------------------------------------------------------
749 # The following tests, fkey2-11.*, test CASCADE actions.
752 do_test fkey2-11.1.1 {
754 CREATE TABLE t1(a INTEGER PRIMARY KEY, b, rowid, _rowid_, oid);
755 CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(a) ON UPDATE CASCADE);
757 INSERT INTO t1 VALUES(10, 100, 'abc', 'def', 'ghi');
758 INSERT INTO t2 VALUES(10, 100);
759 UPDATE t1 SET a = 15;
764 #-------------------------------------------------------------------------
765 # The following tests, fkey2-12.*, test RESTRICT actions.
768 do_test fkey2-12.1.1 {
770 CREATE TABLE t1(a, b PRIMARY KEY);
772 x REFERENCES t1 ON UPDATE RESTRICT DEFERRABLE INITIALLY DEFERRED
774 INSERT INTO t1 VALUES(1, 'one');
775 INSERT INTO t1 VALUES(2, 'two');
776 INSERT INTO t1 VALUES(3, 'three');
779 do_test fkey2-12.1.2 {
781 execsql "INSERT INTO t2 VALUES('two')"
783 do_test fkey2-12.1.3 {
784 execsql "UPDATE t1 SET b = 'four' WHERE b = 'one'"
786 do_test fkey2-12.1.4 {
787 catchsql "UPDATE t1 SET b = 'five' WHERE b = 'two'"
788 } {1 {FOREIGN KEY constraint failed}}
789 do_test fkey2-12.1.5 {
790 execsql "DELETE FROM t1 WHERE b = 'two'"
792 do_test fkey2-12.1.6 {
794 } {1 {FOREIGN KEY constraint failed}}
795 do_test fkey2-12.1.7 {
797 INSERT INTO t1 VALUES(2, 'two');
803 do_test fkey2-12.2.1 {
805 CREATE TABLE t1(x COLLATE NOCASE PRIMARY KEY);
806 CREATE TRIGGER tt1 AFTER DELETE ON t1
807 WHEN EXISTS ( SELECT 1 FROM t2 WHERE old.x = y )
809 INSERT INTO t1 VALUES(old.x);
811 CREATE TABLE t2(y REFERENCES t1);
812 INSERT INTO t1 VALUES('A');
813 INSERT INTO t1 VALUES('B');
814 INSERT INTO t2 VALUES('a');
815 INSERT INTO t2 VALUES('b');
821 do_test fkey2-12.2.2 {
822 execsql { DELETE FROM t1 }
828 do_test fkey2-12.2.3 {
831 CREATE TABLE t2(y REFERENCES t1 ON DELETE RESTRICT);
832 INSERT INTO t2 VALUES('a');
833 INSERT INTO t2 VALUES('b');
835 catchsql { DELETE FROM t1 }
836 } {1 {FOREIGN KEY constraint failed}}
837 do_test fkey2-12.2.4 {
845 do_test fkey2-12.3.1 {
848 c00, c01, c02, c03, c04, c05, c06, c07, c08, c09,
849 c10, c11, c12, c13, c14, c15, c16, c17, c18, c19,
850 c20, c21, c22, c23, c24, c25, c26, c27, c28, c29,
851 c30, c31, c32, c33, c34, c35, c36, c37, c38, c39,
852 PRIMARY KEY(c34, c35)
855 c00, c01, c02, c03, c04, c05, c06, c07, c08, c09,
856 c10, c11, c12, c13, c14, c15, c16, c17, c18, c19,
857 c20, c21, c22, c23, c24, c25, c26, c27, c28, c29,
858 c30, c31, c32, c33, c34, c35, c36, c37, c38, c39,
859 FOREIGN KEY(c39, c38) REFERENCES up ON UPDATE CASCADE
863 do_test fkey2-12.3.2 {
865 INSERT INTO up(c34, c35) VALUES('yes', 'no');
866 INSERT INTO down(c39, c38) VALUES('yes', 'no');
867 UPDATE up SET c34 = 'possibly';
868 SELECT c38, c39 FROM down;
872 do_test fkey2-12.3.3 {
873 catchsql { INSERT INTO down(c39, c38) VALUES('yes', 'no') }
874 } {1 {FOREIGN KEY constraint failed}}
875 do_test fkey2-12.3.4 {
877 INSERT INTO up(c34, c35) VALUES('yes', 'no');
878 INSERT INTO down(c39, c38) VALUES('yes', 'no');
880 catchsql { DELETE FROM up WHERE c34 = 'yes' }
881 } {1 {FOREIGN KEY constraint failed}}
882 do_test fkey2-12.3.5 {
884 DELETE FROM up WHERE c34 = 'possibly';
885 SELECT c34, c35 FROM up;
886 SELECT c39, c38 FROM down;
890 #-------------------------------------------------------------------------
891 # The following tests, fkey2-13.*, test that FK processing is performed
892 # when rows are REPLACEd.
895 do_test fkey2-13.1.1 {
897 CREATE TABLE pp(a UNIQUE, b, c, PRIMARY KEY(b, c));
898 CREATE TABLE cc(d, e, f UNIQUE, FOREIGN KEY(d, e) REFERENCES pp);
899 INSERT INTO pp VALUES(1, 2, 3);
900 INSERT INTO cc VALUES(2, 3, 1);
904 1 "REPLACE INTO pp VALUES(1, 4, 5)"
905 2 "REPLACE INTO pp(rowid, a, b, c) VALUES(1, 2, 3, 4)"
907 do_test fkey2-13.1.$tn.1 {
909 } {1 {FOREIGN KEY constraint failed}}
910 do_test fkey2-13.1.$tn.2 {
916 do_test fkey2-13.1.$tn.3 {
919 } {1 {FOREIGN KEY constraint failed}}
920 do_test fkey2-13.1.$tn.4 {
928 do_test fkey2-13.1.3 {
930 REPLACE INTO pp(rowid, a, b, c) VALUES(1, 2, 2, 3);
931 SELECT rowid, * FROM pp;
935 do_test fkey2-13.1.4 {
937 REPLACE INTO pp(rowid, a, b, c) VALUES(2, 2, 2, 3);
938 SELECT rowid, * FROM pp;
943 #-------------------------------------------------------------------------
944 # The following tests, fkey2-14.*, test that the "DROP TABLE" and "ALTER
945 # TABLE" commands work as expected wrt foreign key constraints.
947 # fkey2-14.1*: ALTER TABLE ADD COLUMN
948 # fkey2-14.2*: ALTER TABLE RENAME TABLE
949 # fkey2-14.3*: DROP TABLE
952 ifcapable altertable {
953 do_test fkey2-14.1.1 {
954 # Adding a column with a REFERENCES clause is not supported.
956 CREATE TABLE t1(a PRIMARY KEY);
957 CREATE TABLE t2(a, b);
959 catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
961 do_test fkey2-14.1.2 {
962 catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
964 do_test fkey2-14.1.3 {
965 catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}
967 do_test fkey2-14.1.4 {
968 catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'}
969 } {1 {Cannot add a REFERENCES column with non-NULL default value}}
970 do_test fkey2-14.1.5 {
971 catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 }
972 } {1 {Cannot add a REFERENCES column with non-NULL default value}}
973 do_test fkey2-14.1.6 {
975 PRAGMA foreign_keys = off;
976 ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
977 PRAGMA foreign_keys = on;
978 SELECT sql FROM sqlite_master WHERE name='t2';
980 } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
983 # Test the sqlite_rename_parent() function directly.
985 proc test_rename_parent {zCreate zOld zNew} {
986 db eval {SELECT sqlite_rename_table(
987 'main', 'table', 't1', $zCreate, $zOld, $zNew, 0
990 sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1
991 do_test fkey2-14.2.1.1 {
992 test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
993 } {{CREATE TABLE t1(a REFERENCES "t3")}}
994 do_test fkey2-14.2.1.2 {
995 test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
996 } {{CREATE TABLE t1(a REFERENCES t2)}}
997 do_test fkey2-14.2.1.3 {
998 test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
999 } {{CREATE TABLE t1(a REFERENCES "t3")}}
1000 sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0
1002 # Test ALTER TABLE RENAME TABLE a bit.
1004 do_test fkey2-14.2.2.1 {
1007 CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1);
1008 CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2);
1009 CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
1011 execsql { SELECT sql FROM sqlite_master WHERE type = 'table'}
1013 {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1)} \
1014 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)} \
1015 {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)} \
1017 do_test fkey2-14.2.2.2 {
1018 execsql { ALTER TABLE t1 RENAME TO t4 }
1019 execsql { SELECT sql FROM sqlite_master WHERE type = 'table'}
1021 {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4")} \
1022 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)} \
1023 {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \
1025 do_test fkey2-14.2.2.3 {
1026 catchsql { INSERT INTO t3 VALUES(1, 2, 3) }
1027 } {1 {FOREIGN KEY constraint failed}}
1028 do_test fkey2-14.2.2.4 {
1029 execsql { INSERT INTO t4 VALUES(1, NULL) }
1031 do_test fkey2-14.2.2.5 {
1032 catchsql { UPDATE t4 SET b = 5 }
1033 } {1 {FOREIGN KEY constraint failed}}
1034 do_test fkey2-14.2.2.6 {
1035 catchsql { UPDATE t4 SET b = 1 }
1037 do_test fkey2-14.2.2.7 {
1038 execsql { INSERT INTO t3 VALUES(1, NULL, 1) }
1041 # Repeat for TEMP tables
1044 do_test fkey2-14.1tmp.1 {
1045 # Adding a column with a REFERENCES clause is not supported.
1047 CREATE TEMP TABLE t1(a PRIMARY KEY);
1048 CREATE TEMP TABLE t2(a, b);
1050 catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
1052 do_test fkey2-14.1tmp.2 {
1053 catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
1055 do_test fkey2-14.1tmp.3 {
1056 catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}
1058 do_test fkey2-14.1tmp.4 {
1059 catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'}
1060 } {1 {Cannot add a REFERENCES column with non-NULL default value}}
1061 do_test fkey2-14.1tmp.5 {
1062 catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 }
1063 } {1 {Cannot add a REFERENCES column with non-NULL default value}}
1064 do_test fkey2-14.1tmp.6 {
1066 PRAGMA foreign_keys = off;
1067 ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
1068 PRAGMA foreign_keys = on;
1069 SELECT sql FROM temp.sqlite_master WHERE name='t2';
1071 } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
1073 sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1
1074 do_test fkey2-14.2tmp.1.1 {
1075 test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
1076 } {{CREATE TABLE t1(a REFERENCES "t3")}}
1077 do_test fkey2-14.2tmp.1.2 {
1078 test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
1079 } {{CREATE TABLE t1(a REFERENCES t2)}}
1080 do_test fkey2-14.2tmp.1.3 {
1081 test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
1082 } {{CREATE TABLE t1(a REFERENCES "t3")}}
1083 sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0
1085 # Test ALTER TABLE RENAME TABLE a bit.
1087 do_test fkey2-14.2tmp.2.1 {
1090 CREATE TEMP TABLE t1(a PRIMARY KEY, b REFERENCES t1);
1091 CREATE TEMP TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2);
1092 CREATE TEMP TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
1094 execsql { SELECT sql FROM sqlite_temp_master WHERE type = 'table'}
1096 {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1)} \
1097 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)} \
1098 {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)} \
1100 do_test fkey2-14.2tmp.2.2 {
1101 execsql { ALTER TABLE t1 RENAME TO t4 }
1102 execsql { SELECT sql FROM temp.sqlite_master WHERE type = 'table'}
1104 {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4")} \
1105 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)} \
1106 {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \
1108 do_test fkey2-14.2tmp.2.3 {
1109 catchsql { INSERT INTO t3 VALUES(1, 2, 3) }
1110 } {1 {FOREIGN KEY constraint failed}}
1111 do_test fkey2-14.2tmp.2.4 {
1112 execsql { INSERT INTO t4 VALUES(1, NULL) }
1114 do_test fkey2-14.2tmp.2.5 {
1115 catchsql { UPDATE t4 SET b = 5 }
1116 } {1 {FOREIGN KEY constraint failed}}
1117 do_test fkey2-14.2tmp.2.6 {
1118 catchsql { UPDATE t4 SET b = 1 }
1120 do_test fkey2-14.2tmp.2.7 {
1121 execsql { INSERT INTO t3 VALUES(1, NULL, 1) }
1124 # Repeat for ATTACH-ed tables
1127 do_test fkey2-14.1aux.1 {
1128 # Adding a column with a REFERENCES clause is not supported.
1130 ATTACH ':memory:' AS aux;
1131 CREATE TABLE aux.t1(a PRIMARY KEY);
1132 CREATE TABLE aux.t2(a, b);
1134 catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
1136 do_test fkey2-14.1aux.2 {
1137 catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
1139 do_test fkey2-14.1aux.3 {
1140 catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}
1142 do_test fkey2-14.1aux.4 {
1143 catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'}
1144 } {1 {Cannot add a REFERENCES column with non-NULL default value}}
1145 do_test fkey2-14.1aux.5 {
1146 catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 }
1147 } {1 {Cannot add a REFERENCES column with non-NULL default value}}
1148 do_test fkey2-14.1aux.6 {
1150 PRAGMA foreign_keys = off;
1151 ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
1152 PRAGMA foreign_keys = on;
1153 SELECT sql FROM aux.sqlite_master WHERE name='t2';
1155 } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
1157 sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 1
1158 do_test fkey2-14.2aux.1.1 {
1159 test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
1160 } {{CREATE TABLE t1(a REFERENCES "t3")}}
1161 do_test fkey2-14.2aux.1.2 {
1162 test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
1163 } {{CREATE TABLE t1(a REFERENCES t2)}}
1164 do_test fkey2-14.2aux.1.3 {
1165 test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
1166 } {{CREATE TABLE t1(a REFERENCES "t3")}}
1167 sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 0
1169 # Test ALTER TABLE RENAME TABLE a bit.
1171 do_test fkey2-14.2aux.2.1 {
1174 CREATE TABLE aux.t1(a PRIMARY KEY, b REFERENCES t1);
1175 CREATE TABLE aux.t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2);
1176 CREATE TABLE aux.t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
1178 execsql { SELECT sql FROM aux.sqlite_master WHERE type = 'table'}
1180 {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1)} \
1181 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)} \
1182 {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)} \
1184 do_test fkey2-14.2aux.2.2 {
1185 execsql { ALTER TABLE t1 RENAME TO t4 }
1186 execsql { SELECT sql FROM aux.sqlite_master WHERE type = 'table'}
1188 {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4")} \
1189 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)} \
1190 {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \
1192 do_test fkey2-14.2aux.2.3 {
1193 catchsql { INSERT INTO t3 VALUES(1, 2, 3) }
1194 } {1 {FOREIGN KEY constraint failed}}
1195 do_test fkey2-14.2aux.2.4 {
1196 execsql { INSERT INTO t4 VALUES(1, NULL) }
1198 do_test fkey2-14.2aux.2.5 {
1199 catchsql { UPDATE t4 SET b = 5 }
1200 } {1 {FOREIGN KEY constraint failed}}
1201 do_test fkey2-14.2aux.2.6 {
1202 catchsql { UPDATE t4 SET b = 1 }
1204 do_test fkey2-14.2aux.2.7 {
1205 execsql { INSERT INTO t3 VALUES(1, NULL, 1) }
1209 do_test fkey-2.14.3.1 {
1212 CREATE TABLE t1(a, b REFERENCES nosuchtable);
1216 do_test fkey-2.14.3.2 {
1218 CREATE TABLE t1(a PRIMARY KEY, b);
1219 INSERT INTO t1 VALUES('a', 1);
1220 CREATE TABLE t2(x REFERENCES t1);
1221 INSERT INTO t2 VALUES('a');
1224 do_test fkey-2.14.3.3 {
1225 catchsql { DROP TABLE t1 }
1226 } {1 {FOREIGN KEY constraint failed}}
1227 do_test fkey-2.14.3.4 {
1233 do_test fkey-2.14.3.4 {
1234 catchsql { INSERT INTO t2 VALUES('x') }
1235 } {1 {no such table: main.t1}}
1236 do_test fkey-2.14.3.5 {
1238 CREATE TABLE t1(x PRIMARY KEY);
1239 INSERT INTO t1 VALUES('x');
1241 execsql { INSERT INTO t2 VALUES('x') }
1243 do_test fkey-2.14.3.6 {
1244 catchsql { DROP TABLE t1 }
1245 } {1 {FOREIGN KEY constraint failed}}
1246 do_test fkey-2.14.3.7 {
1252 do_test fkey-2.14.3.8 {
1254 CREATE TABLE pp(x, y, PRIMARY KEY(x, y));
1255 CREATE TABLE cc(a, b, FOREIGN KEY(a, b) REFERENCES pp(x, z));
1257 catchsql { INSERT INTO cc VALUES(1, 2) }
1258 } {1 {foreign key mismatch - "cc" referencing "pp"}}
1259 do_test fkey-2.14.3.9 {
1260 execsql { DROP TABLE cc }
1262 do_test fkey-2.14.3.10 {
1264 CREATE TABLE cc(a, b,
1265 FOREIGN KEY(a, b) REFERENCES pp DEFERRABLE INITIALLY DEFERRED
1269 INSERT INTO pp VALUES('a', 'b');
1270 INSERT INTO cc VALUES('a', 'b');
1273 CREATE TABLE pp(a, b, c, PRIMARY KEY(b, c));
1274 INSERT INTO pp VALUES(1, 'a', 'b');
1278 do_test fkey-2.14.3.11 {
1286 do_test fkey-2.14.3.12 {
1288 CREATE TABLE b1(a, b);
1289 CREATE TABLE b2(a, b REFERENCES b1);
1293 do_test fkey-2.14.3.13 {
1295 CREATE TABLE b3(a, b REFERENCES b2 DEFERRABLE INITIALLY DEFERRED);
1300 # Test that nothing goes wrong when dropping a table that refers to a view.
1301 # Or dropping a view that an existing FK (incorrectly) refers to. Or either
1302 # of the above scenarios with a virtual table.
1304 do_test fkey-2.14.4.1 {
1306 CREATE TABLE t1(x REFERENCES v);
1307 CREATE VIEW v AS SELECT * FROM t1;
1310 do_test fkey-2.14.4.2 {
1316 register_echo_module db
1317 do_test fkey-2.14.4.3 {
1318 execsql { CREATE VIRTUAL TABLE v USING echo(t1) }
1320 do_test fkey-2.14.4.2 {
1327 #-------------------------------------------------------------------------
1328 # The following tests, fkey2-15.*, test that unnecessary FK related scans
1329 # and lookups are avoided when the constraint counters are zero.
1332 proc execsqlS {zSql} {
1333 set ::sqlite_search_count 0
1334 set ::sqlite_found_count 0
1335 set res [uplevel [list execsql $zSql]]
1336 concat [expr $::sqlite_found_count + $::sqlite_search_count] $res
1338 do_test fkey2-15.1.1 {
1340 CREATE TABLE pp(a PRIMARY KEY, b);
1341 CREATE TABLE cc(x, y REFERENCES pp DEFERRABLE INITIALLY DEFERRED);
1342 INSERT INTO pp VALUES(1, 'one');
1343 INSERT INTO pp VALUES(2, 'two');
1344 INSERT INTO cc VALUES('neung', 1);
1345 INSERT INTO cc VALUES('song', 2);
1348 do_test fkey2-15.1.2 {
1349 execsqlS { INSERT INTO pp VALUES(3, 'three') }
1351 do_test fkey2-15.1.3 {
1354 INSERT INTO cc VALUES('see', 4); -- Violates deferred constraint
1356 execsqlS { INSERT INTO pp VALUES(5, 'five') }
1358 do_test fkey2-15.1.4 {
1359 execsql { DELETE FROM cc WHERE x = 'see' }
1360 execsqlS { INSERT INTO pp VALUES(6, 'six') }
1362 do_test fkey2-15.1.5 {
1365 do_test fkey2-15.1.6 {
1368 DELETE FROM cc WHERE x = 'neung';
1372 do_test fkey2-15.1.7 {
1375 DELETE FROM pp WHERE a = 2;
1378 DELETE FROM cc WHERE x = 'neung';
1383 #-------------------------------------------------------------------------
1384 # This next block of tests, fkey2-16.*, test that rows that refer to
1385 # themselves may be inserted and deleted.
1387 foreach {tn zSchema} {
1388 1 { CREATE TABLE self(a INTEGER PRIMARY KEY, b REFERENCES self(a)) }
1389 2 { CREATE TABLE self(a PRIMARY KEY, b REFERENCES self(a)) }
1390 3 { CREATE TABLE self(a UNIQUE, b INTEGER PRIMARY KEY REFERENCES self(a)) }
1393 do_test fkey2-16.1.$tn.1 {
1395 execsql { INSERT INTO self VALUES(13, 13) }
1397 do_test fkey2-16.1.$tn.2 {
1398 execsql { UPDATE self SET a = 14, b = 14 }
1401 do_test fkey2-16.1.$tn.3 {
1402 catchsql { UPDATE self SET b = 15 }
1403 } {1 {FOREIGN KEY constraint failed}}
1405 do_test fkey2-16.1.$tn.4 {
1406 catchsql { UPDATE self SET a = 15 }
1407 } {1 {FOREIGN KEY constraint failed}}
1409 do_test fkey2-16.1.$tn.5 {
1410 catchsql { UPDATE self SET a = 15, b = 16 }
1411 } {1 {FOREIGN KEY constraint failed}}
1413 do_test fkey2-16.1.$tn.6 {
1414 catchsql { UPDATE self SET a = 17, b = 17 }
1417 do_test fkey2-16.1.$tn.7 {
1418 execsql { DELETE FROM self }
1420 do_test fkey2-16.1.$tn.8 {
1421 catchsql { INSERT INTO self VALUES(20, 21) }
1422 } {1 {FOREIGN KEY constraint failed}}
1425 #-------------------------------------------------------------------------
1426 # This next block of tests, fkey2-17.*, tests that if "PRAGMA count_changes"
1427 # is turned on statements that violate immediate FK constraints return
1428 # SQLITE_CONSTRAINT immediately, not after returning a number of rows.
1429 # Whereas statements that violate deferred FK constraints return the number
1430 # of rows before failing.
1432 # Also test that rows modified by FK actions are not counted in either the
1433 # returned row count or the values returned by sqlite3_changes(). Like
1434 # trigger related changes, they are included in sqlite3_total_changes() though.
1437 do_test fkey2-17.1.1 {
1438 execsql { PRAGMA count_changes = 1 }
1440 CREATE TABLE one(a, b, c, UNIQUE(b, c));
1441 CREATE TABLE two(d, e, f, FOREIGN KEY(e, f) REFERENCES one(b, c));
1442 INSERT INTO one VALUES(1, 2, 3);
1445 do_test fkey2-17.1.2 {
1446 set STMT [sqlite3_prepare_v2 db "INSERT INTO two VALUES(4, 5, 6)" -1 dummy]
1448 } {SQLITE_CONSTRAINT}
1449 verify_ex_errcode fkey2-17.1.2b SQLITE_CONSTRAINT_FOREIGNKEY
1450 ifcapable autoreset {
1451 do_test fkey2-17.1.3 {
1453 } {SQLITE_CONSTRAINT}
1454 verify_ex_errcode fkey2-17.1.3b SQLITE_CONSTRAINT_FOREIGNKEY
1456 do_test fkey2-17.1.3 {
1460 do_test fkey2-17.1.4 {
1461 sqlite3_finalize $STMT
1462 } {SQLITE_CONSTRAINT}
1463 verify_ex_errcode fkey2-17.1.4b SQLITE_CONSTRAINT_FOREIGNKEY
1464 do_test fkey2-17.1.5 {
1466 INSERT INTO one VALUES(2, 3, 4);
1467 INSERT INTO one VALUES(3, 4, 5);
1468 INSERT INTO two VALUES(1, 2, 3);
1469 INSERT INTO two VALUES(2, 3, 4);
1470 INSERT INTO two VALUES(3, 4, 5);
1473 do_test fkey2-17.1.6 {
1476 INSERT INTO one VALUES(0, 0, 0);
1477 UPDATE two SET e=e+1, f=f+1;
1479 } {1 {FOREIGN KEY constraint failed}}
1480 do_test fkey2-17.1.7 {
1481 execsql { SELECT * FROM one }
1482 } {1 2 3 2 3 4 3 4 5 0 0 0}
1483 do_test fkey2-17.1.8 {
1484 execsql { SELECT * FROM two }
1485 } {1 2 3 2 3 4 3 4 5}
1486 do_test fkey2-17.1.9 {
1489 do_test fkey2-17.1.10 {
1493 FOREIGN KEY(h, i) REFERENCES one(b, c) DEFERRABLE INITIALLY DEFERRED
1497 do_test fkey2-17.1.11 {
1498 set STMT [sqlite3_prepare_v2 db "INSERT INTO three VALUES(7, 8, 9)" -1 dummy]
1501 do_test fkey2-17.1.12 {
1502 sqlite3_column_text $STMT 0
1504 do_test fkey2-17.1.13 {
1506 } {SQLITE_CONSTRAINT}
1507 verify_ex_errcode fkey2-17.1.13b SQLITE_CONSTRAINT_FOREIGNKEY
1508 do_test fkey2-17.1.14 {
1509 sqlite3_finalize $STMT
1510 } {SQLITE_CONSTRAINT}
1511 verify_ex_errcode fkey2-17.1.14b SQLITE_CONSTRAINT_FOREIGNKEY
1514 do_test fkey2-17.2.1 {
1516 CREATE TABLE high("a'b!" PRIMARY KEY, b);
1519 "d&6" REFERENCES high ON UPDATE CASCADE ON DELETE CASCADE
1523 do_test fkey2-17.2.2 {
1525 INSERT INTO high VALUES('a', 'b');
1526 INSERT INTO low VALUES('b', 'a');
1530 set nTotal [db total_changes]
1531 do_test fkey2-17.2.3 {
1532 execsql { UPDATE high SET "a'b!" = 'c' }
1534 do_test fkey2-17.2.4 {
1537 do_test fkey2-17.2.5 {
1538 expr [db total_changes] - $nTotal
1540 do_test fkey2-17.2.6 {
1541 execsql { SELECT * FROM high ; SELECT * FROM low }
1543 do_test fkey2-17.2.7 {
1544 execsql { DELETE FROM high }
1546 do_test fkey2-17.2.8 {
1549 do_test fkey2-17.2.9 {
1550 expr [db total_changes] - $nTotal
1552 do_test fkey2-17.2.10 {
1553 execsql { SELECT * FROM high ; SELECT * FROM low }
1555 execsql { PRAGMA count_changes = 0 }
1557 #-------------------------------------------------------------------------
1558 # Test that the authorization callback works.
1562 do_test fkey2-18.1 {
1564 CREATE TABLE long(a, b PRIMARY KEY, c);
1565 CREATE TABLE short(d, e, f REFERENCES long);
1566 CREATE TABLE mid(g, h, i REFERENCES long DEFERRABLE INITIALLY DEFERRED);
1570 proc auth {args} {eval lappend ::authargs [lrange $args 0 4]; return SQLITE_OK}
1573 # An insert on the parent table must read the child key of any deferred
1574 # foreign key constraints. But not the child key of immediate constraints.
1576 do_test fkey2-18.2 {
1577 execsql { INSERT INTO long VALUES(1, 2, 3) }
1579 } {SQLITE_INSERT long {} main {} SQLITE_READ mid i main {}}
1581 # An insert on the child table of an immediate constraint must read the
1582 # parent key columns (to see if it is a violation or not).
1584 do_test fkey2-18.3 {
1585 execsql { INSERT INTO short VALUES(1, 3, 2) }
1587 } {SQLITE_INSERT short {} main {} SQLITE_READ long b main {}}
1589 # As must an insert on the child table of a deferred constraint.
1591 do_test fkey2-18.4 {
1592 execsql { INSERT INTO mid VALUES(1, 3, 2) }
1594 } {SQLITE_INSERT mid {} main {} SQLITE_READ long b main {}}
1596 do_test fkey2-18.5 {
1598 CREATE TABLE nought(a, b PRIMARY KEY, c);
1599 CREATE TABLE cross(d, e, f,
1600 FOREIGN KEY(e) REFERENCES nought(b) ON UPDATE CASCADE
1603 execsql { INSERT INTO nought VALUES(2, 1, 2) }
1604 execsql { INSERT INTO cross VALUES(0, 1, 0) }
1606 execsql { UPDATE nought SET b = 5 }
1608 } {SQLITE_UPDATE nought b main {} SQLITE_READ cross e main {} SQLITE_READ cross e main {} SQLITE_READ nought b main {} SQLITE_READ nought b main {} SQLITE_READ nought b main {} SQLITE_UPDATE cross e main {} SQLITE_READ nought b main {} SQLITE_READ cross e main {} SQLITE_READ nought b main {} SQLITE_READ nought b main {}}
1610 do_test fkey2-18.6 {
1611 execsql {SELECT * FROM cross}
1614 do_test fkey2-18.7 {
1616 CREATE TABLE one(a INTEGER PRIMARY KEY, b);
1617 CREATE TABLE two(b, c REFERENCES one);
1618 INSERT INTO one VALUES(101, 102);
1621 execsql { INSERT INTO two VALUES(100, 101); }
1623 } {SQLITE_INSERT two {} main {} SQLITE_READ one a main {}}
1625 # Return SQLITE_IGNORE to requests to read from the parent table. This
1626 # causes inserts of non-NULL keys into the child table to fail.
1630 if {[lindex $args 1] == "long"} {return SQLITE_IGNORE}
1633 do_test fkey2-18.8 {
1634 catchsql { INSERT INTO short VALUES(1, 3, 2) }
1635 } {1 {FOREIGN KEY constraint failed}}
1636 do_test fkey2-18.9 {
1637 execsql { INSERT INTO short VALUES(1, 3, NULL) }
1639 do_test fkey2-18.10 {
1640 execsql { SELECT * FROM short }
1642 do_test fkey2-18.11 {
1643 catchsql { UPDATE short SET f = 2 WHERE f IS NULL }
1644 } {1 {FOREIGN KEY constraint failed}}
1651 do_test fkey2-19.1 {
1653 CREATE TABLE main(id INTEGER PRIMARY KEY);
1654 CREATE TABLE sub(id INT REFERENCES main(id));
1655 INSERT INTO main VALUES(1);
1656 INSERT INTO main VALUES(2);
1657 INSERT INTO sub VALUES(2);
1660 do_test fkey2-19.2 {
1661 set S [sqlite3_prepare_v2 db "DELETE FROM main WHERE id = ?" -1 dummy]
1662 sqlite3_bind_int $S 1 2
1664 } {SQLITE_CONSTRAINT}
1665 verify_ex_errcode fkey2-19.2b SQLITE_CONSTRAINT_FOREIGNKEY
1666 do_test fkey2-19.3 {
1668 } {SQLITE_CONSTRAINT}
1669 verify_ex_errcode fkey2-19.3b SQLITE_CONSTRAINT_FOREIGNKEY
1670 do_test fkey2-19.4 {
1671 sqlite3_bind_int $S 1 1
1674 do_test fkey2-19.4 {
1679 do_test fkey2-20.1 {
1681 CREATE TABLE pp(a PRIMARY KEY, b);
1682 CREATE TABLE cc(c PRIMARY KEY, d REFERENCES pp);
1686 foreach {tn insert} {
1688 2 "INSERT OR IGNORE"
1690 4 "INSERT OR ROLLBACK"
1691 5 "INSERT OR REPLACE"
1694 do_test fkey2-20.2.$tn.1 {
1695 catchsql "$insert INTO cc VALUES(1, 2)"
1696 } {1 {FOREIGN KEY constraint failed}}
1697 do_test fkey2-20.2.$tn.2 {
1698 execsql { SELECT * FROM cc }
1700 do_test fkey2-20.2.$tn.3 {
1703 INSERT INTO pp VALUES(2, 'two');
1704 INSERT INTO cc VALUES(1, 2);
1706 catchsql "$insert INTO cc VALUES(3, 4)"
1707 } {1 {FOREIGN KEY constraint failed}}
1708 do_test fkey2-20.2.$tn.4 {
1709 execsql { COMMIT ; SELECT * FROM cc }
1711 do_test fkey2-20.2.$tn.5 {
1712 execsql { DELETE FROM cc ; DELETE FROM pp }
1716 foreach {tn update} {
1718 2 "UPDATE OR IGNORE"
1720 4 "UPDATE OR ROLLBACK"
1721 5 "UPDATE OR REPLACE"
1724 do_test fkey2-20.3.$tn.1 {
1726 INSERT INTO pp VALUES(2, 'two');
1727 INSERT INTO cc VALUES(1, 2);
1730 do_test fkey2-20.3.$tn.2 {
1731 catchsql "$update pp SET a = 1"
1732 } {1 {FOREIGN KEY constraint failed}}
1733 do_test fkey2-20.3.$tn.3 {
1734 execsql { SELECT * FROM pp }
1736 do_test fkey2-20.3.$tn.4 {
1737 catchsql "$update cc SET d = 1"
1738 } {1 {FOREIGN KEY constraint failed}}
1739 do_test fkey2-20.3.$tn.5 {
1740 execsql { SELECT * FROM cc }
1742 do_test fkey2-20.3.$tn.6 {
1745 INSERT INTO pp VALUES(3, 'three');
1747 catchsql "$update pp SET a = 1 WHERE a = 2"
1748 } {1 {FOREIGN KEY constraint failed}}
1749 do_test fkey2-20.3.$tn.7 {
1750 execsql { COMMIT ; SELECT * FROM pp }
1752 do_test fkey2-20.3.$tn.8 {
1755 INSERT INTO cc VALUES(2, 2);
1757 catchsql "$update cc SET d = 1 WHERE c = 1"
1758 } {1 {FOREIGN KEY constraint failed}}
1759 do_test fkey2-20.3.$tn.9 {
1760 execsql { COMMIT ; SELECT * FROM cc }
1762 do_test fkey2-20.3.$tn.10 {
1763 execsql { DELETE FROM cc ; DELETE FROM pp }
1767 #-------------------------------------------------------------------------
1768 # The following block of tests, those prefixed with "fkey2-genfkey.", are
1769 # the same tests that were used to test the ".genfkey" command provided
1770 # by the shell tool. So these tests show that the built-in foreign key
1771 # implementation is more or less compatible with the triggers generated
1775 do_test fkey2-genfkey.1.1 {
1777 CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, UNIQUE(b, c));
1778 CREATE TABLE t2(e REFERENCES t1, f);
1779 CREATE TABLE t3(g, h, i, FOREIGN KEY (h, i) REFERENCES t1(b, c));
1782 do_test fkey2-genfkey.1.2 {
1783 catchsql { INSERT INTO t2 VALUES(1, 2) }
1784 } {1 {FOREIGN KEY constraint failed}}
1785 do_test fkey2-genfkey.1.3 {
1787 INSERT INTO t1 VALUES(1, 2, 3);
1788 INSERT INTO t2 VALUES(1, 2);
1791 do_test fkey2-genfkey.1.4 {
1792 execsql { INSERT INTO t2 VALUES(NULL, 3) }
1794 do_test fkey2-genfkey.1.5 {
1795 catchsql { UPDATE t2 SET e = 5 WHERE e IS NULL }
1796 } {1 {FOREIGN KEY constraint failed}}
1797 do_test fkey2-genfkey.1.6 {
1798 execsql { UPDATE t2 SET e = 1 WHERE e IS NULL }
1800 do_test fkey2-genfkey.1.7 {
1801 execsql { UPDATE t2 SET e = NULL WHERE f = 3 }
1803 do_test fkey2-genfkey.1.8 {
1804 catchsql { UPDATE t1 SET a = 10 }
1805 } {1 {FOREIGN KEY constraint failed}}
1806 do_test fkey2-genfkey.1.9 {
1807 catchsql { UPDATE t1 SET a = NULL }
1808 } {1 {datatype mismatch}}
1809 do_test fkey2-genfkey.1.10 {
1810 catchsql { DELETE FROM t1 }
1811 } {1 {FOREIGN KEY constraint failed}}
1812 do_test fkey2-genfkey.1.11 {
1813 execsql { UPDATE t2 SET e = NULL }
1815 do_test fkey2-genfkey.1.12 {
1817 UPDATE t1 SET a = 10;
1822 do_test fkey2-genfkey.1.13 {
1824 INSERT INTO t3 VALUES(1, NULL, NULL);
1825 INSERT INTO t3 VALUES(1, 2, NULL);
1826 INSERT INTO t3 VALUES(1, NULL, 3);
1829 do_test fkey2-genfkey.1.14 {
1830 catchsql { INSERT INTO t3 VALUES(3, 1, 4) }
1831 } {1 {FOREIGN KEY constraint failed}}
1832 do_test fkey2-genfkey.1.15 {
1834 INSERT INTO t1 VALUES(1, 1, 4);
1835 INSERT INTO t3 VALUES(3, 1, 4);
1838 do_test fkey2-genfkey.1.16 {
1839 catchsql { DELETE FROM t1 }
1840 } {1 {FOREIGN KEY constraint failed}}
1841 do_test fkey2-genfkey.1.17 {
1842 catchsql { UPDATE t1 SET b = 10}
1843 } {1 {FOREIGN KEY constraint failed}}
1844 do_test fkey2-genfkey.1.18 {
1845 execsql { UPDATE t1 SET a = 10}
1847 do_test fkey2-genfkey.1.19 {
1848 catchsql { UPDATE t3 SET h = 'hello' WHERE i = 3}
1849 } {1 {FOREIGN KEY constraint failed}}
1852 do_test fkey2-genfkey.2.1 {
1854 CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, UNIQUE(b, c));
1855 CREATE TABLE t2(e REFERENCES t1 ON UPDATE CASCADE ON DELETE CASCADE, f);
1856 CREATE TABLE t3(g, h, i,
1858 REFERENCES t1(b, c) ON UPDATE CASCADE ON DELETE CASCADE
1862 do_test fkey2-genfkey.2.2 {
1864 INSERT INTO t1 VALUES(1, 2, 3);
1865 INSERT INTO t1 VALUES(4, 5, 6);
1866 INSERT INTO t2 VALUES(1, 'one');
1867 INSERT INTO t2 VALUES(4, 'four');
1870 do_test fkey2-genfkey.2.3 {
1872 UPDATE t1 SET a = 2 WHERE a = 1;
1876 do_test fkey2-genfkey.2.4 {
1878 DELETE FROM t1 WHERE a = 4;
1883 do_test fkey2-genfkey.2.5 {
1885 INSERT INTO t3 VALUES('hello', 2, 3);
1886 UPDATE t1 SET c = 2;
1890 do_test fkey2-genfkey.2.6 {
1898 do_test fkey2-genfkey.3.1 {
1900 CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, UNIQUE(c, b));
1901 CREATE TABLE t2(e REFERENCES t1 ON UPDATE SET NULL ON DELETE SET NULL, f);
1902 CREATE TABLE t3(g, h, i,
1904 REFERENCES t1(b, c) ON UPDATE SET NULL ON DELETE SET NULL
1908 do_test fkey2-genfkey.3.2 {
1910 INSERT INTO t1 VALUES(1, 2, 3);
1911 INSERT INTO t1 VALUES(4, 5, 6);
1912 INSERT INTO t2 VALUES(1, 'one');
1913 INSERT INTO t2 VALUES(4, 'four');
1916 do_test fkey2-genfkey.3.3 {
1918 UPDATE t1 SET a = 2 WHERE a = 1;
1922 do_test fkey2-genfkey.3.4 {
1924 DELETE FROM t1 WHERE a = 4;
1928 do_test fkey2-genfkey.3.5 {
1930 INSERT INTO t3 VALUES('hello', 2, 3);
1931 UPDATE t1 SET c = 2;
1935 do_test fkey2-genfkey.3.6 {
1937 UPDATE t3 SET h = 2, i = 2;
1943 #-------------------------------------------------------------------------
1944 # Verify that ticket dd08e5a988d00decc4a543daa8dbbfab9c577ad8 has been
1947 do_test fkey2-dd08e5.1.1 {
1949 PRAGMA foreign_keys=ON;
1950 CREATE TABLE tdd08(a INTEGER PRIMARY KEY, b);
1951 CREATE UNIQUE INDEX idd08 ON tdd08(a,b);
1952 INSERT INTO tdd08 VALUES(200,300);
1954 CREATE TABLE tdd08_b(w,x,y, FOREIGN KEY(x,y) REFERENCES tdd08(a,b));
1955 INSERT INTO tdd08_b VALUES(100,200,300);
1958 do_test fkey2-dd08e5.1.2 {
1962 } {1 {FOREIGN KEY constraint failed}}
1963 do_test fkey2-dd08e5.1.3 {
1965 SELECT * FROM tdd08;
1968 do_test fkey2-dd08e5.1.4 {
1970 INSERT INTO tdd08_b VALUES(400,500,300);
1972 } {1 {FOREIGN KEY constraint failed}}
1973 do_test fkey2-dd08e5.1.5 {
1975 UPDATE tdd08_b SET x=x+1;
1977 } {1 {FOREIGN KEY constraint failed}}
1978 do_test fkey2-dd08e5.1.6 {
1980 UPDATE tdd08 SET a=a+1;
1982 } {1 {FOREIGN KEY constraint failed}}
1984 #-------------------------------------------------------------------------
1985 # Verify that ticket ce7c133ea6cc9ccdc1a60d80441f80b6180f5eba
1988 do_test fkey2-ce7c13.1.1 {
1990 CREATE TABLE tce71(a INTEGER PRIMARY KEY, b);
1991 CREATE UNIQUE INDEX ice71 ON tce71(a,b);
1992 INSERT INTO tce71 VALUES(100,200);
1993 CREATE TABLE tce72(w, x, y, FOREIGN KEY(x,y) REFERENCES tce71(a,b));
1994 INSERT INTO tce72 VALUES(300,100,200);
1995 UPDATE tce71 set b = 200 where a = 100;
1996 SELECT * FROM tce71, tce72;
1998 } {100 200 300 100 200}
1999 do_test fkey2-ce7c13.1.2 {
2001 UPDATE tce71 set b = 201 where a = 100;
2003 } {1 {FOREIGN KEY constraint failed}}
2004 do_test fkey2-ce7c13.1.3 {
2006 UPDATE tce71 set a = 101 where a = 100;
2008 } {1 {FOREIGN KEY constraint failed}}
2009 do_test fkey2-ce7c13.1.4 {
2011 CREATE TABLE tce73(a INTEGER PRIMARY KEY, b, UNIQUE(a,b));
2012 INSERT INTO tce73 VALUES(100,200);
2013 CREATE TABLE tce74(w, x, y, FOREIGN KEY(x,y) REFERENCES tce73(a,b));
2014 INSERT INTO tce74 VALUES(300,100,200);
2015 UPDATE tce73 set b = 200 where a = 100;
2016 SELECT * FROM tce73, tce74;
2018 } {100 200 300 100 200}
2019 do_test fkey2-ce7c13.1.5 {
2021 UPDATE tce73 set b = 201 where a = 100;
2023 } {1 {FOREIGN KEY constraint failed}}
2024 do_test fkey2-ce7c13.1.6 {
2026 UPDATE tce73 set a = 101 where a = 100;
2028 } {1 {FOREIGN KEY constraint failed}}
2030 # 2015-04-16: Foreign key errors propagate back up to the parser.
2032 do_test fkey2-20150416-100 {
2036 PRAGMA foreign_keys=1;
2037 CREATE TABLE t1(x PRIMARY KEY);
2038 CREATE TABLE t(y REFERENCES t0(x)ON DELETE SET DEFAULT);
2039 CREATE TABLE t0(y REFERENCES t1 ON DELETE SET NULL);
2040 REPLACE INTO t1 SELECT(0);CREATE TABLE t2(x);CREATE TABLE t3;
2042 } {1 {foreign key mismatch - "t" referencing "t0"}}