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)" {1 {foreign key mismatch}}
145 do_test fkey2-1.1.0 {
146 execsql [string map {/D/ {}} $FkeySimpleSchema]
148 foreach {tn zSql res} $FkeySimpleTests {
149 do_test fkey2-1.1.$tn { catchsql $zSql } $res
153 do_test fkey2-1.2.0 {
154 execsql [string map {/D/ {DEFERRABLE INITIALLY DEFERRED}} $FkeySimpleSchema]
156 foreach {tn zSql res} $FkeySimpleTests {
157 do_test fkey2-1.2.$tn { catchsql $zSql } $res
161 do_test fkey2-1.3.0 {
162 execsql [string map {/D/ {}} $FkeySimpleSchema]
163 execsql { PRAGMA count_changes = 1 }
165 foreach {tn zSql res} $FkeySimpleTests {
166 if {$res == "0 {}"} { set res {0 1} }
167 do_test fkey2-1.3.$tn { catchsql $zSql } $res
169 execsql { PRAGMA count_changes = 0 }
172 do_test fkey2-1.4.0 {
173 execsql [string map {/D/ {}} $FkeySimpleSchema]
174 execsql { PRAGMA count_changes = 1 }
176 foreach {tn zSql res} $FkeySimpleTests {
177 if {$res == "0 {}"} { set res {0 1} }
179 do_test fkey2-1.4.$tn { catchsql $zSql } $res
182 execsql { PRAGMA count_changes = 0 }
185 # Special test: When the parent key is an IPK, make sure the affinity of
186 # the IPK is not applied to the child key value before it is inserted
187 # into the child table.
188 do_test fkey2-1.5.1 {
190 CREATE TABLE i(i INTEGER PRIMARY KEY);
191 CREATE TABLE j(j REFERENCES i);
192 INSERT INTO i VALUES(35);
193 INSERT INTO j VALUES('35.0');
194 SELECT j, typeof(j) FROM j;
197 do_test fkey2-1.5.2 {
198 catchsql { DELETE FROM i }
199 } {1 {foreign key constraint failed}}
201 # Same test using a regular primary key with integer affinity.
203 do_test fkey2-1.6.1 {
205 CREATE TABLE i(i INT UNIQUE);
206 CREATE TABLE j(j REFERENCES i(i));
207 INSERT INTO i VALUES('35.0');
208 INSERT INTO j VALUES('35.0');
209 SELECT j, typeof(j) FROM j;
210 SELECT i, typeof(i) FROM i;
212 } {35.0 text 35 integer}
213 do_test fkey2-1.6.2 {
214 catchsql { DELETE FROM i }
215 } {1 {foreign key constraint failed}}
217 # Use a collation sequence on the parent key.
219 do_test fkey2-1.7.1 {
221 CREATE TABLE i(i TEXT COLLATE nocase PRIMARY KEY);
222 CREATE TABLE j(j TEXT COLLATE binary REFERENCES i(i));
223 INSERT INTO i VALUES('SQLite');
224 INSERT INTO j VALUES('sqlite');
226 catchsql { DELETE FROM i }
227 } {1 {foreign key constraint failed}}
229 # Use the parent key collation even if it is default and the child key
230 # has an explicit value.
232 do_test fkey2-1.7.2 {
234 CREATE TABLE i(i TEXT PRIMARY KEY); -- Colseq is "BINARY"
235 CREATE TABLE j(j TEXT COLLATE nocase REFERENCES i(i));
236 INSERT INTO i VALUES('SQLite');
238 catchsql { INSERT INTO j VALUES('sqlite') }
239 } {1 {foreign key constraint failed}}
240 do_test fkey2-1.7.3 {
242 INSERT INTO i VALUES('sqlite');
243 INSERT INTO j VALUES('sqlite');
244 DELETE FROM i WHERE i = 'SQLite';
246 catchsql { DELETE FROM i WHERE i = 'sqlite' }
247 } {1 {foreign key constraint failed}}
249 #-------------------------------------------------------------------------
250 # This section (test cases fkey2-2.*) contains tests to check that the
251 # deferred foreign key constraint logic works.
253 proc fkey2-2-test {tn nocommit sql {res {}}} {
255 set expected {1 {foreign key constraint failed}}
257 set expected [list 0 $res]
259 do_test fkey2-2.$tn [list catchsql $sql] $expected
261 do_test fkey2-2.${tn}c {
263 } {1 {foreign key constraint failed}}
270 parent REFERENCES node DEFERRABLE INITIALLY DEFERRED
274 parent REFERENCES node DEFERRABLE INITIALLY DEFERRED
278 fkey2-2-test 1 0 "INSERT INTO node VALUES(1, 0)" FKV
279 fkey2-2-test 2 0 "BEGIN"
280 fkey2-2-test 3 1 "INSERT INTO node VALUES(1, 0)"
281 fkey2-2-test 4 0 "UPDATE node SET parent = NULL"
282 fkey2-2-test 5 0 "COMMIT"
283 fkey2-2-test 6 0 "SELECT * FROM node" {1 {}}
285 fkey2-2-test 7 0 "BEGIN"
286 fkey2-2-test 8 1 "INSERT INTO leaf VALUES('a', 2)"
287 fkey2-2-test 9 1 "INSERT INTO node VALUES(2, 0)"
288 fkey2-2-test 10 0 "UPDATE node SET parent = 1 WHERE nodeid = 2"
289 fkey2-2-test 11 0 "COMMIT"
290 fkey2-2-test 12 0 "SELECT * FROM node" {1 {} 2 1}
291 fkey2-2-test 13 0 "SELECT * FROM leaf" {a 2}
293 fkey2-2-test 14 0 "BEGIN"
294 fkey2-2-test 15 1 "DELETE FROM node WHERE nodeid = 2"
295 fkey2-2-test 16 0 "INSERT INTO node VALUES(2, NULL)"
296 fkey2-2-test 17 0 "COMMIT"
297 fkey2-2-test 18 0 "SELECT * FROM node" {1 {} 2 {}}
298 fkey2-2-test 19 0 "SELECT * FROM leaf" {a 2}
300 fkey2-2-test 20 0 "BEGIN"
301 fkey2-2-test 21 0 "INSERT INTO leaf VALUES('b', 1)"
302 fkey2-2-test 22 0 "SAVEPOINT save"
303 fkey2-2-test 23 0 "DELETE FROM node WHERE nodeid = 1"
304 fkey2-2-test 24 0 "ROLLBACK TO save"
305 fkey2-2-test 25 0 "COMMIT"
306 fkey2-2-test 26 0 "SELECT * FROM node" {1 {} 2 {}}
307 fkey2-2-test 27 0 "SELECT * FROM leaf" {a 2 b 1}
309 fkey2-2-test 28 0 "BEGIN"
310 fkey2-2-test 29 0 "INSERT INTO leaf VALUES('c', 1)"
311 fkey2-2-test 30 0 "SAVEPOINT save"
312 fkey2-2-test 31 0 "DELETE FROM node WHERE nodeid = 1"
313 fkey2-2-test 32 1 "RELEASE save"
314 fkey2-2-test 33 1 "DELETE FROM leaf WHERE cellid = 'b'"
315 fkey2-2-test 34 0 "DELETE FROM leaf WHERE cellid = 'c'"
316 fkey2-2-test 35 0 "COMMIT"
317 fkey2-2-test 36 0 "SELECT * FROM node" {2 {}}
318 fkey2-2-test 37 0 "SELECT * FROM leaf" {a 2}
320 fkey2-2-test 38 0 "SAVEPOINT outer"
321 fkey2-2-test 39 1 "INSERT INTO leaf VALUES('d', 3)"
322 fkey2-2-test 40 1 "RELEASE outer" FKV
323 fkey2-2-test 41 1 "INSERT INTO leaf VALUES('e', 3)"
324 fkey2-2-test 42 0 "INSERT INTO node VALUES(3, 2)"
325 fkey2-2-test 43 0 "RELEASE outer"
327 fkey2-2-test 44 0 "SAVEPOINT outer"
328 fkey2-2-test 45 1 "DELETE FROM node WHERE nodeid=3"
329 fkey2-2-test 47 0 "INSERT INTO node VALUES(3, 2)"
330 fkey2-2-test 48 0 "ROLLBACK TO outer"
331 fkey2-2-test 49 0 "RELEASE outer"
333 fkey2-2-test 50 0 "SAVEPOINT outer"
334 fkey2-2-test 51 1 "INSERT INTO leaf VALUES('f', 4)"
335 fkey2-2-test 52 1 "SAVEPOINT inner"
336 fkey2-2-test 53 1 "INSERT INTO leaf VALUES('g', 4)"
337 fkey2-2-test 54 1 "RELEASE outer" FKV
338 fkey2-2-test 55 1 "ROLLBACK TO inner"
339 fkey2-2-test 56 0 "COMMIT" FKV
340 fkey2-2-test 57 0 "INSERT INTO node VALUES(4, NULL)"
341 fkey2-2-test 58 0 "RELEASE outer"
342 fkey2-2-test 59 0 "SELECT * FROM node" {2 {} 3 2 4 {}}
343 fkey2-2-test 60 0 "SELECT * FROM leaf" {a 2 d 3 e 3 f 4}
345 # The following set of tests check that if a statement that affects
346 # multiple rows violates some foreign key constraints, then strikes a
347 # constraint that causes the statement-transaction to be rolled back,
348 # the deferred constraint counter is correctly reset to the value it
349 # had before the statement-transaction was opened.
351 fkey2-2-test 61 0 "BEGIN"
352 fkey2-2-test 62 0 "DELETE FROM leaf"
353 fkey2-2-test 63 0 "DELETE FROM node"
354 fkey2-2-test 64 1 "INSERT INTO leaf VALUES('a', 1)"
355 fkey2-2-test 65 1 "INSERT INTO leaf VALUES('b', 2)"
356 fkey2-2-test 66 1 "INSERT INTO leaf VALUES('c', 1)"
357 do_test fkey2-2-test-67 {
358 catchsql "INSERT INTO node SELECT parent, 3 FROM leaf"
359 } {1 {column nodeid is not unique}}
360 fkey2-2-test 68 0 "COMMIT" FKV
361 fkey2-2-test 69 1 "INSERT INTO node VALUES(1, NULL)"
362 fkey2-2-test 70 0 "INSERT INTO node VALUES(2, NULL)"
363 fkey2-2-test 71 0 "COMMIT"
365 fkey2-2-test 72 0 "BEGIN"
366 fkey2-2-test 73 1 "DELETE FROM node"
367 fkey2-2-test 74 0 "INSERT INTO node(nodeid) SELECT DISTINCT parent FROM leaf"
368 fkey2-2-test 75 0 "COMMIT"
370 #-------------------------------------------------------------------------
371 # Test cases fkey2-3.* test that a program that executes foreign key
372 # actions (CASCADE, SET DEFAULT, SET NULL etc.) or tests FK constraints
373 # opens a statement transaction if required.
375 # fkey2-3.1.*: Test UPDATE statements.
376 # fkey2-3.2.*: Test DELETE statements.
379 do_test fkey2-3.1.1 {
381 CREATE TABLE ab(a PRIMARY KEY, b);
383 c PRIMARY KEY REFERENCES ab ON UPDATE CASCADE ON DELETE CASCADE,
387 e REFERENCES cd ON UPDATE CASCADE,
392 do_test fkey2-3.1.2 {
394 INSERT INTO ab VALUES(1, 'b');
395 INSERT INTO cd VALUES(1, 'd');
396 INSERT INTO ef VALUES(1, 'e');
399 do_test fkey2-3.1.3 {
400 catchsql { UPDATE ab SET a = 5 }
401 } {1 {constraint failed}}
402 do_test fkey2-3.1.4 {
403 execsql { SELECT * FROM ab }
405 do_test fkey2-3.1.4 {
407 catchsql { UPDATE ab SET a = 5 }
408 } {1 {constraint failed}}
409 do_test fkey2-3.1.5 {
411 execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef }
414 do_test fkey2-3.2.1 {
416 catchsql { DELETE FROM ab }
417 } {1 {foreign key constraint failed}}
418 do_test fkey2-3.2.2 {
420 execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef }
423 #-------------------------------------------------------------------------
424 # Test cases fkey2-4.* test that recursive foreign key actions
425 # (i.e. CASCADE) are allowed even if recursive triggers are disabled.
432 parent REFERENCES t1 ON DELETE CASCADE
434 CREATE TABLE t2(node PRIMARY KEY, parent);
435 CREATE TRIGGER t2t AFTER DELETE ON t2 BEGIN
436 DELETE FROM t2 WHERE parent = old.node;
438 INSERT INTO t1 VALUES(1, NULL);
439 INSERT INTO t1 VALUES(2, 1);
440 INSERT INTO t1 VALUES(3, 1);
441 INSERT INTO t1 VALUES(4, 2);
442 INSERT INTO t1 VALUES(5, 2);
443 INSERT INTO t1 VALUES(6, 3);
444 INSERT INTO t1 VALUES(7, 3);
445 INSERT INTO t2 SELECT * FROM t1;
449 execsql { PRAGMA recursive_triggers = off }
452 DELETE FROM t1 WHERE node = 1;
458 DELETE FROM t2 WHERE node = 1;
464 execsql { PRAGMA recursive_triggers = on }
467 DELETE FROM t1 WHERE node = 1;
473 DELETE FROM t2 WHERE node = 1;
479 #-------------------------------------------------------------------------
480 # Test cases fkey2-5.* verify that the incremental blob API may not
481 # write to a foreign key column while foreign-keys are enabled.
487 CREATE TABLE t1(a PRIMARY KEY, b);
488 CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1(a));
489 INSERT INTO t1 VALUES('hello', 'world');
490 INSERT INTO t2 VALUES('key', 'hello');
494 set rc [catch { set fd [db incrblob t2 b 1] } msg]
496 } {1 {cannot open foreign key column for writing}}
498 set rc [catch { set fd [db incrblob -readonly t2 b 1] } msg]
503 execsql { PRAGMA foreign_keys = off }
504 set rc [catch { set fd [db incrblob t2 b 1] } msg]
509 execsql { PRAGMA foreign_keys = on }
517 CREATE TABLE t1(a REFERENCES t2(c), b);
518 CREATE TABLE t2(c UNIQUE, b);
519 INSERT INTO t2 VALUES(1, 2);
520 INSERT INTO t1 VALUES(1, 2);
526 #-------------------------------------------------------------------------
527 # Test that it is possible to use an INTEGER PRIMARY KEY as the child key
528 # of a foreign constraint.
533 CREATE TABLE t1(a PRIMARY KEY, b);
534 CREATE TABLE t2(c INTEGER PRIMARY KEY REFERENCES t1, b);
538 catchsql { INSERT INTO t2 VALUES(1, 'A'); }
539 } {1 {foreign key constraint failed}}
542 INSERT INTO t1 VALUES(1, 2);
543 INSERT INTO t1 VALUES(2, 3);
544 INSERT INTO t2 VALUES(1, 'A');
548 execsql { UPDATE t2 SET c = 2 }
551 catchsql { UPDATE t2 SET c = 3 }
552 } {1 {foreign key constraint failed}}
554 catchsql { DELETE FROM t1 WHERE a = 2 }
555 } {1 {foreign key constraint failed}}
557 execsql { DELETE FROM t1 WHERE a = 1 }
560 catchsql { UPDATE t1 SET a = 3 }
561 } {1 {foreign key constraint failed}}
563 catchsql { UPDATE t2 SET rowid = 3 }
564 } {1 {foreign key constraint failed}}
566 #-------------------------------------------------------------------------
567 # Test that it is not possible to enable/disable FK support while a
568 # transaction is open.
571 proc fkey2-8-test {tn zSql value} {
572 do_test fkey-2.8.$tn.1 [list execsql $zSql] {}
573 do_test fkey-2.8.$tn.2 { execsql "PRAGMA foreign_keys" } $value
575 fkey2-8-test 1 { PRAGMA foreign_keys = 0 } 0
576 fkey2-8-test 2 { PRAGMA foreign_keys = 1 } 1
577 fkey2-8-test 3 { BEGIN } 1
578 fkey2-8-test 4 { PRAGMA foreign_keys = 0 } 1
579 fkey2-8-test 5 { COMMIT } 1
580 fkey2-8-test 6 { PRAGMA foreign_keys = 0 } 0
581 fkey2-8-test 7 { BEGIN } 0
582 fkey2-8-test 8 { PRAGMA foreign_keys = 1 } 0
583 fkey2-8-test 9 { COMMIT } 0
584 fkey2-8-test 10 { PRAGMA foreign_keys = 1 } 1
585 fkey2-8-test 11 { PRAGMA foreign_keys = off } 0
586 fkey2-8-test 12 { PRAGMA foreign_keys = on } 1
587 fkey2-8-test 13 { PRAGMA foreign_keys = no } 0
588 fkey2-8-test 14 { PRAGMA foreign_keys = yes } 1
589 fkey2-8-test 15 { PRAGMA foreign_keys = false } 0
590 fkey2-8-test 16 { PRAGMA foreign_keys = true } 1
592 #-------------------------------------------------------------------------
593 # The following tests, fkey2-9.*, test SET DEFAULT actions.
596 do_test fkey2-9.1.1 {
598 CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
600 c INTEGER PRIMARY KEY,
601 d INTEGER DEFAULT 1 REFERENCES t1 ON DELETE SET DEFAULT
606 do_test fkey2-9.1.2 {
608 INSERT INTO t1 VALUES(1, 'one');
609 INSERT INTO t1 VALUES(2, 'two');
610 INSERT INTO t2 VALUES(1, 2);
612 DELETE FROM t1 WHERE a = 2;
616 do_test fkey2-9.1.3 {
618 INSERT INTO t1 VALUES(2, 'two');
620 DELETE FROM t1 WHERE a = 1;
624 do_test fkey2-9.1.4 {
625 execsql { SELECT * FROM t1 }
627 do_test fkey2-9.1.5 {
628 catchsql { DELETE FROM t1 }
629 } {1 {foreign key constraint failed}}
631 do_test fkey2-9.2.1 {
633 CREATE TABLE pp(a, b, c, PRIMARY KEY(b, c));
634 CREATE TABLE cc(d DEFAULT 3, e DEFAULT 1, f DEFAULT 2,
635 FOREIGN KEY(f, d) REFERENCES pp
636 ON UPDATE SET DEFAULT
639 INSERT INTO pp VALUES(1, 2, 3);
640 INSERT INTO pp VALUES(4, 5, 6);
641 INSERT INTO pp VALUES(7, 8, 9);
644 do_test fkey2-9.2.2 {
646 INSERT INTO cc VALUES(6, 'A', 5);
647 INSERT INTO cc VALUES(6, 'B', 5);
648 INSERT INTO cc VALUES(9, 'A', 8);
649 INSERT INTO cc VALUES(9, 'B', 8);
650 UPDATE pp SET b = 1 WHERE a = 7;
653 } {6 A 5 6 B 5 3 A 2 3 B 2}
654 do_test fkey2-9.2.3 {
656 DELETE FROM pp WHERE a = 4;
659 } {{} A {} {} B {} 3 A 2 3 B 2}
661 #-------------------------------------------------------------------------
662 # The following tests, fkey2-10.*, test "foreign key mismatch" and
667 CREATE TABLE p(a PRIMARY KEY, b);
668 CREATE TABLE c(x REFERENCES p(c));
670 CREATE TABLE c(x REFERENCES v(y));
671 CREATE VIEW v AS SELECT x AS y FROM c;
673 CREATE TABLE p(a, b, PRIMARY KEY(a, b));
674 CREATE TABLE c(x REFERENCES p);
676 CREATE TABLE p(a COLLATE binary, b);
677 CREATE UNIQUE INDEX i ON p(a COLLATE nocase);
678 CREATE TABLE c(x REFERENCES p(a));
681 do_test fkey2-10.1.[incr tn] {
683 catchsql { INSERT INTO c DEFAULT VALUES }
684 } {1 {foreign key mismatch}}
687 # "rowid" cannot be used as part of a child or parent key definition
688 # unless it happens to be the name of an explicitly declared column.
690 do_test fkey2-10.2.1 {
693 CREATE TABLE t1(a PRIMARY KEY, b);
694 CREATE TABLE t2(c, d, FOREIGN KEY(rowid) REFERENCES t1(a));
696 } {1 {unknown column "rowid" in foreign key definition}}
697 do_test fkey2-10.2.2 {
700 CREATE TABLE t1(a PRIMARY KEY, b);
701 CREATE TABLE t2(rowid, d, FOREIGN KEY(rowid) REFERENCES t1(a));
704 do_test fkey2-10.2.1 {
707 CREATE TABLE t1(a, b);
708 CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(rowid));
709 INSERT INTO t1(rowid, a, b) VALUES(1, 1, 1);
710 INSERT INTO t2 VALUES(1, 1);
712 } {1 {foreign key mismatch}}
713 do_test fkey2-10.2.2 {
716 CREATE TABLE t1(rowid PRIMARY KEY, b);
717 CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(rowid));
718 INSERT INTO t1(rowid, b) VALUES(1, 1);
719 INSERT INTO t2 VALUES(1, 1);
724 #-------------------------------------------------------------------------
725 # The following tests, fkey2-11.*, test CASCADE actions.
728 do_test fkey2-11.1.1 {
730 CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
731 CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(a) ON UPDATE CASCADE);
733 INSERT INTO t1 VALUES(10, 100);
734 INSERT INTO t2 VALUES(10, 100);
735 UPDATE t1 SET a = 15;
740 #-------------------------------------------------------------------------
741 # The following tests, fkey2-12.*, test RESTRICT actions.
744 do_test fkey2-12.1.1 {
746 CREATE TABLE t1(a, b PRIMARY KEY);
748 x REFERENCES t1 ON UPDATE RESTRICT DEFERRABLE INITIALLY DEFERRED
750 INSERT INTO t1 VALUES(1, 'one');
751 INSERT INTO t1 VALUES(2, 'two');
752 INSERT INTO t1 VALUES(3, 'three');
755 do_test fkey2-12.1.2 {
757 execsql "INSERT INTO t2 VALUES('two')"
759 do_test fkey2-12.1.3 {
760 execsql "UPDATE t1 SET b = 'four' WHERE b = 'one'"
762 do_test fkey2-12.1.4 {
763 catchsql "UPDATE t1 SET b = 'five' WHERE b = 'two'"
764 } {1 {foreign key constraint failed}}
765 do_test fkey2-12.1.5 {
766 execsql "DELETE FROM t1 WHERE b = 'two'"
768 do_test fkey2-12.1.6 {
770 } {1 {foreign key constraint failed}}
771 do_test fkey2-12.1.7 {
773 INSERT INTO t1 VALUES(2, 'two');
779 do_test fkey2-12.2.1 {
781 CREATE TABLE t1(x COLLATE NOCASE PRIMARY KEY);
782 CREATE TRIGGER tt1 AFTER DELETE ON t1
783 WHEN EXISTS ( SELECT 1 FROM t2 WHERE old.x = y )
785 INSERT INTO t1 VALUES(old.x);
787 CREATE TABLE t2(y REFERENCES t1);
788 INSERT INTO t1 VALUES('A');
789 INSERT INTO t1 VALUES('B');
790 INSERT INTO t2 VALUES('a');
791 INSERT INTO t2 VALUES('b');
797 do_test fkey2-12.2.2 {
798 execsql { DELETE FROM t1 }
804 do_test fkey2-12.2.3 {
807 CREATE TABLE t2(y REFERENCES t1 ON DELETE RESTRICT);
808 INSERT INTO t2 VALUES('a');
809 INSERT INTO t2 VALUES('b');
811 catchsql { DELETE FROM t1 }
812 } {1 {foreign key constraint failed}}
813 do_test fkey2-12.2.4 {
821 do_test fkey2-12.3.1 {
824 c00, c01, c02, c03, c04, c05, c06, c07, c08, c09,
825 c10, c11, c12, c13, c14, c15, c16, c17, c18, c19,
826 c20, c21, c22, c23, c24, c25, c26, c27, c28, c29,
827 c30, c31, c32, c33, c34, c35, c36, c37, c38, c39,
828 PRIMARY KEY(c34, c35)
831 c00, c01, c02, c03, c04, c05, c06, c07, c08, c09,
832 c10, c11, c12, c13, c14, c15, c16, c17, c18, c19,
833 c20, c21, c22, c23, c24, c25, c26, c27, c28, c29,
834 c30, c31, c32, c33, c34, c35, c36, c37, c38, c39,
835 FOREIGN KEY(c39, c38) REFERENCES up ON UPDATE CASCADE
839 do_test fkey2-12.3.2 {
841 INSERT INTO up(c34, c35) VALUES('yes', 'no');
842 INSERT INTO down(c39, c38) VALUES('yes', 'no');
843 UPDATE up SET c34 = 'possibly';
844 SELECT c38, c39 FROM down;
848 do_test fkey2-12.3.3 {
849 catchsql { INSERT INTO down(c39, c38) VALUES('yes', 'no') }
850 } {1 {foreign key constraint failed}}
851 do_test fkey2-12.3.4 {
853 INSERT INTO up(c34, c35) VALUES('yes', 'no');
854 INSERT INTO down(c39, c38) VALUES('yes', 'no');
856 catchsql { DELETE FROM up WHERE c34 = 'yes' }
857 } {1 {foreign key constraint failed}}
858 do_test fkey2-12.3.5 {
860 DELETE FROM up WHERE c34 = 'possibly';
861 SELECT c34, c35 FROM up;
862 SELECT c39, c38 FROM down;
866 #-------------------------------------------------------------------------
867 # The following tests, fkey2-13.*, test that FK processing is performed
868 # when rows are REPLACEd.
871 do_test fkey2-13.1.1 {
873 CREATE TABLE pp(a UNIQUE, b, c, PRIMARY KEY(b, c));
874 CREATE TABLE cc(d, e, f UNIQUE, FOREIGN KEY(d, e) REFERENCES pp);
875 INSERT INTO pp VALUES(1, 2, 3);
876 INSERT INTO cc VALUES(2, 3, 1);
880 1 "REPLACE INTO pp VALUES(1, 4, 5)"
881 2 "REPLACE INTO pp(rowid, a, b, c) VALUES(1, 2, 3, 4)"
883 do_test fkey2-13.1.$tn.1 {
885 } {1 {foreign key constraint failed}}
886 do_test fkey2-13.1.$tn.2 {
892 do_test fkey2-13.1.$tn.3 {
895 } {1 {foreign key constraint failed}}
896 do_test fkey2-13.1.$tn.4 {
904 do_test fkey2-13.1.3 {
906 REPLACE INTO pp(rowid, a, b, c) VALUES(1, 2, 2, 3);
907 SELECT rowid, * FROM pp;
911 do_test fkey2-13.1.4 {
913 REPLACE INTO pp(rowid, a, b, c) VALUES(2, 2, 2, 3);
914 SELECT rowid, * FROM pp;
919 #-------------------------------------------------------------------------
920 # The following tests, fkey2-14.*, test that the "DROP TABLE" and "ALTER
921 # TABLE" commands work as expected wrt foreign key constraints.
923 # fkey2-14.1*: ALTER TABLE ADD COLUMN
924 # fkey2-14.2*: ALTER TABLE RENAME TABLE
925 # fkey2-14.3*: DROP TABLE
928 ifcapable altertable {
929 do_test fkey2-14.1.1 {
930 # Adding a column with a REFERENCES clause is not supported.
932 CREATE TABLE t1(a PRIMARY KEY);
933 CREATE TABLE t2(a, b);
935 catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
937 do_test fkey2-14.1.2 {
938 catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
940 do_test fkey2-14.1.3 {
941 catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}
943 do_test fkey2-14.1.4 {
944 catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'}
945 } {1 {Cannot add a REFERENCES column with non-NULL default value}}
946 do_test fkey2-14.1.5 {
947 catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 }
948 } {1 {Cannot add a REFERENCES column with non-NULL default value}}
949 do_test fkey2-14.1.6 {
951 PRAGMA foreign_keys = off;
952 ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
953 PRAGMA foreign_keys = on;
954 SELECT sql FROM sqlite_master WHERE name='t2';
956 } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
959 # Test the sqlite_rename_parent() function directly.
961 proc test_rename_parent {zCreate zOld zNew} {
962 db eval {SELECT sqlite_rename_parent($zCreate, $zOld, $zNew)}
964 do_test fkey2-14.2.1.1 {
965 test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
966 } {{CREATE TABLE t1(a REFERENCES "t3")}}
967 do_test fkey2-14.2.1.2 {
968 test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
969 } {{CREATE TABLE t1(a REFERENCES t2)}}
970 do_test fkey2-14.2.1.3 {
971 test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
972 } {{CREATE TABLE t1(a REFERENCES "t3")}}
974 # Test ALTER TABLE RENAME TABLE a bit.
976 do_test fkey2-14.2.2.1 {
979 CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1);
980 CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2);
981 CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
983 execsql { SELECT sql FROM sqlite_master WHERE type = 'table'}
985 {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1)} \
986 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)} \
987 {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)} \
989 do_test fkey2-14.2.2.2 {
990 execsql { ALTER TABLE t1 RENAME TO t4 }
991 execsql { SELECT sql FROM sqlite_master WHERE type = 'table'}
993 {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4")} \
994 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)} \
995 {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \
997 do_test fkey2-14.2.2.3 {
998 catchsql { INSERT INTO t3 VALUES(1, 2, 3) }
999 } {1 {foreign key constraint failed}}
1000 do_test fkey2-14.2.2.4 {
1001 execsql { INSERT INTO t4 VALUES(1, NULL) }
1003 do_test fkey2-14.2.2.5 {
1004 catchsql { UPDATE t4 SET b = 5 }
1005 } {1 {foreign key constraint failed}}
1006 do_test fkey2-14.2.2.6 {
1007 catchsql { UPDATE t4 SET b = 1 }
1009 do_test fkey2-14.2.2.7 {
1010 execsql { INSERT INTO t3 VALUES(1, NULL, 1) }
1013 # Repeat for TEMP tables
1016 do_test fkey2-14.1tmp.1 {
1017 # Adding a column with a REFERENCES clause is not supported.
1019 CREATE TEMP TABLE t1(a PRIMARY KEY);
1020 CREATE TEMP TABLE t2(a, b);
1022 catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
1024 do_test fkey2-14.1tmp.2 {
1025 catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
1027 do_test fkey2-14.1tmp.3 {
1028 catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}
1030 do_test fkey2-14.1tmp.4 {
1031 catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'}
1032 } {1 {Cannot add a REFERENCES column with non-NULL default value}}
1033 do_test fkey2-14.1tmp.5 {
1034 catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 }
1035 } {1 {Cannot add a REFERENCES column with non-NULL default value}}
1036 do_test fkey2-14.1tmp.6 {
1038 PRAGMA foreign_keys = off;
1039 ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
1040 PRAGMA foreign_keys = on;
1041 SELECT sql FROM sqlite_temp_master WHERE name='t2';
1043 } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
1045 do_test fkey2-14.2tmp.1.1 {
1046 test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
1047 } {{CREATE TABLE t1(a REFERENCES "t3")}}
1048 do_test fkey2-14.2tmp.1.2 {
1049 test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
1050 } {{CREATE TABLE t1(a REFERENCES t2)}}
1051 do_test fkey2-14.2tmp.1.3 {
1052 test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
1053 } {{CREATE TABLE t1(a REFERENCES "t3")}}
1055 # Test ALTER TABLE RENAME TABLE a bit.
1057 do_test fkey2-14.2tmp.2.1 {
1060 CREATE TEMP TABLE t1(a PRIMARY KEY, b REFERENCES t1);
1061 CREATE TEMP TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2);
1062 CREATE TEMP TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
1064 execsql { SELECT sql FROM sqlite_temp_master WHERE type = 'table'}
1066 {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1)} \
1067 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)} \
1068 {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)} \
1070 do_test fkey2-14.2tmp.2.2 {
1071 execsql { ALTER TABLE t1 RENAME TO t4 }
1072 execsql { SELECT sql FROM sqlite_temp_master WHERE type = 'table'}
1074 {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4")} \
1075 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)} \
1076 {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \
1078 do_test fkey2-14.2tmp.2.3 {
1079 catchsql { INSERT INTO t3 VALUES(1, 2, 3) }
1080 } {1 {foreign key constraint failed}}
1081 do_test fkey2-14.2tmp.2.4 {
1082 execsql { INSERT INTO t4 VALUES(1, NULL) }
1084 do_test fkey2-14.2tmp.2.5 {
1085 catchsql { UPDATE t4 SET b = 5 }
1086 } {1 {foreign key constraint failed}}
1087 do_test fkey2-14.2tmp.2.6 {
1088 catchsql { UPDATE t4 SET b = 1 }
1090 do_test fkey2-14.2tmp.2.7 {
1091 execsql { INSERT INTO t3 VALUES(1, NULL, 1) }
1094 # Repeat for ATTACH-ed tables
1097 do_test fkey2-14.1aux.1 {
1098 # Adding a column with a REFERENCES clause is not supported.
1100 ATTACH ':memory:' AS aux;
1101 CREATE TABLE aux.t1(a PRIMARY KEY);
1102 CREATE TABLE aux.t2(a, b);
1104 catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
1106 do_test fkey2-14.1aux.2 {
1107 catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
1109 do_test fkey2-14.1aux.3 {
1110 catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}
1112 do_test fkey2-14.1aux.4 {
1113 catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'}
1114 } {1 {Cannot add a REFERENCES column with non-NULL default value}}
1115 do_test fkey2-14.1aux.5 {
1116 catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 }
1117 } {1 {Cannot add a REFERENCES column with non-NULL default value}}
1118 do_test fkey2-14.1aux.6 {
1120 PRAGMA foreign_keys = off;
1121 ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
1122 PRAGMA foreign_keys = on;
1123 SELECT sql FROM aux.sqlite_master WHERE name='t2';
1125 } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
1127 do_test fkey2-14.2aux.1.1 {
1128 test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
1129 } {{CREATE TABLE t1(a REFERENCES "t3")}}
1130 do_test fkey2-14.2aux.1.2 {
1131 test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
1132 } {{CREATE TABLE t1(a REFERENCES t2)}}
1133 do_test fkey2-14.2aux.1.3 {
1134 test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
1135 } {{CREATE TABLE t1(a REFERENCES "t3")}}
1137 # Test ALTER TABLE RENAME TABLE a bit.
1139 do_test fkey2-14.2aux.2.1 {
1142 CREATE TABLE aux.t1(a PRIMARY KEY, b REFERENCES t1);
1143 CREATE TABLE aux.t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2);
1144 CREATE TABLE aux.t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
1146 execsql { SELECT sql FROM aux.sqlite_master WHERE type = 'table'}
1148 {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1)} \
1149 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)} \
1150 {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)} \
1152 do_test fkey2-14.2aux.2.2 {
1153 execsql { ALTER TABLE t1 RENAME TO t4 }
1154 execsql { SELECT sql FROM aux.sqlite_master WHERE type = 'table'}
1156 {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4")} \
1157 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)} \
1158 {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \
1160 do_test fkey2-14.2aux.2.3 {
1161 catchsql { INSERT INTO t3 VALUES(1, 2, 3) }
1162 } {1 {foreign key constraint failed}}
1163 do_test fkey2-14.2aux.2.4 {
1164 execsql { INSERT INTO t4 VALUES(1, NULL) }
1166 do_test fkey2-14.2aux.2.5 {
1167 catchsql { UPDATE t4 SET b = 5 }
1168 } {1 {foreign key constraint failed}}
1169 do_test fkey2-14.2aux.2.6 {
1170 catchsql { UPDATE t4 SET b = 1 }
1172 do_test fkey2-14.2aux.2.7 {
1173 execsql { INSERT INTO t3 VALUES(1, NULL, 1) }
1177 do_test fkey-2.14.3.1 {
1180 CREATE TABLE t1(a, b REFERENCES nosuchtable);
1184 do_test fkey-2.14.3.2 {
1186 CREATE TABLE t1(a PRIMARY KEY, b);
1187 INSERT INTO t1 VALUES('a', 1);
1188 CREATE TABLE t2(x REFERENCES t1);
1189 INSERT INTO t2 VALUES('a');
1192 do_test fkey-2.14.3.3 {
1193 catchsql { DROP TABLE t1 }
1194 } {1 {foreign key constraint failed}}
1195 do_test fkey-2.14.3.4 {
1201 do_test fkey-2.14.3.4 {
1202 catchsql { INSERT INTO t2 VALUES('x') }
1203 } {1 {no such table: main.t1}}
1204 do_test fkey-2.14.3.5 {
1206 CREATE TABLE t1(x PRIMARY KEY);
1207 INSERT INTO t1 VALUES('x');
1209 execsql { INSERT INTO t2 VALUES('x') }
1211 do_test fkey-2.14.3.6 {
1212 catchsql { DROP TABLE t1 }
1213 } {1 {foreign key constraint failed}}
1214 do_test fkey-2.14.3.7 {
1220 do_test fkey-2.14.3.8 {
1222 CREATE TABLE pp(x, y, PRIMARY KEY(x, y));
1223 CREATE TABLE cc(a, b, FOREIGN KEY(a, b) REFERENCES pp(x, z));
1225 catchsql { INSERT INTO cc VALUES(1, 2) }
1226 } {1 {foreign key mismatch}}
1227 do_test fkey-2.14.3.9 {
1228 execsql { DROP TABLE cc }
1230 do_test fkey-2.14.3.10 {
1232 CREATE TABLE cc(a, b,
1233 FOREIGN KEY(a, b) REFERENCES pp DEFERRABLE INITIALLY DEFERRED
1237 INSERT INTO pp VALUES('a', 'b');
1238 INSERT INTO cc VALUES('a', 'b');
1241 CREATE TABLE pp(a, b, c, PRIMARY KEY(b, c));
1242 INSERT INTO pp VALUES(1, 'a', 'b');
1246 do_test fkey-2.14.3.11 {
1254 do_test fkey-2.14.3.12 {
1256 CREATE TABLE b1(a, b);
1257 CREATE TABLE b2(a, b REFERENCES b1);
1261 do_test fkey-2.14.3.13 {
1263 CREATE TABLE b3(a, b REFERENCES b2 DEFERRABLE INITIALLY DEFERRED);
1268 # Test that nothing goes wrong when dropping a table that refers to a view.
1269 # Or dropping a view that an existing FK (incorrectly) refers to. Or either
1270 # of the above scenarios with a virtual table.
1272 do_test fkey-2.14.4.1 {
1274 CREATE TABLE t1(x REFERENCES v);
1275 CREATE VIEW v AS SELECT * FROM t1;
1278 do_test fkey-2.14.4.2 {
1284 register_echo_module db
1285 do_test fkey-2.14.4.3 {
1286 execsql { CREATE VIRTUAL TABLE v USING echo(t1) }
1288 do_test fkey-2.14.4.2 {
1295 #-------------------------------------------------------------------------
1296 # The following tests, fkey2-15.*, test that unnecessary FK related scans
1297 # and lookups are avoided when the constraint counters are zero.
1300 proc execsqlS {zSql} {
1301 set ::sqlite_search_count 0
1302 set ::sqlite_found_count 0
1303 set res [uplevel [list execsql $zSql]]
1304 concat [expr $::sqlite_found_count + $::sqlite_search_count] $res
1306 do_test fkey2-15.1.1 {
1308 CREATE TABLE pp(a PRIMARY KEY, b);
1309 CREATE TABLE cc(x, y REFERENCES pp DEFERRABLE INITIALLY DEFERRED);
1310 INSERT INTO pp VALUES(1, 'one');
1311 INSERT INTO pp VALUES(2, 'two');
1312 INSERT INTO cc VALUES('neung', 1);
1313 INSERT INTO cc VALUES('song', 2);
1316 do_test fkey2-15.1.2 {
1317 execsqlS { INSERT INTO pp VALUES(3, 'three') }
1319 do_test fkey2-15.1.3 {
1322 INSERT INTO cc VALUES('see', 4); -- Violates deferred constraint
1324 execsqlS { INSERT INTO pp VALUES(5, 'five') }
1326 do_test fkey2-15.1.4 {
1327 execsql { DELETE FROM cc WHERE x = 'see' }
1328 execsqlS { INSERT INTO pp VALUES(6, 'six') }
1330 do_test fkey2-15.1.5 {
1333 do_test fkey2-15.1.6 {
1336 DELETE FROM cc WHERE x = 'neung';
1340 do_test fkey2-15.1.7 {
1343 DELETE FROM pp WHERE a = 2;
1346 DELETE FROM cc WHERE x = 'neung';
1351 #-------------------------------------------------------------------------
1352 # This next block of tests, fkey2-16.*, test that rows that refer to
1353 # themselves may be inserted and deleted.
1355 foreach {tn zSchema} {
1356 1 { CREATE TABLE self(a INTEGER PRIMARY KEY, b REFERENCES self(a)) }
1357 2 { CREATE TABLE self(a PRIMARY KEY, b REFERENCES self(a)) }
1358 3 { CREATE TABLE self(a UNIQUE, b INTEGER PRIMARY KEY REFERENCES self(a)) }
1361 do_test fkey2-16.1.$tn.1 {
1363 execsql { INSERT INTO self VALUES(13, 13) }
1365 do_test fkey2-16.1.$tn.2 {
1366 execsql { UPDATE self SET a = 14, b = 14 }
1369 do_test fkey2-16.1.$tn.3 {
1370 catchsql { UPDATE self SET b = 15 }
1371 } {1 {foreign key constraint failed}}
1373 do_test fkey2-16.1.$tn.4 {
1374 catchsql { UPDATE self SET a = 15 }
1375 } {1 {foreign key constraint failed}}
1377 do_test fkey2-16.1.$tn.5 {
1378 catchsql { UPDATE self SET a = 15, b = 16 }
1379 } {1 {foreign key constraint failed}}
1381 do_test fkey2-16.1.$tn.6 {
1382 catchsql { UPDATE self SET a = 17, b = 17 }
1385 do_test fkey2-16.1.$tn.7 {
1386 execsql { DELETE FROM self }
1388 do_test fkey2-16.1.$tn.8 {
1389 catchsql { INSERT INTO self VALUES(20, 21) }
1390 } {1 {foreign key constraint failed}}
1393 #-------------------------------------------------------------------------
1394 # This next block of tests, fkey2-17.*, tests that if "PRAGMA count_changes"
1395 # is turned on statements that violate immediate FK constraints return
1396 # SQLITE_CONSTRAINT immediately, not after returning a number of rows.
1397 # Whereas statements that violate deferred FK constraints return the number
1398 # of rows before failing.
1400 # Also test that rows modified by FK actions are not counted in either the
1401 # returned row count or the values returned by sqlite3_changes(). Like
1402 # trigger related changes, they are included in sqlite3_total_changes() though.
1405 do_test fkey2-17.1.1 {
1406 execsql { PRAGMA count_changes = 1 }
1408 CREATE TABLE one(a, b, c, UNIQUE(b, c));
1409 CREATE TABLE two(d, e, f, FOREIGN KEY(e, f) REFERENCES one(b, c));
1410 INSERT INTO one VALUES(1, 2, 3);
1413 do_test fkey2-17.1.2 {
1414 set STMT [sqlite3_prepare_v2 db "INSERT INTO two VALUES(4, 5, 6)" -1 dummy]
1416 } {SQLITE_CONSTRAINT}
1417 ifcapable autoreset {
1418 do_test fkey2-17.1.3 {
1420 } {SQLITE_CONSTRAINT}
1422 do_test fkey2-17.1.3 {
1426 do_test fkey2-17.1.4 {
1427 sqlite3_finalize $STMT
1428 } {SQLITE_CONSTRAINT}
1429 do_test fkey2-17.1.5 {
1431 INSERT INTO one VALUES(2, 3, 4);
1432 INSERT INTO one VALUES(3, 4, 5);
1433 INSERT INTO two VALUES(1, 2, 3);
1434 INSERT INTO two VALUES(2, 3, 4);
1435 INSERT INTO two VALUES(3, 4, 5);
1438 do_test fkey2-17.1.6 {
1441 INSERT INTO one VALUES(0, 0, 0);
1442 UPDATE two SET e=e+1, f=f+1;
1444 } {1 {foreign key constraint failed}}
1445 do_test fkey2-17.1.7 {
1446 execsql { SELECT * FROM one }
1447 } {1 2 3 2 3 4 3 4 5 0 0 0}
1448 do_test fkey2-17.1.8 {
1449 execsql { SELECT * FROM two }
1450 } {1 2 3 2 3 4 3 4 5}
1451 do_test fkey2-17.1.9 {
1454 do_test fkey2-17.1.10 {
1458 FOREIGN KEY(h, i) REFERENCES one(b, c) DEFERRABLE INITIALLY DEFERRED
1462 do_test fkey2-17.1.11 {
1463 set STMT [sqlite3_prepare_v2 db "INSERT INTO three VALUES(7, 8, 9)" -1 dummy]
1466 do_test fkey2-17.1.12 {
1467 sqlite3_column_text $STMT 0
1469 do_test fkey2-17.1.13 {
1471 } {SQLITE_CONSTRAINT}
1472 do_test fkey2-17.1.14 {
1473 sqlite3_finalize $STMT
1474 } {SQLITE_CONSTRAINT}
1477 do_test fkey2-17.2.1 {
1479 CREATE TABLE high("a'b!" PRIMARY KEY, b);
1482 "d&6" REFERENCES high ON UPDATE CASCADE ON DELETE CASCADE
1486 do_test fkey2-17.2.2 {
1488 INSERT INTO high VALUES('a', 'b');
1489 INSERT INTO low VALUES('b', 'a');
1493 set nTotal [db total_changes]
1494 do_test fkey2-17.2.3 {
1495 execsql { UPDATE high SET "a'b!" = 'c' }
1497 do_test fkey2-17.2.4 {
1500 do_test fkey2-17.2.5 {
1501 expr [db total_changes] - $nTotal
1503 do_test fkey2-17.2.6 {
1504 execsql { SELECT * FROM high ; SELECT * FROM low }
1506 do_test fkey2-17.2.7 {
1507 execsql { DELETE FROM high }
1509 do_test fkey2-17.2.8 {
1512 do_test fkey2-17.2.9 {
1513 expr [db total_changes] - $nTotal
1515 do_test fkey2-17.2.10 {
1516 execsql { SELECT * FROM high ; SELECT * FROM low }
1518 execsql { PRAGMA count_changes = 0 }
1520 #-------------------------------------------------------------------------
1521 # Test that the authorization callback works.
1525 do_test fkey2-18.1 {
1527 CREATE TABLE long(a, b PRIMARY KEY, c);
1528 CREATE TABLE short(d, e, f REFERENCES long);
1529 CREATE TABLE mid(g, h, i REFERENCES long DEFERRABLE INITIALLY DEFERRED);
1533 proc auth {args} {eval lappend ::authargs $args ; return SQLITE_OK}
1536 # An insert on the parent table must read the child key of any deferred
1537 # foreign key constraints. But not the child key of immediate constraints.
1539 do_test fkey2-18.2 {
1540 execsql { INSERT INTO long VALUES(1, 2, 3) }
1542 } {SQLITE_INSERT long {} main {} SQLITE_READ mid i main {}}
1544 # An insert on the child table of an immediate constraint must read the
1545 # parent key columns (to see if it is a violation or not).
1547 do_test fkey2-18.3 {
1548 execsql { INSERT INTO short VALUES(1, 3, 2) }
1550 } {SQLITE_INSERT short {} main {} SQLITE_READ long b main {}}
1552 # As must an insert on the child table of a deferred constraint.
1554 do_test fkey2-18.4 {
1555 execsql { INSERT INTO mid VALUES(1, 3, 2) }
1557 } {SQLITE_INSERT mid {} main {} SQLITE_READ long b main {}}
1559 do_test fkey2-18.5 {
1561 CREATE TABLE nought(a, b PRIMARY KEY, c);
1562 CREATE TABLE cross(d, e, f,
1563 FOREIGN KEY(e) REFERENCES nought(b) ON UPDATE CASCADE
1566 execsql { INSERT INTO nought VALUES(2, 1, 2) }
1567 execsql { INSERT INTO cross VALUES(0, 1, 0) }
1569 execsql { UPDATE nought SET b = 5 }
1571 } {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 {}}
1573 do_test fkey2-18.6 {
1574 execsql {SELECT * FROM cross}
1577 do_test fkey2-18.7 {
1579 CREATE TABLE one(a INTEGER PRIMARY KEY, b);
1580 CREATE TABLE two(b, c REFERENCES one);
1581 INSERT INTO one VALUES(101, 102);
1584 execsql { INSERT INTO two VALUES(100, 101); }
1586 } {SQLITE_INSERT two {} main {} SQLITE_READ one a main {}}
1588 # Return SQLITE_IGNORE to requests to read from the parent table. This
1589 # causes inserts of non-NULL keys into the child table to fail.
1593 if {[lindex $args 1] == "long"} {return SQLITE_IGNORE}
1596 do_test fkey2-18.8 {
1597 catchsql { INSERT INTO short VALUES(1, 3, 2) }
1598 } {1 {foreign key constraint failed}}
1599 do_test fkey2-18.9 {
1600 execsql { INSERT INTO short VALUES(1, 3, NULL) }
1602 do_test fkey2-18.10 {
1603 execsql { SELECT * FROM short }
1605 do_test fkey2-18.11 {
1606 catchsql { UPDATE short SET f = 2 WHERE f IS NULL }
1607 } {1 {foreign key constraint failed}}
1614 do_test fkey2-19.1 {
1616 CREATE TABLE main(id INTEGER PRIMARY KEY);
1617 CREATE TABLE sub(id INT REFERENCES main(id));
1618 INSERT INTO main VALUES(1);
1619 INSERT INTO main VALUES(2);
1620 INSERT INTO sub VALUES(2);
1623 do_test fkey2-19.2 {
1624 set S [sqlite3_prepare_v2 db "DELETE FROM main WHERE id = ?" -1 dummy]
1625 sqlite3_bind_int $S 1 2
1627 } {SQLITE_CONSTRAINT}
1628 do_test fkey2-19.3 {
1630 } {SQLITE_CONSTRAINT}
1631 do_test fkey2-19.4 {
1632 sqlite3_bind_int $S 1 1
1635 do_test fkey2-19.4 {
1640 do_test fkey2-20.1 {
1642 CREATE TABLE pp(a PRIMARY KEY, b);
1643 CREATE TABLE cc(c PRIMARY KEY, d REFERENCES pp);
1647 foreach {tn insert} {
1649 2 "INSERT OR IGNORE"
1651 4 "INSERT OR ROLLBACK"
1652 5 "INSERT OR REPLACE"
1655 do_test fkey2-20.2.$tn.1 {
1656 catchsql "$insert INTO cc VALUES(1, 2)"
1657 } {1 {foreign key constraint failed}}
1658 do_test fkey2-20.2.$tn.2 {
1659 execsql { SELECT * FROM cc }
1661 do_test fkey2-20.2.$tn.3 {
1664 INSERT INTO pp VALUES(2, 'two');
1665 INSERT INTO cc VALUES(1, 2);
1667 catchsql "$insert INTO cc VALUES(3, 4)"
1668 } {1 {foreign key constraint failed}}
1669 do_test fkey2-20.2.$tn.4 {
1670 execsql { COMMIT ; SELECT * FROM cc }
1672 do_test fkey2-20.2.$tn.5 {
1673 execsql { DELETE FROM cc ; DELETE FROM pp }
1677 foreach {tn update} {
1679 2 "UPDATE OR IGNORE"
1681 4 "UPDATE OR ROLLBACK"
1682 5 "UPDATE OR REPLACE"
1685 do_test fkey2-20.3.$tn.1 {
1687 INSERT INTO pp VALUES(2, 'two');
1688 INSERT INTO cc VALUES(1, 2);
1691 do_test fkey2-20.3.$tn.2 {
1692 catchsql "$update pp SET a = 1"
1693 } {1 {foreign key constraint failed}}
1694 do_test fkey2-20.3.$tn.3 {
1695 execsql { SELECT * FROM pp }
1697 do_test fkey2-20.3.$tn.4 {
1698 catchsql "$update cc SET d = 1"
1699 } {1 {foreign key constraint failed}}
1700 do_test fkey2-20.3.$tn.5 {
1701 execsql { SELECT * FROM cc }
1703 do_test fkey2-20.3.$tn.6 {
1706 INSERT INTO pp VALUES(3, 'three');
1708 catchsql "$update pp SET a = 1 WHERE a = 2"
1709 } {1 {foreign key constraint failed}}
1710 do_test fkey2-20.3.$tn.7 {
1711 execsql { COMMIT ; SELECT * FROM pp }
1713 do_test fkey2-20.3.$tn.8 {
1716 INSERT INTO cc VALUES(2, 2);
1718 catchsql "$update cc SET d = 1 WHERE c = 1"
1719 } {1 {foreign key constraint failed}}
1720 do_test fkey2-20.3.$tn.9 {
1721 execsql { COMMIT ; SELECT * FROM cc }
1723 do_test fkey2-20.3.$tn.10 {
1724 execsql { DELETE FROM cc ; DELETE FROM pp }
1728 #-------------------------------------------------------------------------
1729 # The following block of tests, those prefixed with "fkey2-genfkey.", are
1730 # the same tests that were used to test the ".genfkey" command provided
1731 # by the shell tool. So these tests show that the built-in foreign key
1732 # implementation is more or less compatible with the triggers generated
1736 do_test fkey2-genfkey.1.1 {
1738 CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, UNIQUE(b, c));
1739 CREATE TABLE t2(e REFERENCES t1, f);
1740 CREATE TABLE t3(g, h, i, FOREIGN KEY (h, i) REFERENCES t1(b, c));
1743 do_test fkey2-genfkey.1.2 {
1744 catchsql { INSERT INTO t2 VALUES(1, 2) }
1745 } {1 {foreign key constraint failed}}
1746 do_test fkey2-genfkey.1.3 {
1748 INSERT INTO t1 VALUES(1, 2, 3);
1749 INSERT INTO t2 VALUES(1, 2);
1752 do_test fkey2-genfkey.1.4 {
1753 execsql { INSERT INTO t2 VALUES(NULL, 3) }
1755 do_test fkey2-genfkey.1.5 {
1756 catchsql { UPDATE t2 SET e = 5 WHERE e IS NULL }
1757 } {1 {foreign key constraint failed}}
1758 do_test fkey2-genfkey.1.6 {
1759 execsql { UPDATE t2 SET e = 1 WHERE e IS NULL }
1761 do_test fkey2-genfkey.1.7 {
1762 execsql { UPDATE t2 SET e = NULL WHERE f = 3 }
1764 do_test fkey2-genfkey.1.8 {
1765 catchsql { UPDATE t1 SET a = 10 }
1766 } {1 {foreign key constraint failed}}
1767 do_test fkey2-genfkey.1.9 {
1768 catchsql { UPDATE t1 SET a = NULL }
1769 } {1 {datatype mismatch}}
1770 do_test fkey2-genfkey.1.10 {
1771 catchsql { DELETE FROM t1 }
1772 } {1 {foreign key constraint failed}}
1773 do_test fkey2-genfkey.1.11 {
1774 execsql { UPDATE t2 SET e = NULL }
1776 do_test fkey2-genfkey.1.12 {
1778 UPDATE t1 SET a = 10;
1783 do_test fkey2-genfkey.1.13 {
1785 INSERT INTO t3 VALUES(1, NULL, NULL);
1786 INSERT INTO t3 VALUES(1, 2, NULL);
1787 INSERT INTO t3 VALUES(1, NULL, 3);
1790 do_test fkey2-genfkey.1.14 {
1791 catchsql { INSERT INTO t3 VALUES(3, 1, 4) }
1792 } {1 {foreign key constraint failed}}
1793 do_test fkey2-genfkey.1.15 {
1795 INSERT INTO t1 VALUES(1, 1, 4);
1796 INSERT INTO t3 VALUES(3, 1, 4);
1799 do_test fkey2-genfkey.1.16 {
1800 catchsql { DELETE FROM t1 }
1801 } {1 {foreign key constraint failed}}
1802 do_test fkey2-genfkey.1.17 {
1803 catchsql { UPDATE t1 SET b = 10}
1804 } {1 {foreign key constraint failed}}
1805 do_test fkey2-genfkey.1.18 {
1806 execsql { UPDATE t1 SET a = 10}
1808 do_test fkey2-genfkey.1.19 {
1809 catchsql { UPDATE t3 SET h = 'hello' WHERE i = 3}
1810 } {1 {foreign key constraint failed}}
1813 do_test fkey2-genfkey.2.1 {
1815 CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, UNIQUE(b, c));
1816 CREATE TABLE t2(e REFERENCES t1 ON UPDATE CASCADE ON DELETE CASCADE, f);
1817 CREATE TABLE t3(g, h, i,
1819 REFERENCES t1(b, c) ON UPDATE CASCADE ON DELETE CASCADE
1823 do_test fkey2-genfkey.2.2 {
1825 INSERT INTO t1 VALUES(1, 2, 3);
1826 INSERT INTO t1 VALUES(4, 5, 6);
1827 INSERT INTO t2 VALUES(1, 'one');
1828 INSERT INTO t2 VALUES(4, 'four');
1831 do_test fkey2-genfkey.2.3 {
1833 UPDATE t1 SET a = 2 WHERE a = 1;
1837 do_test fkey2-genfkey.2.4 {
1839 DELETE FROM t1 WHERE a = 4;
1844 do_test fkey2-genfkey.2.5 {
1846 INSERT INTO t3 VALUES('hello', 2, 3);
1847 UPDATE t1 SET c = 2;
1851 do_test fkey2-genfkey.2.6 {
1859 do_test fkey2-genfkey.3.1 {
1861 CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, UNIQUE(c, b));
1862 CREATE TABLE t2(e REFERENCES t1 ON UPDATE SET NULL ON DELETE SET NULL, f);
1863 CREATE TABLE t3(g, h, i,
1865 REFERENCES t1(b, c) ON UPDATE SET NULL ON DELETE SET NULL
1869 do_test fkey2-genfkey.3.2 {
1871 INSERT INTO t1 VALUES(1, 2, 3);
1872 INSERT INTO t1 VALUES(4, 5, 6);
1873 INSERT INTO t2 VALUES(1, 'one');
1874 INSERT INTO t2 VALUES(4, 'four');
1877 do_test fkey2-genfkey.3.3 {
1879 UPDATE t1 SET a = 2 WHERE a = 1;
1883 do_test fkey2-genfkey.3.4 {
1885 DELETE FROM t1 WHERE a = 4;
1889 do_test fkey2-genfkey.3.5 {
1891 INSERT INTO t3 VALUES('hello', 2, 3);
1892 UPDATE t1 SET c = 2;
1896 do_test fkey2-genfkey.3.6 {
1898 UPDATE t3 SET h = 2, i = 2;
1904 #-------------------------------------------------------------------------
1905 # Verify that ticket dd08e5a988d00decc4a543daa8dbbfab9c577ad8 has been
1908 do_test fkey2-dd08e5.1.1 {
1910 PRAGMA foreign_keys=ON;
1911 CREATE TABLE tdd08(a INTEGER PRIMARY KEY, b);
1912 CREATE UNIQUE INDEX idd08 ON tdd08(a,b);
1913 INSERT INTO tdd08 VALUES(200,300);
1915 CREATE TABLE tdd08_b(w,x,y, FOREIGN KEY(x,y) REFERENCES tdd08(a,b));
1916 INSERT INTO tdd08_b VALUES(100,200,300);
1919 do_test fkey2-dd08e5.1.2 {
1923 } {1 {foreign key constraint failed}}
1924 do_test fkey2-dd08e5.1.3 {
1926 SELECT * FROM tdd08;
1929 do_test fkey2-dd08e5.1.4 {
1931 INSERT INTO tdd08_b VALUES(400,500,300);
1933 } {1 {foreign key constraint failed}}
1934 do_test fkey2-dd08e5.1.5 {
1936 UPDATE tdd08_b SET x=x+1;
1938 } {1 {foreign key constraint failed}}
1939 do_test fkey2-dd08e5.1.6 {
1941 UPDATE tdd08 SET a=a+1;
1943 } {1 {foreign key constraint failed}}
1945 #-------------------------------------------------------------------------
1946 # Verify that ticket ce7c133ea6cc9ccdc1a60d80441f80b6180f5eba
1949 do_test fkey2-ce7c13.1.1 {
1951 CREATE TABLE tce71(a INTEGER PRIMARY KEY, b);
1952 CREATE UNIQUE INDEX ice71 ON tce71(a,b);
1953 INSERT INTO tce71 VALUES(100,200);
1954 CREATE TABLE tce72(w, x, y, FOREIGN KEY(x,y) REFERENCES tce71(a,b));
1955 INSERT INTO tce72 VALUES(300,100,200);
1956 UPDATE tce71 set b = 200 where a = 100;
1957 SELECT * FROM tce71, tce72;
1959 } {100 200 300 100 200}
1960 do_test fkey2-ce7c13.1.2 {
1962 UPDATE tce71 set b = 201 where a = 100;
1964 } {1 {foreign key constraint failed}}
1965 do_test fkey2-ce7c13.1.3 {
1967 UPDATE tce71 set a = 101 where a = 100;
1969 } {1 {foreign key constraint failed}}
1970 do_test fkey2-ce7c13.1.4 {
1972 CREATE TABLE tce73(a INTEGER PRIMARY KEY, b, UNIQUE(a,b));
1973 INSERT INTO tce73 VALUES(100,200);
1974 CREATE TABLE tce74(w, x, y, FOREIGN KEY(x,y) REFERENCES tce73(a,b));
1975 INSERT INTO tce74 VALUES(300,100,200);
1976 UPDATE tce73 set b = 200 where a = 100;
1977 SELECT * FROM tce73, tce74;
1979 } {100 200 300 100 200}
1980 do_test fkey2-ce7c13.1.5 {
1982 UPDATE tce73 set b = 201 where a = 100;
1984 } {1 {foreign key constraint failed}}
1985 do_test fkey2-ce7c13.1.6 {
1987 UPDATE tce73 set a = 101 where a = 100;
1989 } {1 {foreign key constraint failed}}