bump version
[sqlcipher.git] / test / without_rowid3.test
blobf7687455ec543d22818e19aaac433d5b18dffa8a
1 # 2013-11-02
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
14 # tables.
17 set testdir [file dirname $argv0]
18 source $testdir/tester.tcl
20 ifcapable {!foreignkey||!trigger} {
21   finish_test
22   return
25 #-------------------------------------------------------------------------
26 # Test structure:
28 # without_rowid3-1.*: Simple tests to check that immediate and deferred foreign key 
29 #            constraints work when not inside a transaction.
30 #            
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
38 #            are disabled.
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 
44 #            running VACUUM.
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.
74
75 # without_rowid3-18.*: Test that the authorization callback is invoked when processing
76 #             FK constraints.
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
85 #                  has been fixed.
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]
148 } {}
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)} } {}
158 drop_all_tables
160 do_test without_rowid3-1.2.0 {
161   execsql [string map {/D/ {DEFERRABLE INITIALLY DEFERRED}} $FkeySimpleSchema]
162 } {}
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)} } {}
172 drop_all_tables
174 do_test without_rowid3-1.3.0 {
175   execsql [string map {/D/ {}} $FkeySimpleSchema]
176   execsql { PRAGMA count_changes = 1 }
177 } {}
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 }
189 drop_all_tables
191 do_test without_rowid3-1.4.0 {
192   execsql [string map {/D/ {}} $FkeySimpleSchema]
193   execsql { PRAGMA count_changes = 1 }
194 } {}
195 foreach {tn zSql res} $FkeySimpleTests {
196   if {$res == "0 {}"} { set res {0 1} }
197   execsql BEGIN
198   do_test without_rowid3-1.4.$tn { catchsql $zSql } $res
199   execsql COMMIT
201 execsql { PRAGMA count_changes = 0 }
202 drop_all_tables
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 {
208   execsql {
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;
214   }
215 } {35.0 text}
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.
221 drop_all_tables
222 do_test without_rowid3-1.6.1 {
223   execsql {
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;
230   }
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.
237 drop_all_tables
238 do_test without_rowid3-1.7.1 {
239   execsql {
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');
244   }
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.
250 drop_all_tables
251 do_test without_rowid3-1.7.2 {
252   execsql {
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');
256   }
257   catchsql { INSERT INTO j VALUES('sqlite') }
258 } {1 {FOREIGN KEY constraint failed}}
259 do_test without_rowid3-1.7.3 {
260   execsql {
261     INSERT INTO i VALUES('sqlite');
262     INSERT INTO j VALUES('sqlite');
263     DELETE FROM i WHERE i = 'SQLite';
264   }
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 {}}} {
273   if {$res eq "FKV"} {
274     set expected {1 {FOREIGN KEY constraint failed}}
275   } else {
276     set expected [list 0 $res]
277   }
278   do_test without_rowid3-2.$tn [list catchsql $sql] $expected
279   if {$nocommit} {
280     do_test without_rowid3-2.${tn}c {
281       catchsql COMMIT
282     } {1 {FOREIGN KEY constraint failed}}
283   }
286 without_rowid3-2-test 1 0 {
287   CREATE TABLE node(
288     nodeid PRIMARY KEY,
289     parent REFERENCES node DEFERRABLE INITIALLY DEFERRED
290   ) WITHOUT rowid;
291   CREATE TABLE leaf(
292     cellid PRIMARY KEY,
293     parent REFERENCES node DEFERRABLE INITIALLY DEFERRED
294   ) WITHOUT rowid;
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.
397 drop_all_tables
398 do_test without_rowid3-3.1.1 {
399   execsql {
400     CREATE TABLE ab(a PRIMARY KEY, b) WITHOUT rowid;
401     CREATE TABLE cd(
402       c PRIMARY KEY REFERENCES ab ON UPDATE CASCADE ON DELETE CASCADE, 
403       d
404     ) WITHOUT rowid;
405     CREATE TABLE ef(
406       e REFERENCES cd ON UPDATE CASCADE, 
407       f, CHECK (e!=5)
408     );
409   }
410 } {}
411 do_test without_rowid3-3.1.2 {
412   execsql {
413     INSERT INTO ab VALUES(1, 'b');
414     INSERT INTO cd VALUES(1, 'd');
415     INSERT INTO ef VALUES(1, 'e');
416   }
417 } {}
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 }
423 } {1 b}
424 do_test without_rowid3-3.1.4 {
425   execsql BEGIN;
426   catchsql { UPDATE ab SET a = 5 }
427 } {1 {CHECK constraint failed: e!=5}}
428 do_test without_rowid3-3.1.5 {
429   execsql COMMIT;
430   execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef }
431 } {1 b 1 d 1 e}
433 do_test without_rowid3-3.2.1 {
434   execsql BEGIN;
435   catchsql { DELETE FROM ab }
436 } {1 {FOREIGN KEY constraint failed}}
437 do_test without_rowid3-3.2.2 {
438   execsql COMMIT
439   execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef }
440 } {1 b 1 d 1 e}
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.
446 drop_all_tables
447 do_test without_rowid3-4.1 {
448   execsql {
449     CREATE TABLE t1(
450       node PRIMARY KEY, 
451       parent REFERENCES t1 ON DELETE CASCADE
452     ) WITHOUT rowid;
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;
456     END;
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;
465   }
466 } {}
467 do_test without_rowid3-4.2 {
468   execsql { PRAGMA recursive_triggers = off }
469   execsql { 
470     BEGIN;
471       DELETE FROM t1 WHERE node = 1;
472       SELECT node FROM t1;
473   }
474 } {}
475 do_test without_rowid3-4.3 {
476   execsql { 
477       DELETE FROM t2 WHERE node = 1;
478       SELECT node FROM t2;
479     ROLLBACK;
480   }
481 } {4 5 6 7}
482 do_test without_rowid3-4.4 {
483   execsql { PRAGMA recursive_triggers = on }
484   execsql { 
485     BEGIN;
486       DELETE FROM t1 WHERE node = 1;
487       SELECT node FROM t1;
488   }
489 } {}
490 do_test without_rowid3-4.3 {
491   execsql { 
492       DELETE FROM t2 WHERE node = 1;
493       SELECT node FROM t2;
494     ROLLBACK;
495   }
496 } {}
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.
502 drop_all_tables
503 ifcapable incrblob {
504   do_test without_rowid3-5.1 {
505     execsql {
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');
510     }
511   } {}
512   do_test without_rowid3-5.2 {
513     set rc [catch { set fd [db incrblob t2 b 1] } msg]
514     list $rc $msg
515   } {1 {cannot open table without rowid: t2}}
516   do_test without_rowid3-5.5 {
517     execsql { PRAGMA foreign_keys = on }
518   } {}
521 drop_all_tables
522 ifcapable vacuum {
523   do_test without_rowid3-6.1 {
524     execsql {
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);
529       VACUUM;
530     }
531   } {}
534 #-------------------------------------------------------------------------
535 # Test that it is possible to use an INT PRIMARY KEY as the child key
536 # of a foreign constraint.
538 drop_all_tables
539 do_test without_rowid3-7.1 {
540   execsql {
541     CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT rowid;
542     CREATE TABLE t2(c INT PRIMARY KEY REFERENCES t1, b) WITHOUT rowid;
543   }
544 } {}
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 {
549   execsql { 
550     INSERT INTO t1 VALUES(1, 2);
551     INSERT INTO t1 VALUES(2, 3);
552     INSERT INTO t2 VALUES(1, 'A');
553   }
554 } {}
555 do_test without_rowid3-7.4 {
556   execsql { UPDATE t2 SET c = 2 }
557 } {}
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 }
566 } {}
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.
575 drop_all_tables
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.
600 drop_all_tables
601 do_test without_rowid3-9.1.1 {
602   execsql {
603     CREATE TABLE t1(a INT PRIMARY KEY, b) WITHOUT rowid;
604     CREATE TABLE t2(
605       c INT PRIMARY KEY,
606       d INTEGER DEFAULT 1 REFERENCES t1 ON DELETE SET DEFAULT
607     ) WITHOUT rowid;
608     DELETE FROM t1;
609   }
610 } {}
611 do_test without_rowid3-9.1.2 {
612   execsql {
613     INSERT INTO t1 VALUES(1, 'one');
614     INSERT INTO t1 VALUES(2, 'two');
615     INSERT INTO t2 VALUES(1, 2);
616     SELECT * FROM t2;
617     DELETE FROM t1 WHERE a = 2;
618     SELECT * FROM t2;
619   }
620 } {1 2 1 1}
621 do_test without_rowid3-9.1.3 {
622   execsql {
623     INSERT INTO t1 VALUES(2, 'two');
624     UPDATE t2 SET d = 2;
625     DELETE FROM t1 WHERE a = 1;
626     SELECT * FROM t2;
627   }
628 } {1 2}
629 do_test without_rowid3-9.1.4 {
630   execsql { SELECT * FROM t1 }
631 } {2 two}
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 {
637   execsql {
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 
642         ON DELETE SET NULL
643     );
644     INSERT INTO pp VALUES(1, 2, 3);
645     INSERT INTO pp VALUES(4, 5, 6);
646     INSERT INTO pp VALUES(7, 8, 9);
647   }
648 } {}
649 do_test without_rowid3-9.2.2 {
650   execsql {
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;
656     SELECT * FROM cc;
657   }
658 } {6 A 5 6 B 5 3 A 2 3 B 2}
659 do_test without_rowid3-9.2.3 {
660   execsql {
661     DELETE FROM pp WHERE a = 4;
662     SELECT * FROM cc;
663   }
664 } {{} A {} {} B {} 3 A 2 3 B 2}
666 #-------------------------------------------------------------------------
667 # The following tests, without_rowid3-10.*, test "foreign key mismatch" and 
668 # other errors.
670 set tn 0
671 foreach zSql [list {
672   CREATE TABLE p(a PRIMARY KEY, b) WITHOUT rowid;
673   CREATE TABLE c(x REFERENCES p(c));
674 } {
675   CREATE TABLE c(x REFERENCES v(y));
676   CREATE VIEW v AS SELECT x AS y FROM c;
677 } {
678   CREATE TABLE p(a, b, PRIMARY KEY(a, b)) WITHOUT rowid;
679   CREATE TABLE c(x REFERENCES p);
680 } {
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));
684 }] {
685   drop_all_tables
686   do_test without_rowid3-10.1.[incr tn] {
687     execsql $zSql
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 {
696   drop_all_tables
697   catchsql {
698     CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT rowid;
699     CREATE TABLE t2(c, d, FOREIGN KEY(rowid) REFERENCES t1(a));
700   }
701 } {1 {unknown column "rowid" in foreign key definition}}
702 do_test without_rowid3-10.2.2 {
703   drop_all_tables
704   catchsql {
705     CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT rowid;
706     CREATE TABLE t2(rowid, d, FOREIGN KEY(rowid) REFERENCES t1(a));
707   }
708 } {0 {}}
709 do_test without_rowid3-10.2.1 {
710   drop_all_tables
711   catchsql {
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);
716   }
717 } {1 {foreign key mismatch - "t2" referencing "t1"}}
718 do_test without_rowid3-10.2.2 {
719   drop_all_tables
720   catchsql {
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);
725   }
726 } {0 {}}
729 #-------------------------------------------------------------------------
730 # The following tests, without_rowid3-11.*, test CASCADE actions.
732 drop_all_tables
733 do_test without_rowid3-11.1.1 {
734   execsql {
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;
741     SELECT * FROM t2;
742   }
743 } {15 100}
745 #-------------------------------------------------------------------------
746 # The following tests, without_rowid3-12.*, test RESTRICT actions.
748 drop_all_tables
749 do_test without_rowid3-12.1.1 {
750   execsql {
751     CREATE TABLE t1(a, b PRIMARY KEY) WITHOUT rowid;
752     CREATE TABLE t2(
753       x REFERENCES t1 ON UPDATE RESTRICT DEFERRABLE INITIALLY DEFERRED 
754     );
755     INSERT INTO t1 VALUES(1, 'one');
756     INSERT INTO t1 VALUES(2, 'two');
757     INSERT INTO t1 VALUES(3, 'three');
758   }
759 } {}
760 do_test without_rowid3-12.1.2 { 
761   execsql "BEGIN"
762   execsql "INSERT INTO t2 VALUES('two')"
763 } {}
764 do_test without_rowid3-12.1.3 { 
765   execsql "UPDATE t1 SET b = 'four' WHERE b = 'one'"
766 } {}
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'"
772 } {}
773 do_test without_rowid3-12.1.6 { 
774   catchsql "COMMIT"
775 } {1 {FOREIGN KEY constraint failed}}
776 do_test without_rowid3-12.1.7 { 
777   execsql {
778     INSERT INTO t1 VALUES(2, 'two');
779     COMMIT;
780   }
781 } {}
783 drop_all_tables
784 do_test without_rowid3-12.2.1 {
785   execsql {
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 )
789     BEGIN
790       INSERT INTO t1 VALUES(old.x);
791     END;
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');
798     SELECT * FROM t1;
799     SELECT * FROM t2;
800   }
801 } {A B a b}
802 do_test without_rowid3-12.2.2 {
803   execsql { DELETE FROM t1 }
804   execsql {
805     SELECT * FROM t1;
806     SELECT * FROM t2;
807   }
808 } {A B a b}
809 do_test without_rowid3-12.2.3 {
810   execsql {
811     DROP TABLE t2;
812     CREATE TABLE t2(y REFERENCES t1 ON DELETE RESTRICT);
813     INSERT INTO t2 VALUES('a');
814     INSERT INTO t2 VALUES('b');
815   }
816   catchsql { DELETE FROM t1 }
817 } {1 {FOREIGN KEY constraint failed}}
818 do_test without_rowid3-12.2.4 {
819   execsql {
820     SELECT * FROM t1;
821     SELECT * FROM t2;
822   }
823 } {A B a b}
825 drop_all_tables
826 do_test without_rowid3-12.3.1 {
827   execsql {
828     CREATE TABLE up(
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)
834     ) WITHOUT rowid;
835     CREATE TABLE down(
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
841     );
842   }
843 } {}
844 do_test without_rowid3-12.3.2 {
845   execsql {
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;
850     DELETE FROM down;
851   }
852 } {no possibly}
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 {
857   execsql { 
858     INSERT INTO up(c34, c35) VALUES('yes', 'no');
859     INSERT INTO down(c39, c38) VALUES('yes', 'no');
860   }
861   catchsql { DELETE FROM up WHERE c34 = 'yes' }
862 } {1 {FOREIGN KEY constraint failed}}
863 do_test without_rowid3-12.3.5 {
864   execsql { 
865     DELETE FROM up WHERE c34 = 'possibly';
866     SELECT c34, c35 FROM up;
867     SELECT c39, c38 FROM down;
868   }
869 } {yes no yes no}
871 #-------------------------------------------------------------------------
872 # The following tests, without_rowid3-13.*, test that FK processing is performed
873 # when rows are REPLACEd.
875 drop_all_tables
876 do_test without_rowid3-13.1.1 {
877   execsql {
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);
882   }
883 } {}
884 foreach {tn stmt} {
885   1   "REPLACE INTO pp VALUES(1, 4, 5)"
886 } {
887   do_test without_rowid3-13.1.$tn.1 {
888     catchsql $stmt
889   } {1 {FOREIGN KEY constraint failed}}
890   do_test without_rowid3-13.1.$tn.2 {
891     execsql {
892       SELECT * FROM pp;
893       SELECT * FROM cc;
894     }
895   } {1 2 3 2 3 1}
896   do_test without_rowid3-13.1.$tn.3 {
897     execsql BEGIN;
898     catchsql $stmt
899   } {1 {FOREIGN KEY constraint failed}}
900   do_test without_rowid3-13.1.$tn.4 {
901     execsql {
902       COMMIT;
903       SELECT * FROM pp;
904       SELECT * FROM cc;
905     }
906   } {1 2 3 2 3 1}
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
917 drop_all_tables
918 ifcapable altertable {
919   do_test without_rowid3-14.1.1 {
920     # Adding a column with a REFERENCES clause is not supported.
921     execsql { 
922       CREATE TABLE t1(a PRIMARY KEY) WITHOUT rowid;
923       CREATE TABLE t2(a, b);
924       INSERT INTO t2(a,b) VALUES(1,2);
925     }
926     catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
927   } {0 {}}
928   do_test without_rowid3-14.1.2 {
929     catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
930   } {0 {}}
931   do_test without_rowid3-14.1.3 {
932     catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}
933   } {0 {}}
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 {
941     execsql { 
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';
946     }
947   } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
948   
949   
950   # Test the sqlite_rename_parent() function directly.
951   #
952   proc test_rename_parent {zCreate zOld zNew} {
953     db eval {SELECT sqlite_rename_table(
954         'main', 'table', 't1', $zCreate, $zOld, $zNew, 0
955     )}
956   }
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
968   
969   # Test ALTER TABLE RENAME TABLE a bit.
970   #
971   do_test without_rowid3-14.2.2.1 {
972     drop_all_tables
973     execsql {
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)
976             WITHOUT rowid;
977       CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
978     }
979     execsql { SELECT sql FROM sqlite_schema WHERE type = 'table'}
980   } [list \
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)
983             WITHOUT rowid}    \
984     {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)}  \
985   ]
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'}
989   } [list \
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)
992             WITHOUT rowid}     \
993     {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \
994   ]
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) }
1000   } {}
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 }
1006   } {0 {}}
1007   do_test without_rowid3-14.2.2.7 {
1008     execsql { INSERT INTO t3 VALUES(1, NULL, 1) }
1009   } {}
1011   # Repeat for TEMP tables
1012   #
1013   drop_all_tables
1014   do_test without_rowid3-14.1tmp.1 {
1015     # Adding a column with a REFERENCES clause is not supported.
1016     execsql { 
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);
1020     }
1021     catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
1022   } {0 {}}
1023   do_test without_rowid3-14.1tmp.2 {
1024     catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
1025   } {0 {}}
1026   do_test without_rowid3-14.1tmp.3 {
1027     catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}
1028   } {0 {}}
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 {
1036     execsql { 
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';
1041     }
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
1055   
1056   # Test ALTER TABLE RENAME TABLE a bit.
1057   #
1058   do_test without_rowid3-14.2tmp.2.1 {
1059     drop_all_tables
1060     execsql {
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)
1063             WITHOUT rowid;
1064       CREATE TEMP TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
1065     }
1066     execsql { SELECT sql FROM sqlite_temp_schema WHERE type = 'table'}
1067   } [list \
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)
1070             WITHOUT rowid}    \
1071     {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)}  \
1072   ]
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'}
1076   } [list \
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)
1079             WITHOUT rowid}     \
1080     {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \
1081   ]
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) }
1087   } {}
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 }
1093   } {0 {}}
1094   do_test without_rowid3-14.2tmp.2.7 {
1095     execsql { INSERT INTO t3 VALUES(1, NULL, 1) }
1096   } {}
1098   # Repeat for ATTACH-ed tables
1099   #
1100   drop_all_tables
1101   do_test without_rowid3-14.1aux.1 {
1102     # Adding a column with a REFERENCES clause is not supported.
1103     execsql { 
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);
1108     }
1109     catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
1110   } {0 {}}
1111   do_test without_rowid3-14.1aux.2 {
1112     catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
1113   } {0 {}}
1114   do_test without_rowid3-14.1aux.3 {
1115     catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}
1116   } {0 {}}
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 {
1124     execsql { 
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';
1129     }
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
1143   
1144   # Test ALTER TABLE RENAME TABLE a bit.
1145   #
1146   do_test without_rowid3-14.2aux.2.1 {
1147     drop_all_tables
1148     execsql {
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)
1151             WITHOUT rowid;
1152       CREATE TABLE aux.t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
1153     }
1154     execsql { SELECT sql FROM aux.sqlite_schema WHERE type = 'table'}
1155   } [list \
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)
1158             WITHOUT rowid}    \
1159     {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)}  \
1160   ]
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'}
1164   } [list \
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)
1167             WITHOUT rowid}     \
1168     {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \
1169   ]
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) }
1175   } {}
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 }
1181   } {0 {}}
1182   do_test without_rowid3-14.2aux.2.7 {
1183     execsql { INSERT INTO t3 VALUES(1, NULL, 1) }
1184   } {}
1187 do_test without_rowid3-2.14.3.1 {
1188   drop_all_tables
1189   execsql {
1190     CREATE TABLE t1(a, b REFERENCES nosuchtable);
1191     DROP TABLE t1;
1192   }
1193 } {}
1194 do_test without_rowid3-2.14.3.2 {
1195   execsql {
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');
1200   }
1201 } {}
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 {
1206   execsql {
1207     DELETE FROM t2;
1208     DROP TABLE t1;
1209   }
1210 } {}
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 {
1215   execsql {
1216     CREATE TABLE t1(x PRIMARY KEY) WITHOUT rowid;
1217     INSERT INTO t1 VALUES('x');
1218   }
1219   execsql { INSERT INTO t2 VALUES('x') }
1220 } {}
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 {
1225   execsql {
1226     DROP TABLE t2;
1227     DROP TABLE t1;
1228   }
1229 } {}
1230 do_test without_rowid3-2.14.3.8 {
1231   execsql {
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));
1234   }
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 }
1239 } {}
1240 do_test without_rowid3-2.14.3.10 {
1241   execsql {
1242     CREATE TABLE cc(a, b, 
1243       FOREIGN KEY(a, b) REFERENCES pp DEFERRABLE INITIALLY DEFERRED
1244     );
1245   }
1246   execsql {
1247     INSERT INTO pp VALUES('a', 'b');
1248     INSERT INTO cc VALUES('a', 'b');
1249     BEGIN;
1250       DROP TABLE pp;
1251       CREATE TABLE pp(a, b, c, PRIMARY KEY(b, c)) WITHOUT rowid;
1252       INSERT INTO pp VALUES(1, 'a', 'b');
1253     COMMIT;
1254   }
1255 } {}
1256 do_test without_rowid3-2.14.3.11 {
1257   execsql { 
1258     BEGIN;
1259       DROP TABLE cc;
1260       DROP TABLE pp;
1261     COMMIT;
1262   }
1263 } {}
1264 do_test without_rowid3-2.14.3.12 {
1265   execsql {
1266     CREATE TABLE b1(a, b);
1267     CREATE TABLE b2(a, b REFERENCES b1);
1268     DROP TABLE b1;
1269   }
1270 } {}
1271 do_test without_rowid3-2.14.3.13 {
1272   execsql {
1273     CREATE TABLE b3(a, b REFERENCES b2 DEFERRABLE INITIALLY DEFERRED);
1274     DROP TABLE b2;
1275   }
1276 } {}
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.
1281 drop_all_tables
1282 do_test without_rowid3-2.14.4.1 {
1283   execsql {
1284     CREATE TABLE t1(x REFERENCES v); 
1285     CREATE VIEW v AS SELECT * FROM t1;
1286   }
1287 } {}
1288 do_test without_rowid3-2.14.4.2 {
1289   execsql {
1290     DROP VIEW v;
1291   }
1292 } {}
1293 ifcapable vtab {
1294   register_echo_module db
1295   do_test without_rowid3-2.14.4.3 {
1296     execsql { CREATE VIRTUAL TABLE v USING echo(t1) }
1297   } {}
1298   do_test without_rowid3-2.14.4.2 {
1299     execsql {
1300       DROP TABLE v;
1301     }
1302   } {}
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.
1309 drop_all_tables
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 {
1317   execsql {
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);
1324   }
1325 } {}
1326 do_test without_rowid3-15.1.2 {
1327   execsqlS { INSERT INTO pp VALUES(3, 'three') }
1328 } {0}
1329 do_test without_rowid3-15.1.3 {
1330   execsql {
1331     BEGIN;
1332       INSERT INTO cc VALUES('see', 4);    -- Violates deferred constraint
1333   }
1334   execsqlS { INSERT INTO pp VALUES(5, 'five') }
1335 } {2}
1336 do_test without_rowid3-15.1.4 {
1337   execsql { DELETE FROM cc WHERE x = 'see' }
1338   execsqlS { INSERT INTO pp VALUES(6, 'six') }
1339 } {0}
1340 do_test without_rowid3-15.1.5 {
1341   execsql COMMIT
1342 } {}
1343 do_test without_rowid3-15.1.6 {
1344   execsql BEGIN
1345   execsqlS {
1346     DELETE FROM cc WHERE x = 'neung';
1347     ROLLBACK;
1348   }
1349 } {1}
1350 do_test without_rowid3-15.1.7 {
1351   execsql { 
1352     BEGIN;
1353     DELETE FROM pp WHERE a = 2;
1354   }
1355   execsqlS {
1356     DELETE FROM cc WHERE x = 'neung';
1357     ROLLBACK;
1358   }
1359 } {2}
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))
1367              WITHOUT rowid }
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))
1370              WITHOUT rowid }
1371 } {
1372   drop_all_tables
1373   do_test without_rowid3-16.1.$tn.1 {
1374     execsql $zSchema
1375     execsql { INSERT INTO self VALUES(13, 13) }
1376   } {}
1377   do_test without_rowid3-16.1.$tn.2 {
1378     execsql { UPDATE self SET a = 14, b = 14 }
1379   } {}
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 }
1395   } {0 {}}
1397   do_test without_rowid3-16.1.$tn.7 {
1398     execsql { DELETE FROM self }
1399   } {}
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.
1408 drop_all_tables
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,
1412      UNIQUE (a,b),
1413      PRIMARY KEY (e,c),
1414      FOREIGN KEY (d,f) REFERENCES t1(e,c)
1415   ) WITHOUT rowid;
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 {
1433   catchsql {
1434     UPDATE t1 SET c=11, e=22 WHERE a=1;
1435   }
1436 } {1 {FOREIGN KEY constraint failed}}
1438 do_test without_rowid3-16.4.1.5 {
1439   catchsql {
1440     UPDATE t1 SET d=11, f=22 WHERE a=1;
1441   }
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 {
1450   DROP TABLE t1;
1451   CREATE TABLE t1(a,b,c,d,e,f,
1452      PRIMARY KEY (a,b),
1453      UNIQUE (e,c),
1454      FOREIGN KEY (d,f) REFERENCES t1(e,c)
1455   ) WITHOUT rowid;
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 {
1473   catchsql {
1474     UPDATE t1 SET c=11, e=22 WHERE a=1;
1475   }
1476 } {1 {FOREIGN KEY constraint failed}}
1478 do_test without_rowid3-16.4.2.5 {
1479   catchsql {
1480     UPDATE t1 SET d=11, f=22 WHERE a=1;
1481   }
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.
1501 drop_all_tables
1502 do_test without_rowid3-17.1.1 {
1503   execsql { PRAGMA count_changes = 1 }
1504   execsql { 
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);
1508   }
1509 } {1}
1510 do_test without_rowid3-17.1.2 {
1511   set STMT [sqlite3_prepare_v2 db "INSERT INTO two VALUES(4, 5, 6)" -1 dummy]
1512   sqlite3_step $STMT
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 {
1517     sqlite3_step $STMT
1518   } {SQLITE_CONSTRAINT}
1519   verify_ex_errcode without_rowid3-17.1.3b SQLITE_CONSTRAINT_FOREIGNKEY
1520 } else {
1521   do_test without_rowid3-17.1.3 {
1522     sqlite3_step $STMT
1523   } {SQLITE_MISUSE}
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 {
1530   execsql {
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);
1536   }
1537 } {1 1 1 1 1}
1538 do_test without_rowid3-17.1.6 {
1539   catchsql {
1540     BEGIN;
1541       INSERT INTO one VALUES(0, 0, 0);
1542       UPDATE two SET e=e+1, f=f+1;
1543   }
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 {
1552   execsql COMMIT
1553 } {}
1554 do_test without_rowid3-17.1.10 {
1555   execsql {
1556     CREATE TABLE three(
1557       g, h, i, 
1558       FOREIGN KEY(h, i) REFERENCES one(b, c) DEFERRABLE INITIALLY DEFERRED
1559     );
1560   }
1561 } {}
1562 do_test without_rowid3-17.1.11 {
1563   set STMT [sqlite3_prepare_v2 db "INSERT INTO three VALUES(7, 8, 9)" -1 dummy]
1564   sqlite3_step $STMT
1565 } {SQLITE_ROW}
1566 do_test without_rowid3-17.1.12 {
1567   sqlite3_column_text $STMT 0
1568 } {1}
1569 do_test without_rowid3-17.1.13 {
1570   sqlite3_step $STMT
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
1578 drop_all_tables
1579 do_test without_rowid3-17.2.1 {
1580   execsql {
1581     CREATE TABLE high("a'b!" PRIMARY KEY, b) WITHOUT rowid;
1582     CREATE TABLE low(
1583       c, 
1584       "d&6" REFERENCES high ON UPDATE CASCADE ON DELETE CASCADE
1585     );
1586   }
1587 } {}
1588 do_test without_rowid3-17.2.2 {
1589   execsql {
1590     INSERT INTO high VALUES('a', 'b');
1591     INSERT INTO low VALUES('b', 'a');
1592   }
1593   db changes
1594 } {1}
1595 set nTotal [db total_changes]
1596 do_test without_rowid3-17.2.3 {
1597   execsql { UPDATE high SET "a'b!" = 'c' }
1598 } {1}
1599 do_test without_rowid3-17.2.4 {
1600   db changes
1601 } {1}
1602 do_test without_rowid3-17.2.5 {
1603   expr [db total_changes] - $nTotal
1604 } {2}
1605 do_test without_rowid3-17.2.6 {
1606   execsql { SELECT * FROM high ; SELECT * FROM low }
1607 } {c b b c}
1608 do_test without_rowid3-17.2.7 {
1609   execsql { DELETE FROM high }
1610 } {1}
1611 do_test without_rowid3-17.2.8 {
1612   db changes
1613 } {1}
1614 do_test without_rowid3-17.2.9 {
1615   expr [db total_changes] - $nTotal
1616 } {4}
1617 do_test without_rowid3-17.2.10 {
1618   execsql { SELECT * FROM high ; SELECT * FROM low }
1619 } {}
1620 execsql { PRAGMA count_changes = 0 }
1622 #-------------------------------------------------------------------------
1623 # Test that the authorization callback works.
1626 ifcapable auth {
1627   do_test without_rowid3-18.1 {
1628     execsql {
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);
1632     }
1633   } {}
1635   proc auth {args} {eval lappend ::authargs [lrange $args 0 4]; return SQLITE_OK}
1636   db auth auth
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.
1640   set authargs {}
1641   do_test without_rowid3-18.2 {
1642     execsql { INSERT INTO long VALUES(1, 2, 3) }
1643     set authargs
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).
1648   set authargs {}
1649   do_test without_rowid3-18.3 {
1650     execsql { INSERT INTO short VALUES(1, 3, 2) }
1651     set authargs
1652   } {SQLITE_INSERT short {} main {} SQLITE_READ long b main {}}
1653   
1654   # As must an insert on the child table of a deferred constraint.
1655   set authargs {}
1656   do_test without_rowid3-18.4 {
1657     execsql { INSERT INTO mid VALUES(1, 3, 2) }
1658     set authargs
1659   } {SQLITE_INSERT mid {} main {} SQLITE_READ long b main {}}
1661   do_test without_rowid3-18.5 {
1662     execsql {
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
1666       );
1667     }
1668     execsql { INSERT INTO nought VALUES(2, 1, 2) }
1669     execsql { INSERT INTO cross VALUES(0, 1, 0) }
1670     set authargs [list]
1671     execsql { UPDATE nought SET b = 5 }
1672     set authargs
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}
1677   } {0 5 0}
1679   do_test without_rowid3-18.7 {
1680     execsql {
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);
1684     }
1685     set authargs [list]
1686     execsql { INSERT INTO two VALUES(100, 101); }
1687     set authargs
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.
1692   #
1693   rename auth {}
1694   proc auth {args} {
1695     if {[lindex $args 1] == "long"} {return SQLITE_IGNORE}
1696     return SQLITE_OK
1697   }
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) }
1703   } {}
1704   do_test without_rowid3-18.10 {
1705     execsql { SELECT * FROM short }
1706   } {1 3 2 1 3 {}}
1707   do_test without_rowid3-18.11 {
1708     catchsql { UPDATE short SET f = 2 WHERE f IS NULL }
1709   } {1 {FOREIGN KEY constraint failed}}
1711   db auth {}
1712   unset authargs
1716 do_test without_rowid3-19.1 {
1717   execsql {
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);
1723   }
1724 } {}
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
1728   sqlite3_step $S
1729 } {SQLITE_CONSTRAINT}
1730 verify_ex_errcode without_rowid3-19.2b SQLITE_CONSTRAINT_FOREIGNKEY
1731 do_test without_rowid3-19.3 {
1732   sqlite3_reset $S
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
1737   sqlite3_step $S
1738 } {SQLITE_DONE}
1739 do_test without_rowid3-19.4 {
1740   sqlite3_finalize $S
1741 } {SQLITE_OK}
1743 drop_all_tables
1744 do_test without_rowid3-20.1 {
1745   execsql {
1746     CREATE TABLE pp(a PRIMARY KEY, b) WITHOUT rowid;
1747     CREATE TABLE cc(c PRIMARY KEY, d REFERENCES pp) WITHOUT rowid;
1748   }
1749 } {}
1751 foreach {tn insert} {
1752   1 "INSERT"
1753   2 "INSERT OR IGNORE"
1754   3 "INSERT OR ABORT"
1755   4 "INSERT OR ROLLBACK"
1756   5 "INSERT OR REPLACE"
1757   6 "INSERT OR FAIL"
1758 } {
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 }
1764   } {}
1765   do_test without_rowid3-20.2.$tn.3 {
1766     execsql {
1767       BEGIN;
1768         INSERT INTO pp VALUES(2, 'two');
1769         INSERT INTO cc VALUES(1, 2);
1770     }
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 }
1775   } {1 2}
1776   do_test without_rowid3-20.2.$tn.5 {
1777     execsql { DELETE FROM cc ; DELETE FROM pp }
1778   } {}
1781 foreach {tn update} {
1782   1 "UPDATE"
1783   2 "UPDATE OR IGNORE"
1784   3 "UPDATE OR ABORT"
1785   4 "UPDATE OR ROLLBACK"
1786   5 "UPDATE OR REPLACE"
1787   6 "UPDATE OR FAIL"
1788 } {
1789   do_test without_rowid3-20.3.$tn.1 {
1790     execsql {
1791       INSERT INTO pp VALUES(2, 'two');
1792       INSERT INTO cc VALUES(1, 2);
1793     }
1794   } {}
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 }
1800   } {2 two}
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 }
1806   } {1 2}
1807   do_test without_rowid3-20.3.$tn.6 {
1808     execsql {
1809       BEGIN;
1810         INSERT INTO pp VALUES(3, 'three');
1811     }
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 }
1816   } {2 two 3 three}
1817   do_test without_rowid3-20.3.$tn.8 {
1818     execsql {
1819       BEGIN;
1820         INSERT INTO cc VALUES(2, 2);
1821     }
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 }
1826   } {1 2 2 2}
1827   do_test without_rowid3-20.3.$tn.10 {
1828     execsql { DELETE FROM cc ; DELETE FROM pp }
1829   } {}
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 
1837 # by genfkey.
1839 drop_all_tables
1840 do_test without_rowid3-genfkey.1.1 {
1841   execsql {
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));
1845   }
1846 } {}
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 {
1851   execsql {
1852     INSERT INTO t1 VALUES(1, 2, 3);
1853     INSERT INTO t2 VALUES(1, 2);
1854   }
1855 } {}
1856 do_test without_rowid3-genfkey.1.4 {
1857   execsql { INSERT INTO t2 VALUES(NULL, 3) }
1858 } {}
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 }
1864 } {}
1865 do_test without_rowid3-genfkey.1.7 {
1866   execsql { UPDATE t2 SET e = NULL WHERE f = 3 }
1867 } {}
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 }
1879 } {}
1880 do_test without_rowid3-genfkey.1.12 {
1881   execsql { 
1882     UPDATE t1 SET a = 10;
1883     DELETE FROM t1;
1884     DELETE FROM t2;
1885   }
1886 } {}
1887 do_test without_rowid3-genfkey.1.13 {
1888   execsql {
1889     INSERT INTO t3 VALUES(1, NULL, NULL);
1890     INSERT INTO t3 VALUES(1, 2, NULL);
1891     INSERT INTO t3 VALUES(1, NULL, 3);
1892   }
1893 } {}
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 {
1898   execsql { 
1899     INSERT INTO t1 VALUES(1, 1, 4);
1900     INSERT INTO t3 VALUES(3, 1, 4);
1901   }
1902 } {}
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}
1911 } {}
1912 do_test without_rowid3-genfkey.1.19 {
1913   catchsql { UPDATE t3 SET h = 'hello' WHERE i = 3}
1914 } {1 {FOREIGN KEY constraint failed}}
1916 drop_all_tables
1917 do_test without_rowid3-genfkey.2.1 {
1918   execsql {
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, 
1922         FOREIGN KEY (h, i) 
1923         REFERENCES t1(b, c) ON UPDATE CASCADE ON DELETE CASCADE
1924     );
1925   }
1926 } {}
1927 do_test without_rowid3-genfkey.2.2 {
1928   execsql {
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');
1933   }
1934 } {}
1935 do_test without_rowid3-genfkey.2.3 {
1936   execsql {
1937     UPDATE t1 SET a = 2 WHERE a = 1;
1938     SELECT * FROM t2;
1939   }
1940 } {2 one 4 four}
1941 do_test without_rowid3-genfkey.2.4 {
1942   execsql {
1943     DELETE FROM t1 WHERE a = 4;
1944     SELECT * FROM t2;
1945   }
1946 } {2 one}
1948 do_test without_rowid3-genfkey.2.5 {
1949   execsql {
1950     INSERT INTO t3 VALUES('hello', 2, 3);
1951     UPDATE t1 SET c = 2;
1952     SELECT * FROM t3;
1953   }
1954 } {hello 2 2}
1955 do_test without_rowid3-genfkey.2.6 {
1956   execsql {
1957     DELETE FROM t1;
1958     SELECT * FROM t3;
1959   }
1960 } {}
1962 drop_all_tables
1963 do_test without_rowid3-genfkey.3.1 {
1964   execsql {
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, 
1968         FOREIGN KEY (h, i) 
1969         REFERENCES t1(b, c) ON UPDATE SET NULL ON DELETE SET NULL
1970     );
1971   }
1972 } {}
1973 do_test without_rowid3-genfkey.3.2 {
1974   execsql {
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');
1979   }
1980 } {}
1981 do_test without_rowid3-genfkey.3.3 {
1982   execsql {
1983     UPDATE t1 SET a = 2 WHERE a = 1;
1984     SELECT * FROM t2;
1985   }
1986 } {{} one 4 four}
1987 do_test without_rowid3-genfkey.3.4 {
1988   execsql {
1989     DELETE FROM t1 WHERE a = 4;
1990     SELECT * FROM t2;
1991   }
1992 } {{} one {} four}
1993 do_test without_rowid3-genfkey.3.5 {
1994   execsql {
1995     INSERT INTO t3 VALUES('hello', 2, 3);
1996     UPDATE t1 SET c = 2;
1997     SELECT * FROM t3;
1998   }
1999 } {hello {} {}}
2000 do_test without_rowid3-genfkey.3.6 {
2001   execsql {
2002     UPDATE t3 SET h = 2, i = 2;
2003     DELETE FROM t1;
2004     SELECT * FROM t3;
2005   }
2006 } {hello {} {}}
2008 #-------------------------------------------------------------------------
2009 # Verify that ticket dd08e5a988d00decc4a543daa8dbbfab9c577ad8 has been
2010 # fixed.
2012 do_test without_rowid3-dd08e5.1.1 {
2013   execsql {
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);
2021   }
2022 } {}
2023 do_test without_rowid3-dd08e5.1.2 {
2024   catchsql {
2025     DELETE FROM tdd08;
2026   }
2027 } {1 {FOREIGN KEY constraint failed}}
2028 do_test without_rowid3-dd08e5.1.3 {
2029   execsql {
2030     SELECT * FROM tdd08;
2031   }
2032 } {200 300}
2033 do_test without_rowid3-dd08e5.1.4 {
2034   catchsql {
2035     INSERT INTO tdd08_b VALUES(400,500,300);
2036   }
2037 } {1 {FOREIGN KEY constraint failed}}
2038 do_test without_rowid3-dd08e5.1.5 {
2039   catchsql {
2040     UPDATE tdd08_b SET x=x+1;
2041   }
2042 } {1 {FOREIGN KEY constraint failed}}
2043 do_test without_rowid3-dd08e5.1.6 {
2044   catchsql {
2045     UPDATE tdd08 SET a=a+1;
2046   }
2047 } {1 {FOREIGN KEY constraint failed}}
2049 #-------------------------------------------------------------------------
2050 # Verify that ticket ce7c133ea6cc9ccdc1a60d80441f80b6180f5eba
2051 # fixed.
2053 do_test without_rowid3-ce7c13.1.1 {
2054   execsql {
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;
2062   }
2063 } {100 200 300 100 200}
2064 do_test without_rowid3-ce7c13.1.2 {
2065   catchsql {
2066     UPDATE tce71 set b = 201 where a = 100;
2067   }
2068 } {1 {FOREIGN KEY constraint failed}}
2069 do_test without_rowid3-ce7c13.1.3 {
2070   catchsql {
2071     UPDATE tce71 set a = 101 where a = 100;
2072   }
2073 } {1 {FOREIGN KEY constraint failed}}
2074 do_test without_rowid3-ce7c13.1.4 {
2075   execsql {
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;
2082   }
2083 } {100 200 300 100 200}
2084 do_test without_rowid3-ce7c13.1.5 {
2085   catchsql {
2086     UPDATE tce73 set b = 201 where a = 100;
2087   }
2088 } {1 {FOREIGN KEY constraint failed}}
2089 do_test without_rowid3-ce7c13.1.6 {
2090   catchsql {
2091     UPDATE tce73 set a = 101 where a = 100;
2092   }
2093 } {1 {FOREIGN KEY constraint failed}}
2095 # Confirm that changes() works on WITHOUT ROWID tables that use the
2096 # xfer optimization.
2098 db close
2099 sqlite3 db :memory:
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);
2104   SELECT changes();
2105 } {3}
2106 do_execsql_test without_rowid3-30.2 {
2107   INSERT INTO t2 SELECT * FROM t1;
2108   SELECT changes();
2109 } {3}
2111 finish_test