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 on WITHOUT ROWID
17 set testdir [file dirname $argv0]
18 source $testdir/tester.tcl
20 ifcapable {!foreignkey||!trigger} {
25 #-------------------------------------------------------------------------
28 # without_rowid3-1.*: Simple tests to check that immediate and deferred foreign key
29 # constraints work when not inside a transaction.
31 # without_rowid3-2.*: Tests to verify that deferred foreign keys work inside
32 # explicit transactions (i.e that processing really is deferred).
34 # without_rowid3-3.*: Tests that a statement transaction is rolled back if an
35 # immediate foreign key constraint is violated.
37 # without_rowid3-4.*: Test that FK actions may recurse even when recursive triggers
40 # without_rowid3-5.*: Check that if foreign-keys are enabled, it is not possible
41 # to write to an FK column using the incremental blob API.
43 # without_rowid3-6.*: Test that FK processing is automatically disabled when
46 # without_rowid3-7.*: Test using an IPK as the key in the child (referencing) table.
48 # without_rowid3-8.*: Test that enabling/disabling foreign key support while a
49 # transaction is active is not possible.
51 # without_rowid3-9.*: Test SET DEFAULT actions.
53 # without_rowid3-10.*: Test errors.
55 # without_rowid3-11.*: Test CASCADE actions.
57 # without_rowid3-12.*: Test RESTRICT actions.
59 # without_rowid3-13.*: Test that FK processing is performed when a row is REPLACED by
60 # an UPDATE or INSERT statement.
62 # without_rowid3-14.*: Test the ALTER TABLE and DROP TABLE commands.
64 # without_rowid3-15.*: Test that if there are no (known) outstanding foreign key
65 # constraint violations in the database, inserting into a parent
66 # table or deleting from a child table does not cause SQLite
67 # to check if this has repaired an outstanding violation.
69 # without_rowid3-16.*: Test that rows that refer to themselves may be inserted,
70 # updated and deleted.
72 # without_rowid3-17.*: Test that the "count_changes" pragma does not interfere with
73 # FK constraint processing.
75 # without_rowid3-18.*: Test that the authorization callback is invoked when processing
78 # without_rowid3-20.*: Test that ON CONFLICT clauses specified as part of statements
79 # do not affect the operation of FK constraints.
81 # without_rowid3-genfkey.*: Tests that were used with the shell tool .genfkey
82 # command. Recycled to test the built-in implementation.
84 # without_rowid3-dd08e5.*: Tests to verify that ticket dd08e5a988d00decc4a543daa8d
89 execsql { PRAGMA foreign_keys = on }
91 set FkeySimpleSchema {
92 PRAGMA foreign_keys = on;
93 CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT rowid;
94 CREATE TABLE t2(c REFERENCES t1(a) /D/ , d);
96 CREATE TABLE t3(a PRIMARY KEY, b) WITHOUT rowid;
97 CREATE TABLE t4(c REFERENCES t3 /D/, d);
99 CREATE TABLE t7(a, b INT PRIMARY KEY) WITHOUT rowid;
100 CREATE TABLE t8(c REFERENCES t7 /D/, d);
102 CREATE TABLE t9(a REFERENCES nosuchtable, b);
103 CREATE TABLE t10(a REFERENCES t9(c) /D/, b);
107 set FkeySimpleTests {
108 1.1 "INSERT INTO t2 VALUES(1, 3)" {1 {FOREIGN KEY constraint failed}}
109 1.2 "INSERT INTO t1 VALUES(1, 2)" {0 {}}
110 1.3 "INSERT INTO t2 VALUES(1, 3)" {0 {}}
111 1.4 "INSERT INTO t2 VALUES(2, 4)" {1 {FOREIGN KEY constraint failed}}
112 1.5 "INSERT INTO t2 VALUES(NULL, 4)" {0 {}}
113 1.6 "UPDATE t2 SET c=2 WHERE d=4" {1 {FOREIGN KEY constraint failed}}
114 1.7 "UPDATE t2 SET c=1 WHERE d=4" {0 {}}
115 1.9 "UPDATE t2 SET c=1 WHERE d=4" {0 {}}
116 1.10 "UPDATE t2 SET c=NULL WHERE d=4" {0 {}}
117 1.11 "DELETE FROM t1 WHERE a=1" {1 {FOREIGN KEY constraint failed}}
118 1.12 "UPDATE t1 SET a = 2" {1 {FOREIGN KEY constraint failed}}
119 1.13 "UPDATE t1 SET a = 1" {0 {}}
121 2.1 "INSERT INTO t4 VALUES(1, 3)" {1 {FOREIGN KEY constraint failed}}
122 2.2 "INSERT INTO t3 VALUES(1, 2)" {0 {}}
123 2.3 "INSERT INTO t4 VALUES(1, 3)" {0 {}}
125 4.1 "INSERT INTO t8 VALUES(1, 3)" {1 {FOREIGN KEY constraint failed}}
126 4.2 "INSERT INTO t7 VALUES(2, 1)" {0 {}}
127 4.3 "INSERT INTO t8 VALUES(1, 3)" {0 {}}
128 4.4 "INSERT INTO t8 VALUES(2, 4)" {1 {FOREIGN KEY constraint failed}}
129 4.5 "INSERT INTO t8 VALUES(NULL, 4)" {0 {}}
130 4.6 "UPDATE t8 SET c=2 WHERE d=4" {1 {FOREIGN KEY constraint failed}}
131 4.7 "UPDATE t8 SET c=1 WHERE d=4" {0 {}}
132 4.9 "UPDATE t8 SET c=1 WHERE d=4" {0 {}}
133 4.10 "UPDATE t8 SET c=NULL WHERE d=4" {0 {}}
134 4.11 "DELETE FROM t7 WHERE b=1" {1 {FOREIGN KEY constraint failed}}
135 4.12 "UPDATE t7 SET b = 2" {1 {FOREIGN KEY constraint failed}}
136 4.13 "UPDATE t7 SET b = 1" {0 {}}
137 4.14 "INSERT INTO t8 VALUES('a', 'b')" {1 {FOREIGN KEY constraint failed}}
138 4.15 "UPDATE t7 SET b = 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 without_rowid3-1.1.0 {
147 execsql [string map {/D/ {}} $FkeySimpleSchema]
149 foreach {tn zSql res} $FkeySimpleTests {
150 do_test without_rowid3-1.1.$tn.1 { catchsql $zSql } $res
151 do_test without_rowid3-1.1.$tn.2 { execsql {PRAGMA foreign_key_check(t1)} } {}
152 do_test without_rowid3-1.1.$tn.3 { execsql {PRAGMA foreign_key_check(t2)} } {}
153 do_test without_rowid3-1.1.$tn.4 { execsql {PRAGMA foreign_key_check(t3)} } {}
154 do_test without_rowid3-1.1.$tn.5 { execsql {PRAGMA foreign_key_check(t4)} } {}
155 do_test without_rowid3-1.1.$tn.6 { execsql {PRAGMA foreign_key_check(t7)} } {}
156 do_test without_rowid3-1.1.$tn.7 { execsql {PRAGMA foreign_key_check(t8)} } {}
160 do_test without_rowid3-1.2.0 {
161 execsql [string map {/D/ {DEFERRABLE INITIALLY DEFERRED}} $FkeySimpleSchema]
163 foreach {tn zSql res} $FkeySimpleTests {
164 do_test without_rowid3-1.2.$tn { catchsql $zSql } $res
165 do_test without_rowid3-1.2.$tn.2 { execsql {PRAGMA foreign_key_check(t1)} } {}
166 do_test without_rowid3-1.2.$tn.3 { execsql {PRAGMA foreign_key_check(t2)} } {}
167 do_test without_rowid3-1.2.$tn.4 { execsql {PRAGMA foreign_key_check(t3)} } {}
168 do_test without_rowid3-1.2.$tn.5 { execsql {PRAGMA foreign_key_check(t4)} } {}
169 do_test without_rowid3-1.2.$tn.6 { execsql {PRAGMA foreign_key_check(t7)} } {}
170 do_test without_rowid3-1.2.$tn.7 { execsql {PRAGMA foreign_key_check(t8)} } {}
174 do_test without_rowid3-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 without_rowid3-1.3.$tn { catchsql $zSql } $res
181 do_test without_rowid3-1.3.$tn.2 { execsql {PRAGMA foreign_key_check(t1)} } {}
182 do_test without_rowid3-1.3.$tn.3 { execsql {PRAGMA foreign_key_check(t2)} } {}
183 do_test without_rowid3-1.3.$tn.4 { execsql {PRAGMA foreign_key_check(t3)} } {}
184 do_test without_rowid3-1.3.$tn.5 { execsql {PRAGMA foreign_key_check(t4)} } {}
185 do_test without_rowid3-1.3.$tn.6 { execsql {PRAGMA foreign_key_check(t7)} } {}
186 do_test without_rowid3-1.3.$tn.7 { execsql {PRAGMA foreign_key_check(t8)} } {}
188 execsql { PRAGMA count_changes = 0 }
191 do_test without_rowid3-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 without_rowid3-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 without_rowid3-1.5.1 {
209 CREATE TABLE i(i INT PRIMARY KEY) WITHOUT rowid;
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 without_rowid3-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 without_rowid3-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 without_rowid3-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 without_rowid3-1.7.1 {
240 CREATE TABLE i(i TEXT COLLATE nocase PRIMARY KEY) WITHOUT rowid;
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 without_rowid3-1.7.2 {
253 CREATE TABLE i(i TEXT PRIMARY KEY) WITHOUT rowid; -- 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 without_rowid3-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 without_rowid3-2.*) contains tests to check that the
270 # deferred foreign key constraint logic works.
272 proc without_rowid3-2-test {tn nocommit sql {res {}}} {
274 set expected {1 {FOREIGN KEY constraint failed}}
276 set expected [list 0 $res]
278 do_test without_rowid3-2.$tn [list catchsql $sql] $expected
280 do_test without_rowid3-2.${tn}c {
282 } {1 {FOREIGN KEY constraint failed}}
286 without_rowid3-2-test 1 0 {
289 parent REFERENCES node DEFERRABLE INITIALLY DEFERRED
293 parent REFERENCES node DEFERRABLE INITIALLY DEFERRED
297 without_rowid3-2-test 1 0 "INSERT INTO node VALUES(1, 0)" FKV
298 without_rowid3-2-test 2 0 "BEGIN"
299 without_rowid3-2-test 3 1 "INSERT INTO node VALUES(1, 0)"
300 without_rowid3-2-test 4 0 "UPDATE node SET parent = NULL"
301 without_rowid3-2-test 5 0 "COMMIT"
302 without_rowid3-2-test 6 0 "SELECT * FROM node" {1 {}}
304 without_rowid3-2-test 7 0 "BEGIN"
305 without_rowid3-2-test 8 1 "INSERT INTO leaf VALUES('a', 2)"
306 without_rowid3-2-test 9 1 "INSERT INTO node VALUES(2, 0)"
307 without_rowid3-2-test 10 0 "UPDATE node SET parent = 1 WHERE nodeid = 2"
308 without_rowid3-2-test 11 0 "COMMIT"
309 without_rowid3-2-test 12 0 "SELECT * FROM node" {1 {} 2 1}
310 without_rowid3-2-test 13 0 "SELECT * FROM leaf" {a 2}
312 without_rowid3-2-test 14 0 "BEGIN"
313 without_rowid3-2-test 15 1 "DELETE FROM node WHERE nodeid = 2"
314 without_rowid3-2-test 16 0 "INSERT INTO node VALUES(2, NULL)"
315 without_rowid3-2-test 17 0 "COMMIT"
316 without_rowid3-2-test 18 0 "SELECT * FROM node" {1 {} 2 {}}
317 without_rowid3-2-test 19 0 "SELECT * FROM leaf" {a 2}
319 without_rowid3-2-test 20 0 "BEGIN"
320 without_rowid3-2-test 21 0 "INSERT INTO leaf VALUES('b', 1)"
321 without_rowid3-2-test 22 0 "SAVEPOINT save"
322 without_rowid3-2-test 23 0 "DELETE FROM node WHERE nodeid = 1"
323 without_rowid3-2-test 24 0 "ROLLBACK TO save"
324 without_rowid3-2-test 25 0 "COMMIT"
325 without_rowid3-2-test 26 0 "SELECT * FROM node" {1 {} 2 {}}
326 without_rowid3-2-test 27 0 "SELECT * FROM leaf" {a 2 b 1}
328 without_rowid3-2-test 28 0 "BEGIN"
329 without_rowid3-2-test 29 0 "INSERT INTO leaf VALUES('c', 1)"
330 without_rowid3-2-test 30 0 "SAVEPOINT save"
331 without_rowid3-2-test 31 0 "DELETE FROM node WHERE nodeid = 1"
332 without_rowid3-2-test 32 1 "RELEASE save"
333 without_rowid3-2-test 33 1 "DELETE FROM leaf WHERE cellid = 'b'"
334 without_rowid3-2-test 34 0 "DELETE FROM leaf WHERE cellid = 'c'"
335 without_rowid3-2-test 35 0 "COMMIT"
336 without_rowid3-2-test 36 0 "SELECT * FROM node" {2 {}}
337 without_rowid3-2-test 37 0 "SELECT * FROM leaf" {a 2}
339 without_rowid3-2-test 38 0 "SAVEPOINT outer"
340 without_rowid3-2-test 39 1 "INSERT INTO leaf VALUES('d', 3)"
341 without_rowid3-2-test 40 1 "RELEASE outer" FKV
342 without_rowid3-2-test 41 1 "INSERT INTO leaf VALUES('e', 3)"
343 without_rowid3-2-test 42 0 "INSERT INTO node VALUES(3, 2)"
344 without_rowid3-2-test 43 0 "RELEASE outer"
346 without_rowid3-2-test 44 0 "SAVEPOINT outer"
347 without_rowid3-2-test 45 1 "DELETE FROM node WHERE nodeid=3"
348 without_rowid3-2-test 47 0 "INSERT INTO node VALUES(3, 2)"
349 without_rowid3-2-test 48 0 "ROLLBACK TO outer"
350 without_rowid3-2-test 49 0 "RELEASE outer"
352 without_rowid3-2-test 50 0 "SAVEPOINT outer"
353 without_rowid3-2-test 51 1 "INSERT INTO leaf VALUES('f', 4)"
354 without_rowid3-2-test 52 1 "SAVEPOINT inner"
355 without_rowid3-2-test 53 1 "INSERT INTO leaf VALUES('g', 4)"
356 without_rowid3-2-test 54 1 "RELEASE outer" FKV
357 without_rowid3-2-test 55 1 "ROLLBACK TO inner"
358 without_rowid3-2-test 56 0 "COMMIT" FKV
359 without_rowid3-2-test 57 0 "INSERT INTO node VALUES(4, NULL)"
360 without_rowid3-2-test 58 0 "RELEASE outer"
361 without_rowid3-2-test 59 0 "SELECT * FROM node" {2 {} 3 2 4 {}}
362 without_rowid3-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 without_rowid3-2-test 61 0 "BEGIN"
371 without_rowid3-2-test 62 0 "DELETE FROM leaf"
372 without_rowid3-2-test 63 0 "DELETE FROM node"
373 without_rowid3-2-test 64 1 "INSERT INTO leaf VALUES('a', 1)"
374 without_rowid3-2-test 65 1 "INSERT INTO leaf VALUES('b', 2)"
375 without_rowid3-2-test 66 1 "INSERT INTO leaf VALUES('c', 1)"
376 do_test without_rowid3-2-test-67 {
377 catchsql "INSERT INTO node SELECT parent, 3 FROM leaf"
378 } {1 {UNIQUE constraint failed: node.nodeid}}
379 without_rowid3-2-test 68 0 "COMMIT" FKV
380 without_rowid3-2-test 69 1 "INSERT INTO node VALUES(1, NULL)"
381 without_rowid3-2-test 70 0 "INSERT INTO node VALUES(2, NULL)"
382 without_rowid3-2-test 71 0 "COMMIT"
384 without_rowid3-2-test 72 0 "BEGIN"
385 without_rowid3-2-test 73 1 "DELETE FROM node"
386 without_rowid3-2-test 74 0 "INSERT INTO node(nodeid) SELECT DISTINCT parent FROM leaf"
387 without_rowid3-2-test 75 0 "COMMIT"
389 #-------------------------------------------------------------------------
390 # Test cases without_rowid3-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 # without_rowid3-3.1.*: Test UPDATE statements.
395 # without_rowid3-3.2.*: Test DELETE statements.
398 do_test without_rowid3-3.1.1 {
400 CREATE TABLE ab(a PRIMARY KEY, b) WITHOUT rowid;
402 c PRIMARY KEY REFERENCES ab ON UPDATE CASCADE ON DELETE CASCADE,
406 e REFERENCES cd ON UPDATE CASCADE,
411 do_test without_rowid3-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 without_rowid3-3.1.3 {
419 catchsql { UPDATE ab SET a = 5 }
420 } {1 {CHECK constraint failed: e!=5}}
421 do_test without_rowid3-3.1.4 {
422 execsql { SELECT * FROM ab }
424 do_test without_rowid3-3.1.4 {
426 catchsql { UPDATE ab SET a = 5 }
427 } {1 {CHECK constraint failed: e!=5}}
428 do_test without_rowid3-3.1.5 {
430 execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef }
433 do_test without_rowid3-3.2.1 {
435 catchsql { DELETE FROM ab }
436 } {1 {FOREIGN KEY constraint failed}}
437 do_test without_rowid3-3.2.2 {
439 execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef }
442 #-------------------------------------------------------------------------
443 # Test cases without_rowid3-4.* test that recursive foreign key actions
444 # (i.e. CASCADE) are allowed even if recursive triggers are disabled.
447 do_test without_rowid3-4.1 {
451 parent REFERENCES t1 ON DELETE CASCADE
453 CREATE TABLE t2(node PRIMARY KEY, parent) WITHOUT rowid;
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;
467 do_test without_rowid3-4.2 {
468 execsql { PRAGMA recursive_triggers = off }
471 DELETE FROM t1 WHERE node = 1;
475 do_test without_rowid3-4.3 {
477 DELETE FROM t2 WHERE node = 1;
482 do_test without_rowid3-4.4 {
483 execsql { PRAGMA recursive_triggers = on }
486 DELETE FROM t1 WHERE node = 1;
490 do_test without_rowid3-4.3 {
492 DELETE FROM t2 WHERE node = 1;
498 #-------------------------------------------------------------------------
499 # Test cases without_rowid3-5.* verify that the incremental blob API may not
500 # write to a foreign key column while foreign-keys are enabled.
504 do_test without_rowid3-5.1 {
506 CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT rowid;
507 CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1(a)) WITHOUT rowid;
508 INSERT INTO t1 VALUES('hello', 'world');
509 INSERT INTO t2 VALUES('key', 'hello');
512 do_test without_rowid3-5.2 {
513 set rc [catch { set fd [db incrblob t2 b 1] } msg]
515 } {1 {cannot open table without rowid: t2}}
516 do_test without_rowid3-5.5 {
517 execsql { PRAGMA foreign_keys = on }
523 do_test without_rowid3-6.1 {
525 CREATE TABLE t1(a REFERENCES t2(c), b);
526 CREATE TABLE t2(c UNIQUE, b);
527 INSERT INTO t2 VALUES(1, 2);
528 INSERT INTO t1 VALUES(1, 2);
534 #-------------------------------------------------------------------------
535 # Test that it is possible to use an INT PRIMARY KEY as the child key
536 # of a foreign constraint.
539 do_test without_rowid3-7.1 {
541 CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT rowid;
542 CREATE TABLE t2(c INT PRIMARY KEY REFERENCES t1, b) WITHOUT rowid;
545 do_test without_rowid3-7.2 {
546 catchsql { INSERT INTO t2 VALUES(1, 'A'); }
547 } {1 {FOREIGN KEY constraint failed}}
548 do_test without_rowid3-7.3 {
550 INSERT INTO t1 VALUES(1, 2);
551 INSERT INTO t1 VALUES(2, 3);
552 INSERT INTO t2 VALUES(1, 'A');
555 do_test without_rowid3-7.4 {
556 execsql { UPDATE t2 SET c = 2 }
558 do_test without_rowid3-7.5 {
559 catchsql { UPDATE t2 SET c = 3 }
560 } {1 {FOREIGN KEY constraint failed}}
561 do_test without_rowid3-7.6 {
562 catchsql { DELETE FROM t1 WHERE a = 2 }
563 } {1 {FOREIGN KEY constraint failed}}
564 do_test without_rowid3-7.7 {
565 execsql { DELETE FROM t1 WHERE a = 1 }
567 do_test without_rowid3-7.8 {
568 catchsql { UPDATE t1 SET a = 3 }
569 } {1 {FOREIGN KEY constraint failed}}
571 #-------------------------------------------------------------------------
572 # Test that it is not possible to enable/disable FK support while a
573 # transaction is open.
576 proc without_rowid3-8-test {tn zSql value} {
577 do_test without_rowid3-2.8.$tn.1 [list execsql $zSql] {}
578 do_test without_rowid3-2.8.$tn.2 { execsql "PRAGMA foreign_keys" } $value
580 without_rowid3-8-test 1 { PRAGMA foreign_keys = 0 } 0
581 without_rowid3-8-test 2 { PRAGMA foreign_keys = 1 } 1
582 without_rowid3-8-test 3 { BEGIN } 1
583 without_rowid3-8-test 4 { PRAGMA foreign_keys = 0 } 1
584 without_rowid3-8-test 5 { COMMIT } 1
585 without_rowid3-8-test 6 { PRAGMA foreign_keys = 0 } 0
586 without_rowid3-8-test 7 { BEGIN } 0
587 without_rowid3-8-test 8 { PRAGMA foreign_keys = 1 } 0
588 without_rowid3-8-test 9 { COMMIT } 0
589 without_rowid3-8-test 10 { PRAGMA foreign_keys = 1 } 1
590 without_rowid3-8-test 11 { PRAGMA foreign_keys = off } 0
591 without_rowid3-8-test 12 { PRAGMA foreign_keys = on } 1
592 without_rowid3-8-test 13 { PRAGMA foreign_keys = no } 0
593 without_rowid3-8-test 14 { PRAGMA foreign_keys = yes } 1
594 without_rowid3-8-test 15 { PRAGMA foreign_keys = false } 0
595 without_rowid3-8-test 16 { PRAGMA foreign_keys = true } 1
597 #-------------------------------------------------------------------------
598 # The following tests, without_rowid3-9.*, test SET DEFAULT actions.
601 do_test without_rowid3-9.1.1 {
603 CREATE TABLE t1(a INT PRIMARY KEY, b) WITHOUT rowid;
606 d INTEGER DEFAULT 1 REFERENCES t1 ON DELETE SET DEFAULT
611 do_test without_rowid3-9.1.2 {
613 INSERT INTO t1 VALUES(1, 'one');
614 INSERT INTO t1 VALUES(2, 'two');
615 INSERT INTO t2 VALUES(1, 2);
617 DELETE FROM t1 WHERE a = 2;
621 do_test without_rowid3-9.1.3 {
623 INSERT INTO t1 VALUES(2, 'two');
625 DELETE FROM t1 WHERE a = 1;
629 do_test without_rowid3-9.1.4 {
630 execsql { SELECT * FROM t1 }
632 do_test without_rowid3-9.1.5 {
633 catchsql { DELETE FROM t1 }
634 } {1 {FOREIGN KEY constraint failed}}
636 do_test without_rowid3-9.2.1 {
638 CREATE TABLE pp(a, b, c, PRIMARY KEY(b, c)) WITHOUT rowid;
639 CREATE TABLE cc(d DEFAULT 3, e DEFAULT 1, f DEFAULT 2,
640 FOREIGN KEY(f, d) REFERENCES pp
641 ON UPDATE SET DEFAULT
644 INSERT INTO pp VALUES(1, 2, 3);
645 INSERT INTO pp VALUES(4, 5, 6);
646 INSERT INTO pp VALUES(7, 8, 9);
649 do_test without_rowid3-9.2.2 {
651 INSERT INTO cc VALUES(6, 'A', 5);
652 INSERT INTO cc VALUES(6, 'B', 5);
653 INSERT INTO cc VALUES(9, 'A', 8);
654 INSERT INTO cc VALUES(9, 'B', 8);
655 UPDATE pp SET b = 1 WHERE a = 7;
658 } {6 A 5 6 B 5 3 A 2 3 B 2}
659 do_test without_rowid3-9.2.3 {
661 DELETE FROM pp WHERE a = 4;
664 } {{} A {} {} B {} 3 A 2 3 B 2}
666 #-------------------------------------------------------------------------
667 # The following tests, without_rowid3-10.*, test "foreign key mismatch" and
672 CREATE TABLE p(a PRIMARY KEY, b) WITHOUT rowid;
673 CREATE TABLE c(x REFERENCES p(c));
675 CREATE TABLE c(x REFERENCES v(y));
676 CREATE VIEW v AS SELECT x AS y FROM c;
678 CREATE TABLE p(a, b, PRIMARY KEY(a, b)) WITHOUT rowid;
679 CREATE TABLE c(x REFERENCES p);
681 CREATE TABLE p(a COLLATE binary, b);
682 CREATE UNIQUE INDEX i ON p(a COLLATE nocase);
683 CREATE TABLE c(x REFERENCES p(a));
686 do_test without_rowid3-10.1.[incr tn] {
688 catchsql { INSERT INTO c DEFAULT VALUES }
689 } {/1 {foreign key mismatch - "c" referencing "."}/}
692 # "rowid" cannot be used as part of a child or parent key definition
693 # unless it happens to be the name of an explicitly declared column.
695 do_test without_rowid3-10.2.1 {
698 CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT rowid;
699 CREATE TABLE t2(c, d, FOREIGN KEY(rowid) REFERENCES t1(a));
701 } {1 {unknown column "rowid" in foreign key definition}}
702 do_test without_rowid3-10.2.2 {
705 CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT rowid;
706 CREATE TABLE t2(rowid, d, FOREIGN KEY(rowid) REFERENCES t1(a));
709 do_test without_rowid3-10.2.1 {
712 CREATE TABLE t1(a, b);
713 CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(rowid));
714 INSERT INTO t1(rowid, a, b) VALUES(1, 1, 1);
715 INSERT INTO t2 VALUES(1, 1);
717 } {1 {foreign key mismatch - "t2" referencing "t1"}}
718 do_test without_rowid3-10.2.2 {
721 CREATE TABLE t1(rowid PRIMARY KEY, b) WITHOUT rowid;
722 CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(rowid));
723 INSERT INTO t1(rowid, b) VALUES(1, 1);
724 INSERT INTO t2 VALUES(1, 1);
729 #-------------------------------------------------------------------------
730 # The following tests, without_rowid3-11.*, test CASCADE actions.
733 do_test without_rowid3-11.1.1 {
735 CREATE TABLE t1(a INT PRIMARY KEY, b) WITHOUT rowid;
736 CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(a) ON UPDATE CASCADE);
738 INSERT INTO t1 VALUES(10, 100);
739 INSERT INTO t2 VALUES(10, 100);
740 UPDATE t1 SET a = 15;
745 #-------------------------------------------------------------------------
746 # The following tests, without_rowid3-12.*, test RESTRICT actions.
749 do_test without_rowid3-12.1.1 {
751 CREATE TABLE t1(a, b PRIMARY KEY) WITHOUT rowid;
753 x REFERENCES t1 ON UPDATE RESTRICT DEFERRABLE INITIALLY DEFERRED
755 INSERT INTO t1 VALUES(1, 'one');
756 INSERT INTO t1 VALUES(2, 'two');
757 INSERT INTO t1 VALUES(3, 'three');
760 do_test without_rowid3-12.1.2 {
762 execsql "INSERT INTO t2 VALUES('two')"
764 do_test without_rowid3-12.1.3 {
765 execsql "UPDATE t1 SET b = 'four' WHERE b = 'one'"
767 do_test without_rowid3-12.1.4 {
768 catchsql "UPDATE t1 SET b = 'five' WHERE b = 'two'"
769 } {1 {FOREIGN KEY constraint failed}}
770 do_test without_rowid3-12.1.5 {
771 execsql "DELETE FROM t1 WHERE b = 'two'"
773 do_test without_rowid3-12.1.6 {
775 } {1 {FOREIGN KEY constraint failed}}
776 do_test without_rowid3-12.1.7 {
778 INSERT INTO t1 VALUES(2, 'two');
784 do_test without_rowid3-12.2.1 {
786 CREATE TABLE t1(x COLLATE NOCASE PRIMARY KEY) WITHOUT rowid;
787 CREATE TRIGGER tt1 AFTER DELETE ON t1
788 WHEN EXISTS ( SELECT 1 FROM t2 WHERE old.x = y )
790 INSERT INTO t1 VALUES(old.x);
792 CREATE TABLE t2(y REFERENCES t1);
793 INSERT INTO t1 VALUES('A');
794 INSERT INTO t1 VALUES('B');
795 INSERT INTO t2 VALUES('a');
796 INSERT INTO t2 VALUES('b');
802 do_test without_rowid3-12.2.2 {
803 execsql { DELETE FROM t1 }
809 do_test without_rowid3-12.2.3 {
812 CREATE TABLE t2(y REFERENCES t1 ON DELETE RESTRICT);
813 INSERT INTO t2 VALUES('a');
814 INSERT INTO t2 VALUES('b');
816 catchsql { DELETE FROM t1 }
817 } {1 {FOREIGN KEY constraint failed}}
818 do_test without_rowid3-12.2.4 {
826 do_test without_rowid3-12.3.1 {
829 c00, c01, c02, c03, c04, c05, c06, c07, c08, c09,
830 c10, c11, c12, c13, c14, c15, c16, c17, c18, c19,
831 c20, c21, c22, c23, c24, c25, c26, c27, c28, c29,
832 c30, c31, c32, c33, c34, c35, c36, c37, c38, c39,
833 PRIMARY KEY(c34, c35)
836 c00, c01, c02, c03, c04, c05, c06, c07, c08, c09,
837 c10, c11, c12, c13, c14, c15, c16, c17, c18, c19,
838 c20, c21, c22, c23, c24, c25, c26, c27, c28, c29,
839 c30, c31, c32, c33, c34, c35, c36, c37, c38, c39,
840 FOREIGN KEY(c39, c38) REFERENCES up ON UPDATE CASCADE
844 do_test without_rowid3-12.3.2 {
846 INSERT INTO up(c34, c35) VALUES('yes', 'no');
847 INSERT INTO down(c39, c38) VALUES('yes', 'no');
848 UPDATE up SET c34 = 'possibly';
849 SELECT c38, c39 FROM down;
853 do_test without_rowid3-12.3.3 {
854 catchsql { INSERT INTO down(c39, c38) VALUES('yes', 'no') }
855 } {1 {FOREIGN KEY constraint failed}}
856 do_test without_rowid3-12.3.4 {
858 INSERT INTO up(c34, c35) VALUES('yes', 'no');
859 INSERT INTO down(c39, c38) VALUES('yes', 'no');
861 catchsql { DELETE FROM up WHERE c34 = 'yes' }
862 } {1 {FOREIGN KEY constraint failed}}
863 do_test without_rowid3-12.3.5 {
865 DELETE FROM up WHERE c34 = 'possibly';
866 SELECT c34, c35 FROM up;
867 SELECT c39, c38 FROM down;
871 #-------------------------------------------------------------------------
872 # The following tests, without_rowid3-13.*, test that FK processing is performed
873 # when rows are REPLACEd.
876 do_test without_rowid3-13.1.1 {
878 CREATE TABLE pp(a UNIQUE, b, c, PRIMARY KEY(b, c)) WITHOUT rowid;
879 CREATE TABLE cc(d, e, f UNIQUE, FOREIGN KEY(d, e) REFERENCES pp);
880 INSERT INTO pp VALUES(1, 2, 3);
881 INSERT INTO cc VALUES(2, 3, 1);
885 1 "REPLACE INTO pp VALUES(1, 4, 5)"
887 do_test without_rowid3-13.1.$tn.1 {
889 } {1 {FOREIGN KEY constraint failed}}
890 do_test without_rowid3-13.1.$tn.2 {
896 do_test without_rowid3-13.1.$tn.3 {
899 } {1 {FOREIGN KEY constraint failed}}
900 do_test without_rowid3-13.1.$tn.4 {
909 #-------------------------------------------------------------------------
910 # The following tests, without_rowid3-14.*, test that the "DROP TABLE" and "ALTER
911 # TABLE" commands work as expected wrt foreign key constraints.
913 # without_rowid3-14.1*: ALTER TABLE ADD COLUMN
914 # without_rowid3-14.2*: ALTER TABLE RENAME TABLE
915 # without_rowid3-14.3*: DROP TABLE
918 ifcapable altertable {
919 do_test without_rowid3-14.1.1 {
920 # Adding a column with a REFERENCES clause is not supported.
922 CREATE TABLE t1(a PRIMARY KEY) WITHOUT rowid;
923 CREATE TABLE t2(a, b);
924 INSERT INTO t2(a,b) VALUES(1,2);
926 catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
928 do_test without_rowid3-14.1.2 {
929 catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
931 do_test without_rowid3-14.1.3 {
932 catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}
934 do_test without_rowid3-14.1.4 {
935 catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'}
936 } {1 {Cannot add a REFERENCES column with non-NULL default value}}
937 do_test without_rowid3-14.1.5 {
938 catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 }
939 } {1 {Cannot add a REFERENCES column with non-NULL default value}}
940 do_test without_rowid3-14.1.6 {
942 PRAGMA foreign_keys = off;
943 ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
944 PRAGMA foreign_keys = on;
945 SELECT sql FROM sqlite_schema WHERE name='t2';
947 } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
950 # Test the sqlite_rename_parent() function directly.
952 proc test_rename_parent {zCreate zOld zNew} {
953 db eval {SELECT sqlite_rename_table(
954 'main', 'table', 't1', $zCreate, $zOld, $zNew, 0
957 sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
958 do_test without_rowid3-14.2.1.1 {
959 test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
960 } {{CREATE TABLE t1(a REFERENCES "t3")}}
961 do_test without_rowid3-14.2.1.2 {
962 test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
963 } {{CREATE TABLE t1(a REFERENCES t2)}}
964 do_test without_rowid3-14.2.1.3 {
965 test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
966 } {{CREATE TABLE t1(a REFERENCES "t3")}}
967 sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
969 # Test ALTER TABLE RENAME TABLE a bit.
971 do_test without_rowid3-14.2.2.1 {
974 CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid;
975 CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)
977 CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
979 execsql { SELECT sql FROM sqlite_schema WHERE type = 'table'}
981 {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid} \
982 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)
984 {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)} \
986 do_test without_rowid3-14.2.2.2 {
987 execsql { ALTER TABLE t1 RENAME TO t4 }
988 execsql { SELECT sql FROM sqlite_schema WHERE type = 'table'}
990 {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid} \
991 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)
993 {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \
995 do_test without_rowid3-14.2.2.3 {
996 catchsql { INSERT INTO t3 VALUES(1, 2, 3) }
997 } {1 {FOREIGN KEY constraint failed}}
998 do_test without_rowid3-14.2.2.4 {
999 execsql { INSERT INTO t4 VALUES(1, NULL) }
1001 do_test without_rowid3-14.2.2.5 {
1002 catchsql { UPDATE t4 SET b = 5 }
1003 } {1 {FOREIGN KEY constraint failed}}
1004 do_test without_rowid3-14.2.2.6 {
1005 catchsql { UPDATE t4 SET b = 1 }
1007 do_test without_rowid3-14.2.2.7 {
1008 execsql { INSERT INTO t3 VALUES(1, NULL, 1) }
1011 # Repeat for TEMP tables
1014 do_test without_rowid3-14.1tmp.1 {
1015 # Adding a column with a REFERENCES clause is not supported.
1017 CREATE TEMP TABLE t1(a PRIMARY KEY) WITHOUT rowid;
1018 CREATE TEMP TABLE t2(a, b);
1019 INSERT INTO temp.t2(a,b) VALUES(1,2);
1021 catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
1023 do_test without_rowid3-14.1tmp.2 {
1024 catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
1026 do_test without_rowid3-14.1tmp.3 {
1027 catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}
1029 do_test without_rowid3-14.1tmp.4 {
1030 catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'}
1031 } {1 {Cannot add a REFERENCES column with non-NULL default value}}
1032 do_test without_rowid3-14.1tmp.5 {
1033 catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 }
1034 } {1 {Cannot add a REFERENCES column with non-NULL default value}}
1035 do_test without_rowid3-14.1tmp.6 {
1037 PRAGMA foreign_keys = off;
1038 ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
1039 PRAGMA foreign_keys = on;
1040 SELECT sql FROM temp.sqlite_schema WHERE name='t2';
1042 } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
1044 sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
1045 do_test without_rowid3-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 without_rowid3-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 without_rowid3-14.2tmp.1.3 {
1052 test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
1053 } {{CREATE TABLE t1(a REFERENCES "t3")}}
1054 sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
1056 # Test ALTER TABLE RENAME TABLE a bit.
1058 do_test without_rowid3-14.2tmp.2.1 {
1061 CREATE TEMP TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid;
1062 CREATE TEMP TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)
1064 CREATE TEMP TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
1066 execsql { SELECT sql FROM sqlite_temp_schema WHERE type = 'table'}
1068 {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid} \
1069 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)
1071 {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)} \
1073 do_test without_rowid3-14.2tmp.2.2 {
1074 execsql { ALTER TABLE t1 RENAME TO t4 }
1075 execsql { SELECT sql FROM temp.sqlite_schema WHERE type = 'table'}
1077 {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid} \
1078 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)
1080 {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \
1082 do_test without_rowid3-14.2tmp.2.3 {
1083 catchsql { INSERT INTO t3 VALUES(1, 2, 3) }
1084 } {1 {FOREIGN KEY constraint failed}}
1085 do_test without_rowid3-14.2tmp.2.4 {
1086 execsql { INSERT INTO t4 VALUES(1, NULL) }
1088 do_test without_rowid3-14.2tmp.2.5 {
1089 catchsql { UPDATE t4 SET b = 5 }
1090 } {1 {FOREIGN KEY constraint failed}}
1091 do_test without_rowid3-14.2tmp.2.6 {
1092 catchsql { UPDATE t4 SET b = 1 }
1094 do_test without_rowid3-14.2tmp.2.7 {
1095 execsql { INSERT INTO t3 VALUES(1, NULL, 1) }
1098 # Repeat for ATTACH-ed tables
1101 do_test without_rowid3-14.1aux.1 {
1102 # Adding a column with a REFERENCES clause is not supported.
1104 ATTACH ':memory:' AS aux;
1105 CREATE TABLE aux.t1(a PRIMARY KEY) WITHOUT rowid;
1106 CREATE TABLE aux.t2(a, b);
1107 INSERT INTO aux.t2(a,b) VALUES(1,2);
1109 catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
1111 do_test without_rowid3-14.1aux.2 {
1112 catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
1114 do_test without_rowid3-14.1aux.3 {
1115 catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}
1117 do_test without_rowid3-14.1aux.4 {
1118 catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'}
1119 } {1 {Cannot add a REFERENCES column with non-NULL default value}}
1120 do_test without_rowid3-14.1aux.5 {
1121 catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 }
1122 } {1 {Cannot add a REFERENCES column with non-NULL default value}}
1123 do_test without_rowid3-14.1aux.6 {
1125 PRAGMA foreign_keys = off;
1126 ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
1127 PRAGMA foreign_keys = on;
1128 SELECT sql FROM aux.sqlite_schema WHERE name='t2';
1130 } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
1132 sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
1133 do_test without_rowid3-14.2aux.1.1 {
1134 test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
1135 } {{CREATE TABLE t1(a REFERENCES "t3")}}
1136 do_test without_rowid3-14.2aux.1.2 {
1137 test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
1138 } {{CREATE TABLE t1(a REFERENCES t2)}}
1139 do_test without_rowid3-14.2aux.1.3 {
1140 test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
1141 } {{CREATE TABLE t1(a REFERENCES "t3")}}
1142 sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
1144 # Test ALTER TABLE RENAME TABLE a bit.
1146 do_test without_rowid3-14.2aux.2.1 {
1149 CREATE TABLE aux.t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid;
1150 CREATE TABLE aux.t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)
1152 CREATE TABLE aux.t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
1154 execsql { SELECT sql FROM aux.sqlite_schema WHERE type = 'table'}
1156 {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid} \
1157 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)
1159 {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)} \
1161 do_test without_rowid3-14.2aux.2.2 {
1162 execsql { ALTER TABLE t1 RENAME TO t4 }
1163 execsql { SELECT sql FROM aux.sqlite_schema WHERE type = 'table'}
1165 {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid} \
1166 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)
1168 {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \
1170 do_test without_rowid3-14.2aux.2.3 {
1171 catchsql { INSERT INTO t3 VALUES(1, 2, 3) }
1172 } {1 {FOREIGN KEY constraint failed}}
1173 do_test without_rowid3-14.2aux.2.4 {
1174 execsql { INSERT INTO t4 VALUES(1, NULL) }
1176 do_test without_rowid3-14.2aux.2.5 {
1177 catchsql { UPDATE t4 SET b = 5 }
1178 } {1 {FOREIGN KEY constraint failed}}
1179 do_test without_rowid3-14.2aux.2.6 {
1180 catchsql { UPDATE t4 SET b = 1 }
1182 do_test without_rowid3-14.2aux.2.7 {
1183 execsql { INSERT INTO t3 VALUES(1, NULL, 1) }
1187 do_test without_rowid3-2.14.3.1 {
1190 CREATE TABLE t1(a, b REFERENCES nosuchtable);
1194 do_test without_rowid3-2.14.3.2 {
1196 CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT rowid;
1197 INSERT INTO t1 VALUES('a', 1);
1198 CREATE TABLE t2(x REFERENCES t1);
1199 INSERT INTO t2 VALUES('a');
1202 do_test without_rowid3-2.14.3.3 {
1203 catchsql { DROP TABLE t1 }
1204 } {1 {FOREIGN KEY constraint failed}}
1205 do_test without_rowid3-2.14.3.4 {
1211 do_test without_rowid3-2.14.3.4 {
1212 catchsql { INSERT INTO t2 VALUES('x') }
1213 } {1 {no such table: main.t1}}
1214 do_test without_rowid3-2.14.3.5 {
1216 CREATE TABLE t1(x PRIMARY KEY) WITHOUT rowid;
1217 INSERT INTO t1 VALUES('x');
1219 execsql { INSERT INTO t2 VALUES('x') }
1221 do_test without_rowid3-2.14.3.6 {
1222 catchsql { DROP TABLE t1 }
1223 } {1 {FOREIGN KEY constraint failed}}
1224 do_test without_rowid3-2.14.3.7 {
1230 do_test without_rowid3-2.14.3.8 {
1232 CREATE TABLE pp(x, y, PRIMARY KEY(x, y)) WITHOUT ROWID;
1233 CREATE TABLE cc(a, b, FOREIGN KEY(a, b) REFERENCES pp(x, z));
1235 catchsql { INSERT INTO cc VALUES(1, 2) }
1236 } {1 {foreign key mismatch - "cc" referencing "pp"}}
1237 do_test without_rowid3-2.14.3.9 {
1238 execsql { DROP TABLE cc }
1240 do_test without_rowid3-2.14.3.10 {
1242 CREATE TABLE cc(a, b,
1243 FOREIGN KEY(a, b) REFERENCES pp DEFERRABLE INITIALLY DEFERRED
1247 INSERT INTO pp VALUES('a', 'b');
1248 INSERT INTO cc VALUES('a', 'b');
1251 CREATE TABLE pp(a, b, c, PRIMARY KEY(b, c)) WITHOUT rowid;
1252 INSERT INTO pp VALUES(1, 'a', 'b');
1256 do_test without_rowid3-2.14.3.11 {
1264 do_test without_rowid3-2.14.3.12 {
1266 CREATE TABLE b1(a, b);
1267 CREATE TABLE b2(a, b REFERENCES b1);
1271 do_test without_rowid3-2.14.3.13 {
1273 CREATE TABLE b3(a, b REFERENCES b2 DEFERRABLE INITIALLY DEFERRED);
1278 # Test that nothing goes wrong when dropping a table that refers to a view.
1279 # Or dropping a view that an existing FK (incorrectly) refers to. Or either
1280 # of the above scenarios with a virtual table.
1282 do_test without_rowid3-2.14.4.1 {
1284 CREATE TABLE t1(x REFERENCES v);
1285 CREATE VIEW v AS SELECT * FROM t1;
1288 do_test without_rowid3-2.14.4.2 {
1294 register_echo_module db
1295 do_test without_rowid3-2.14.4.3 {
1296 execsql { CREATE VIRTUAL TABLE v USING echo(t1) }
1298 do_test without_rowid3-2.14.4.2 {
1305 #-------------------------------------------------------------------------
1306 # The following tests, without_rowid3-15.*, test that unnecessary FK related scans
1307 # and lookups are avoided when the constraint counters are zero.
1310 proc execsqlS {zSql} {
1311 set ::sqlite_search_count 0
1312 set ::sqlite_found_count 0
1313 set res [uplevel [list execsql $zSql]]
1314 concat [expr $::sqlite_found_count + $::sqlite_search_count] $res
1316 do_test without_rowid3-15.1.1 {
1318 CREATE TABLE pp(a PRIMARY KEY, b) WITHOUT rowid;
1319 CREATE TABLE cc(x, y REFERENCES pp DEFERRABLE INITIALLY DEFERRED);
1320 INSERT INTO pp VALUES(1, 'one');
1321 INSERT INTO pp VALUES(2, 'two');
1322 INSERT INTO cc VALUES('neung', 1);
1323 INSERT INTO cc VALUES('song', 2);
1326 do_test without_rowid3-15.1.2 {
1327 execsqlS { INSERT INTO pp VALUES(3, 'three') }
1329 do_test without_rowid3-15.1.3 {
1332 INSERT INTO cc VALUES('see', 4); -- Violates deferred constraint
1334 execsqlS { INSERT INTO pp VALUES(5, 'five') }
1336 do_test without_rowid3-15.1.4 {
1337 execsql { DELETE FROM cc WHERE x = 'see' }
1338 execsqlS { INSERT INTO pp VALUES(6, 'six') }
1340 do_test without_rowid3-15.1.5 {
1343 do_test without_rowid3-15.1.6 {
1346 DELETE FROM cc WHERE x = 'neung';
1350 do_test without_rowid3-15.1.7 {
1353 DELETE FROM pp WHERE a = 2;
1356 DELETE FROM cc WHERE x = 'neung';
1361 #-------------------------------------------------------------------------
1362 # This next block of tests, without_rowid3-16.*, test that rows that refer to
1363 # themselves may be inserted and deleted.
1365 foreach {tn zSchema} {
1366 1 { CREATE TABLE self(a INTEGER PRIMARY KEY, b REFERENCES self(a))
1368 2 { CREATE TABLE self(a PRIMARY KEY, b REFERENCES self(a)) WITHOUT rowid }
1369 3 { CREATE TABLE self(a UNIQUE, b INT PRIMARY KEY REFERENCES self(a))
1373 do_test without_rowid3-16.1.$tn.1 {
1375 execsql { INSERT INTO self VALUES(13, 13) }
1377 do_test without_rowid3-16.1.$tn.2 {
1378 execsql { UPDATE self SET a = 14, b = 14 }
1381 do_test without_rowid3-16.1.$tn.3 {
1382 catchsql { UPDATE self SET b = 15 }
1383 } {1 {FOREIGN KEY constraint failed}}
1385 do_test without_rowid3-16.1.$tn.4 {
1386 catchsql { UPDATE self SET a = 15 }
1387 } {1 {FOREIGN KEY constraint failed}}
1389 do_test without_rowid3-16.1.$tn.5 {
1390 catchsql { UPDATE self SET a = 15, b = 16 }
1391 } {1 {FOREIGN KEY constraint failed}}
1393 do_test without_rowid3-16.1.$tn.6 {
1394 catchsql { UPDATE self SET a = 17, b = 17 }
1397 do_test without_rowid3-16.1.$tn.7 {
1398 execsql { DELETE FROM self }
1400 do_test without_rowid3-16.1.$tn.8 {
1401 catchsql { INSERT INTO self VALUES(20, 21) }
1402 } {1 {FOREIGN KEY constraint failed}}
1405 # Additional tests cases using multi-column self-referential
1406 # FOREIGN KEY constraints.
1409 do_execsql_test without_rowid3-16.4.1.1 {
1410 PRAGMA foreign_keys=ON;
1411 CREATE TABLE t1(a,b,c,d,e,f,
1414 FOREIGN KEY (d,f) REFERENCES t1(e,c)
1416 INSERT INTO t1 VALUES(1,2,3,5,5,3);
1417 INSERT INTO t1 VALUES(2,3,4,6,6,4);
1418 INSERT INTO t1 VALUES('x','y',1.5,'fizzle','fizzle',1.5);
1419 SELECT *, '|' FROM t1 ORDER BY a, b;
1420 } {1 2 3 5 5 3 | 2 3 4 6 6 4 | x y 1.5 fizzle fizzle 1.5 |}
1422 do_execsql_test without_rowid3-16.4.1.2 {
1423 UPDATE t1 SET c=99, f=99 WHERE a=1;
1424 SELECT *, '|' FROM t1 ORDER BY a, b;
1425 } {1 2 99 5 5 99 | 2 3 4 6 6 4 | x y 1.5 fizzle fizzle 1.5 |}
1427 do_execsql_test without_rowid3-16.4.1.3 {
1428 UPDATE t1 SET e=876, d=876 WHERE a=2;
1429 SELECT *, '|' FROM t1 ORDER BY a, b;
1430 } {1 2 99 5 5 99 | 2 3 4 876 876 4 | x y 1.5 fizzle fizzle 1.5 |}
1432 do_test without_rowid3-16.4.1.4 {
1434 UPDATE t1 SET c=11, e=22 WHERE a=1;
1436 } {1 {FOREIGN KEY constraint failed}}
1438 do_test without_rowid3-16.4.1.5 {
1440 UPDATE t1 SET d=11, f=22 WHERE a=1;
1442 } {1 {FOREIGN KEY constraint failed}}
1444 do_execsql_test without_rowid3-16.4.1.6 {
1445 DELETE FROM t1 WHERE a=1;
1446 SELECT *, '|' FROM t1 ORDER BY a, b;
1447 } {2 3 4 876 876 4 | x y 1.5 fizzle fizzle 1.5 |}
1449 do_execsql_test without_rowid3-16.4.2.1 {
1451 CREATE TABLE t1(a,b,c,d,e,f,
1454 FOREIGN KEY (d,f) REFERENCES t1(e,c)
1456 INSERT INTO t1 VALUES(1,2,3,5,5,3);
1457 INSERT INTO t1 VALUES(2,3,4,6,6,4);
1458 INSERT INTO t1 VALUES('x','y',1.5,'fizzle','fizzle',1.5);
1459 SELECT *, '|' FROM t1 ORDER BY a, b;
1460 } {1 2 3 5 5 3 | 2 3 4 6 6 4 | x y 1.5 fizzle fizzle 1.5 |}
1462 do_execsql_test without_rowid3-16.4.2.2 {
1463 UPDATE t1 SET c=99, f=99 WHERE a=1;
1464 SELECT *, '|' FROM t1 ORDER BY a, b;
1465 } {1 2 99 5 5 99 | 2 3 4 6 6 4 | x y 1.5 fizzle fizzle 1.5 |}
1467 do_execsql_test without_rowid3-16.4.2.3 {
1468 UPDATE t1 SET e=876, d=876 WHERE a=2;
1469 SELECT *, '|' FROM t1 ORDER BY a, b;
1470 } {1 2 99 5 5 99 | 2 3 4 876 876 4 | x y 1.5 fizzle fizzle 1.5 |}
1472 do_test without_rowid3-16.4.2.4 {
1474 UPDATE t1 SET c=11, e=22 WHERE a=1;
1476 } {1 {FOREIGN KEY constraint failed}}
1478 do_test without_rowid3-16.4.2.5 {
1480 UPDATE t1 SET d=11, f=22 WHERE a=1;
1482 } {1 {FOREIGN KEY constraint failed}}
1484 do_execsql_test without_rowid3-16.4.2.6 {
1485 DELETE FROM t1 WHERE a=1;
1486 SELECT *, '|' FROM t1 ORDER BY a, b;
1487 } {2 3 4 876 876 4 | x y 1.5 fizzle fizzle 1.5 |}
1490 #-------------------------------------------------------------------------
1491 # This next block of tests, without_rowid3-17.*, tests that if "PRAGMA count_changes"
1492 # is turned on statements that violate immediate FK constraints return
1493 # SQLITE_CONSTRAINT immediately, not after returning a number of rows.
1494 # Whereas statements that violate deferred FK constraints return the number
1495 # of rows before failing.
1497 # Also test that rows modified by FK actions are not counted in either the
1498 # returned row count or the values returned by sqlite3_changes(). Like
1499 # trigger related changes, they are included in sqlite3_total_changes() though.
1502 do_test without_rowid3-17.1.1 {
1503 execsql { PRAGMA count_changes = 1 }
1505 CREATE TABLE one(a, b, c, UNIQUE(b, c));
1506 CREATE TABLE two(d, e, f, FOREIGN KEY(e, f) REFERENCES one(b, c));
1507 INSERT INTO one VALUES(1, 2, 3);
1510 do_test without_rowid3-17.1.2 {
1511 set STMT [sqlite3_prepare_v2 db "INSERT INTO two VALUES(4, 5, 6)" -1 dummy]
1513 } {SQLITE_CONSTRAINT}
1514 verify_ex_errcode without_rowid3-17.1.2b SQLITE_CONSTRAINT_FOREIGNKEY
1515 ifcapable autoreset {
1516 do_test without_rowid3-17.1.3 {
1518 } {SQLITE_CONSTRAINT}
1519 verify_ex_errcode without_rowid3-17.1.3b SQLITE_CONSTRAINT_FOREIGNKEY
1521 do_test without_rowid3-17.1.3 {
1525 do_test without_rowid3-17.1.4 {
1526 sqlite3_finalize $STMT
1527 } {SQLITE_CONSTRAINT}
1528 verify_ex_errcode without_rowid3-17.1.4b SQLITE_CONSTRAINT_FOREIGNKEY
1529 do_test without_rowid3-17.1.5 {
1531 INSERT INTO one VALUES(2, 3, 4);
1532 INSERT INTO one VALUES(3, 4, 5);
1533 INSERT INTO two VALUES(1, 2, 3);
1534 INSERT INTO two VALUES(2, 3, 4);
1535 INSERT INTO two VALUES(3, 4, 5);
1538 do_test without_rowid3-17.1.6 {
1541 INSERT INTO one VALUES(0, 0, 0);
1542 UPDATE two SET e=e+1, f=f+1;
1544 } {1 {FOREIGN KEY constraint failed}}
1545 do_test without_rowid3-17.1.7 {
1546 execsql { SELECT * FROM one }
1547 } {1 2 3 2 3 4 3 4 5 0 0 0}
1548 do_test without_rowid3-17.1.8 {
1549 execsql { SELECT * FROM two }
1550 } {1 2 3 2 3 4 3 4 5}
1551 do_test without_rowid3-17.1.9 {
1554 do_test without_rowid3-17.1.10 {
1558 FOREIGN KEY(h, i) REFERENCES one(b, c) DEFERRABLE INITIALLY DEFERRED
1562 do_test without_rowid3-17.1.11 {
1563 set STMT [sqlite3_prepare_v2 db "INSERT INTO three VALUES(7, 8, 9)" -1 dummy]
1566 do_test without_rowid3-17.1.12 {
1567 sqlite3_column_text $STMT 0
1569 do_test without_rowid3-17.1.13 {
1571 } {SQLITE_CONSTRAINT}
1572 verify_ex_errcode without_rowid3-17.1.13b SQLITE_CONSTRAINT_FOREIGNKEY
1573 do_test without_rowid3-17.1.14 {
1574 sqlite3_finalize $STMT
1575 } {SQLITE_CONSTRAINT}
1576 verify_ex_errcode without_rowid3-17.1.14b SQLITE_CONSTRAINT_FOREIGNKEY
1579 do_test without_rowid3-17.2.1 {
1581 CREATE TABLE high("a'b!" PRIMARY KEY, b) WITHOUT rowid;
1584 "d&6" REFERENCES high ON UPDATE CASCADE ON DELETE CASCADE
1588 do_test without_rowid3-17.2.2 {
1590 INSERT INTO high VALUES('a', 'b');
1591 INSERT INTO low VALUES('b', 'a');
1595 set nTotal [db total_changes]
1596 do_test without_rowid3-17.2.3 {
1597 execsql { UPDATE high SET "a'b!" = 'c' }
1599 do_test without_rowid3-17.2.4 {
1602 do_test without_rowid3-17.2.5 {
1603 expr [db total_changes] - $nTotal
1605 do_test without_rowid3-17.2.6 {
1606 execsql { SELECT * FROM high ; SELECT * FROM low }
1608 do_test without_rowid3-17.2.7 {
1609 execsql { DELETE FROM high }
1611 do_test without_rowid3-17.2.8 {
1614 do_test without_rowid3-17.2.9 {
1615 expr [db total_changes] - $nTotal
1617 do_test without_rowid3-17.2.10 {
1618 execsql { SELECT * FROM high ; SELECT * FROM low }
1620 execsql { PRAGMA count_changes = 0 }
1622 #-------------------------------------------------------------------------
1623 # Test that the authorization callback works.
1627 do_test without_rowid3-18.1 {
1629 CREATE TABLE long(a, b PRIMARY KEY, c) WITHOUT rowid;
1630 CREATE TABLE short(d, e, f REFERENCES long);
1631 CREATE TABLE mid(g, h, i REFERENCES long DEFERRABLE INITIALLY DEFERRED);
1635 proc auth {args} {eval lappend ::authargs [lrange $args 0 4]; return SQLITE_OK}
1638 # An insert on the parent table must read the child key of any deferred
1639 # foreign key constraints. But not the child key of immediate constraints.
1641 do_test without_rowid3-18.2 {
1642 execsql { INSERT INTO long VALUES(1, 2, 3) }
1644 } {SQLITE_INSERT long {} main {} SQLITE_READ mid i main {}}
1646 # An insert on the child table of an immediate constraint must read the
1647 # parent key columns (to see if it is a violation or not).
1649 do_test without_rowid3-18.3 {
1650 execsql { INSERT INTO short VALUES(1, 3, 2) }
1652 } {SQLITE_INSERT short {} main {} SQLITE_READ long b main {}}
1654 # As must an insert on the child table of a deferred constraint.
1656 do_test without_rowid3-18.4 {
1657 execsql { INSERT INTO mid VALUES(1, 3, 2) }
1659 } {SQLITE_INSERT mid {} main {} SQLITE_READ long b main {}}
1661 do_test without_rowid3-18.5 {
1663 CREATE TABLE nought(a, b PRIMARY KEY, c) WITHOUT rowid;
1664 CREATE TABLE cross(d, e, f,
1665 FOREIGN KEY(e) REFERENCES nought(b) ON UPDATE CASCADE
1668 execsql { INSERT INTO nought VALUES(2, 1, 2) }
1669 execsql { INSERT INTO cross VALUES(0, 1, 0) }
1671 execsql { UPDATE nought SET b = 5 }
1673 } {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 {}}
1675 do_test without_rowid3-18.6 {
1676 execsql {SELECT * FROM cross}
1679 do_test without_rowid3-18.7 {
1681 CREATE TABLE one(a INT PRIMARY KEY, b) WITHOUT rowid;
1682 CREATE TABLE two(b, c REFERENCES one);
1683 INSERT INTO one VALUES(101, 102);
1686 execsql { INSERT INTO two VALUES(100, 101); }
1688 } {SQLITE_INSERT two {} main {} SQLITE_READ one a main {}}
1690 # Return SQLITE_IGNORE to requests to read from the parent table. This
1691 # causes inserts of non-NULL keys into the child table to fail.
1695 if {[lindex $args 1] == "long"} {return SQLITE_IGNORE}
1698 do_test without_rowid3-18.8 {
1699 catchsql { INSERT INTO short VALUES(1, 3, 2) }
1700 } {1 {FOREIGN KEY constraint failed}}
1701 do_test without_rowid3-18.9 {
1702 execsql { INSERT INTO short VALUES(1, 3, NULL) }
1704 do_test without_rowid3-18.10 {
1705 execsql { SELECT * FROM short }
1707 do_test without_rowid3-18.11 {
1708 catchsql { UPDATE short SET f = 2 WHERE f IS NULL }
1709 } {1 {FOREIGN KEY constraint failed}}
1716 do_test without_rowid3-19.1 {
1718 CREATE TABLE main(id INT PRIMARY KEY) WITHOUT rowid;
1719 CREATE TABLE sub(id INT REFERENCES main(id));
1720 INSERT INTO main VALUES(1);
1721 INSERT INTO main VALUES(2);
1722 INSERT INTO sub VALUES(2);
1725 do_test without_rowid3-19.2 {
1726 set S [sqlite3_prepare_v2 db "DELETE FROM main WHERE id = ?" -1 dummy]
1727 sqlite3_bind_int $S 1 2
1729 } {SQLITE_CONSTRAINT}
1730 verify_ex_errcode without_rowid3-19.2b SQLITE_CONSTRAINT_FOREIGNKEY
1731 do_test without_rowid3-19.3 {
1733 } {SQLITE_CONSTRAINT}
1734 verify_ex_errcode without_rowid3-19.3b SQLITE_CONSTRAINT_FOREIGNKEY
1735 do_test without_rowid3-19.4 {
1736 sqlite3_bind_int $S 1 1
1739 do_test without_rowid3-19.4 {
1744 do_test without_rowid3-20.1 {
1746 CREATE TABLE pp(a PRIMARY KEY, b) WITHOUT rowid;
1747 CREATE TABLE cc(c PRIMARY KEY, d REFERENCES pp) WITHOUT rowid;
1751 foreach {tn insert} {
1753 2 "INSERT OR IGNORE"
1755 4 "INSERT OR ROLLBACK"
1756 5 "INSERT OR REPLACE"
1759 do_test without_rowid3-20.2.$tn.1 {
1760 catchsql "$insert INTO cc VALUES(1, 2)"
1761 } {1 {FOREIGN KEY constraint failed}}
1762 do_test without_rowid3-20.2.$tn.2 {
1763 execsql { SELECT * FROM cc }
1765 do_test without_rowid3-20.2.$tn.3 {
1768 INSERT INTO pp VALUES(2, 'two');
1769 INSERT INTO cc VALUES(1, 2);
1771 catchsql "$insert INTO cc VALUES(3, 4)"
1772 } {1 {FOREIGN KEY constraint failed}}
1773 do_test without_rowid3-20.2.$tn.4 {
1774 execsql { COMMIT ; SELECT * FROM cc }
1776 do_test without_rowid3-20.2.$tn.5 {
1777 execsql { DELETE FROM cc ; DELETE FROM pp }
1781 foreach {tn update} {
1783 2 "UPDATE OR IGNORE"
1785 4 "UPDATE OR ROLLBACK"
1786 5 "UPDATE OR REPLACE"
1789 do_test without_rowid3-20.3.$tn.1 {
1791 INSERT INTO pp VALUES(2, 'two');
1792 INSERT INTO cc VALUES(1, 2);
1795 do_test without_rowid3-20.3.$tn.2 {
1796 catchsql "$update pp SET a = 1"
1797 } {1 {FOREIGN KEY constraint failed}}
1798 do_test without_rowid3-20.3.$tn.3 {
1799 execsql { SELECT * FROM pp }
1801 do_test without_rowid3-20.3.$tn.4 {
1802 catchsql "$update cc SET d = 1"
1803 } {1 {FOREIGN KEY constraint failed}}
1804 do_test without_rowid3-20.3.$tn.5 {
1805 execsql { SELECT * FROM cc }
1807 do_test without_rowid3-20.3.$tn.6 {
1810 INSERT INTO pp VALUES(3, 'three');
1812 catchsql "$update pp SET a = 1 WHERE a = 2"
1813 } {1 {FOREIGN KEY constraint failed}}
1814 do_test without_rowid3-20.3.$tn.7 {
1815 execsql { COMMIT ; SELECT * FROM pp }
1817 do_test without_rowid3-20.3.$tn.8 {
1820 INSERT INTO cc VALUES(2, 2);
1822 catchsql "$update cc SET d = 1 WHERE c = 1"
1823 } {1 {FOREIGN KEY constraint failed}}
1824 do_test without_rowid3-20.3.$tn.9 {
1825 execsql { COMMIT ; SELECT * FROM cc }
1827 do_test without_rowid3-20.3.$tn.10 {
1828 execsql { DELETE FROM cc ; DELETE FROM pp }
1832 #-------------------------------------------------------------------------
1833 # The following block of tests, those prefixed with "without_rowid3-genfkey.",
1834 # are the same tests that were used to test the ".genfkey" command provided
1835 # by the shell tool. So these tests show that the built-in foreign key
1836 # implementation is more or less compatible with the triggers generated
1840 do_test without_rowid3-genfkey.1.1 {
1842 CREATE TABLE t1(a INT PRIMARY KEY, b, c, UNIQUE(b, c)) WITHOUT rowid;
1843 CREATE TABLE t2(e REFERENCES t1, f);
1844 CREATE TABLE t3(g, h, i, FOREIGN KEY (h, i) REFERENCES t1(b, c));
1847 do_test without_rowid3-genfkey.1.2 {
1848 catchsql { INSERT INTO t2 VALUES(1, 2) }
1849 } {1 {FOREIGN KEY constraint failed}}
1850 do_test without_rowid3-genfkey.1.3 {
1852 INSERT INTO t1 VALUES(1, 2, 3);
1853 INSERT INTO t2 VALUES(1, 2);
1856 do_test without_rowid3-genfkey.1.4 {
1857 execsql { INSERT INTO t2 VALUES(NULL, 3) }
1859 do_test without_rowid3-genfkey.1.5 {
1860 catchsql { UPDATE t2 SET e = 5 WHERE e IS NULL }
1861 } {1 {FOREIGN KEY constraint failed}}
1862 do_test without_rowid3-genfkey.1.6 {
1863 execsql { UPDATE t2 SET e = 1 WHERE e IS NULL }
1865 do_test without_rowid3-genfkey.1.7 {
1866 execsql { UPDATE t2 SET e = NULL WHERE f = 3 }
1868 do_test without_rowid3-genfkey.1.8 {
1869 catchsql { UPDATE t1 SET a = 10 }
1870 } {1 {FOREIGN KEY constraint failed}}
1871 do_test without_rowid3-genfkey.1.9 {
1872 catchsql { UPDATE t1 SET a = NULL }
1873 } {1 {NOT NULL constraint failed: t1.a}}
1874 do_test without_rowid3-genfkey.1.10 {
1875 catchsql { DELETE FROM t1 }
1876 } {1 {FOREIGN KEY constraint failed}}
1877 do_test without_rowid3-genfkey.1.11 {
1878 execsql { UPDATE t2 SET e = NULL }
1880 do_test without_rowid3-genfkey.1.12 {
1882 UPDATE t1 SET a = 10;
1887 do_test without_rowid3-genfkey.1.13 {
1889 INSERT INTO t3 VALUES(1, NULL, NULL);
1890 INSERT INTO t3 VALUES(1, 2, NULL);
1891 INSERT INTO t3 VALUES(1, NULL, 3);
1894 do_test without_rowid3-genfkey.1.14 {
1895 catchsql { INSERT INTO t3 VALUES(3, 1, 4) }
1896 } {1 {FOREIGN KEY constraint failed}}
1897 do_test without_rowid3-genfkey.1.15 {
1899 INSERT INTO t1 VALUES(1, 1, 4);
1900 INSERT INTO t3 VALUES(3, 1, 4);
1903 do_test without_rowid3-genfkey.1.16 {
1904 catchsql { DELETE FROM t1 }
1905 } {1 {FOREIGN KEY constraint failed}}
1906 do_test without_rowid3-genfkey.1.17 {
1907 catchsql { UPDATE t1 SET b = 10}
1908 } {1 {FOREIGN KEY constraint failed}}
1909 do_test without_rowid3-genfkey.1.18 {
1910 execsql { UPDATE t1 SET a = 10}
1912 do_test without_rowid3-genfkey.1.19 {
1913 catchsql { UPDATE t3 SET h = 'hello' WHERE i = 3}
1914 } {1 {FOREIGN KEY constraint failed}}
1917 do_test without_rowid3-genfkey.2.1 {
1919 CREATE TABLE t1(a INT PRIMARY KEY, b, c, UNIQUE(b, c)) WITHOUT rowid;
1920 CREATE TABLE t2(e REFERENCES t1 ON UPDATE CASCADE ON DELETE CASCADE, f);
1921 CREATE TABLE t3(g, h, i,
1923 REFERENCES t1(b, c) ON UPDATE CASCADE ON DELETE CASCADE
1927 do_test without_rowid3-genfkey.2.2 {
1929 INSERT INTO t1 VALUES(1, 2, 3);
1930 INSERT INTO t1 VALUES(4, 5, 6);
1931 INSERT INTO t2 VALUES(1, 'one');
1932 INSERT INTO t2 VALUES(4, 'four');
1935 do_test without_rowid3-genfkey.2.3 {
1937 UPDATE t1 SET a = 2 WHERE a = 1;
1941 do_test without_rowid3-genfkey.2.4 {
1943 DELETE FROM t1 WHERE a = 4;
1948 do_test without_rowid3-genfkey.2.5 {
1950 INSERT INTO t3 VALUES('hello', 2, 3);
1951 UPDATE t1 SET c = 2;
1955 do_test without_rowid3-genfkey.2.6 {
1963 do_test without_rowid3-genfkey.3.1 {
1965 CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, UNIQUE(c, b)) WITHOUT rowid;
1966 CREATE TABLE t2(e REFERENCES t1 ON UPDATE SET NULL ON DELETE SET NULL, f);
1967 CREATE TABLE t3(g, h, i,
1969 REFERENCES t1(b, c) ON UPDATE SET NULL ON DELETE SET NULL
1973 do_test without_rowid3-genfkey.3.2 {
1975 INSERT INTO t1 VALUES(1, 2, 3);
1976 INSERT INTO t1 VALUES(4, 5, 6);
1977 INSERT INTO t2 VALUES(1, 'one');
1978 INSERT INTO t2 VALUES(4, 'four');
1981 do_test without_rowid3-genfkey.3.3 {
1983 UPDATE t1 SET a = 2 WHERE a = 1;
1987 do_test without_rowid3-genfkey.3.4 {
1989 DELETE FROM t1 WHERE a = 4;
1993 do_test without_rowid3-genfkey.3.5 {
1995 INSERT INTO t3 VALUES('hello', 2, 3);
1996 UPDATE t1 SET c = 2;
2000 do_test without_rowid3-genfkey.3.6 {
2002 UPDATE t3 SET h = 2, i = 2;
2008 #-------------------------------------------------------------------------
2009 # Verify that ticket dd08e5a988d00decc4a543daa8dbbfab9c577ad8 has been
2012 do_test without_rowid3-dd08e5.1.1 {
2014 PRAGMA foreign_keys=ON;
2015 CREATE TABLE tdd08(a INTEGER PRIMARY KEY, b) WITHOUT rowid;
2016 CREATE UNIQUE INDEX idd08 ON tdd08(a,b);
2017 INSERT INTO tdd08 VALUES(200,300);
2019 CREATE TABLE tdd08_b(w,x,y, FOREIGN KEY(x,y) REFERENCES tdd08(a,b));
2020 INSERT INTO tdd08_b VALUES(100,200,300);
2023 do_test without_rowid3-dd08e5.1.2 {
2027 } {1 {FOREIGN KEY constraint failed}}
2028 do_test without_rowid3-dd08e5.1.3 {
2030 SELECT * FROM tdd08;
2033 do_test without_rowid3-dd08e5.1.4 {
2035 INSERT INTO tdd08_b VALUES(400,500,300);
2037 } {1 {FOREIGN KEY constraint failed}}
2038 do_test without_rowid3-dd08e5.1.5 {
2040 UPDATE tdd08_b SET x=x+1;
2042 } {1 {FOREIGN KEY constraint failed}}
2043 do_test without_rowid3-dd08e5.1.6 {
2045 UPDATE tdd08 SET a=a+1;
2047 } {1 {FOREIGN KEY constraint failed}}
2049 #-------------------------------------------------------------------------
2050 # Verify that ticket ce7c133ea6cc9ccdc1a60d80441f80b6180f5eba
2053 do_test without_rowid3-ce7c13.1.1 {
2055 CREATE TABLE tce71(a INTEGER PRIMARY KEY, b) WITHOUT rowid;
2056 CREATE UNIQUE INDEX ice71 ON tce71(a,b);
2057 INSERT INTO tce71 VALUES(100,200);
2058 CREATE TABLE tce72(w, x, y, FOREIGN KEY(x,y) REFERENCES tce71(a,b));
2059 INSERT INTO tce72 VALUES(300,100,200);
2060 UPDATE tce71 set b = 200 where a = 100;
2061 SELECT * FROM tce71, tce72;
2063 } {100 200 300 100 200}
2064 do_test without_rowid3-ce7c13.1.2 {
2066 UPDATE tce71 set b = 201 where a = 100;
2068 } {1 {FOREIGN KEY constraint failed}}
2069 do_test without_rowid3-ce7c13.1.3 {
2071 UPDATE tce71 set a = 101 where a = 100;
2073 } {1 {FOREIGN KEY constraint failed}}
2074 do_test without_rowid3-ce7c13.1.4 {
2076 CREATE TABLE tce73(a INTEGER PRIMARY KEY, b, UNIQUE(a,b)) WITHOUT rowid;
2077 INSERT INTO tce73 VALUES(100,200);
2078 CREATE TABLE tce74(w, x, y, FOREIGN KEY(x,y) REFERENCES tce73(a,b));
2079 INSERT INTO tce74 VALUES(300,100,200);
2080 UPDATE tce73 set b = 200 where a = 100;
2081 SELECT * FROM tce73, tce74;
2083 } {100 200 300 100 200}
2084 do_test without_rowid3-ce7c13.1.5 {
2086 UPDATE tce73 set b = 201 where a = 100;
2088 } {1 {FOREIGN KEY constraint failed}}
2089 do_test without_rowid3-ce7c13.1.6 {
2091 UPDATE tce73 set a = 101 where a = 100;
2093 } {1 {FOREIGN KEY constraint failed}}
2095 # Confirm that changes() works on WITHOUT ROWID tables that use the
2096 # xfer optimization.
2100 do_execsql_test without_rowid3-30.1 {
2101 CREATE TABLE t1(a,b,PRIMARY KEY(a,b)) WITHOUT ROWID;
2102 CREATE TABLE t2(a,b,PRIMARY KEY(a,b)) WITHOUT ROWID;
2103 INSERT INTO t1 VALUES(1,2),(3,4),(5,6);
2106 do_execsql_test without_rowid3-30.2 {
2107 INSERT INTO t2 SELECT * FROM t1;