Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: third_party/sqlite/src/test/e_fkey.test

Issue 901033002: Import SQLite 3.8.7.4. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Chromium changes to support SQLite 3.8.7.4. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 # 2009 October 7 1 # 2009 October 7
2 # 2 #
3 # The author disclaims copyright to this source code. In place of 3 # The author disclaims copyright to this source code. In place of
4 # a legal notice, here is a blessing: 4 # a legal notice, here is a blessing:
5 # 5 #
6 # May you do good and not evil. 6 # May you do good and not evil.
7 # May you find forgiveness for yourself and forgive others. 7 # May you find forgiveness for yourself and forgive others.
8 # May you share freely, never taking more than you give. 8 # May you share freely, never taking more than you give.
9 # 9 #
10 #*********************************************************************** 10 #***********************************************************************
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 reset_db 128 reset_db
129 129
130 130
131 #------------------------------------------------------------------------- 131 #-------------------------------------------------------------------------
132 # EVIDENCE-OF: R-07280-60510 Assuming the library is compiled with 132 # EVIDENCE-OF: R-07280-60510 Assuming the library is compiled with
133 # foreign key constraints enabled, it must still be enabled by the 133 # foreign key constraints enabled, it must still be enabled by the
134 # application at runtime, using the PRAGMA foreign_keys command. 134 # application at runtime, using the PRAGMA foreign_keys command.
135 # 135 #
136 # This also tests that foreign key constraints are disabled by default. 136 # This also tests that foreign key constraints are disabled by default.
137 # 137 #
138 # EVIDENCE-OF: R-59578-04990 Foreign key constraints are disabled by 138 # EVIDENCE-OF: R-44261-39702 Foreign key constraints are disabled by
139 # default (for backwards compatibility), so must be enabled separately 139 # default (for backwards compatibility), so must be enabled separately
140 # for each database connection separately. 140 # for each database connection.
141 # 141 #
142 drop_all_tables 142 drop_all_tables
143 do_test e_fkey-4.1 { 143 do_test e_fkey-4.1 {
144 execsql { 144 execsql {
145 CREATE TABLE p(i PRIMARY KEY); 145 CREATE TABLE p(i PRIMARY KEY);
146 CREATE TABLE c(j REFERENCES p ON UPDATE CASCADE); 146 CREATE TABLE c(j REFERENCES p ON UPDATE CASCADE);
147 INSERT INTO p VALUES('hello'); 147 INSERT INTO p VALUES('hello');
148 INSERT INTO c VALUES('hello'); 148 INSERT INTO c VALUES('hello');
149 UPDATE p SET i = 'world'; 149 UPDATE p SET i = 'world';
150 SELECT * FROM c; 150 SELECT * FROM c;
151 } 151 }
152 } {hello} 152 } {hello}
153 do_test e_fkey-4.2 { 153 do_test e_fkey-4.2 {
154 execsql { 154 execsql {
155 DELETE FROM c; 155 DELETE FROM c;
156 DELETE FROM p; 156 DELETE FROM p;
157 PRAGMA foreign_keys = ON; 157 PRAGMA foreign_keys = ON;
158 INSERT INTO p VALUES('hello'); 158 INSERT INTO p VALUES('hello');
159 INSERT INTO c VALUES('hello'); 159 INSERT INTO c VALUES('hello');
160 UPDATE p SET i = 'world'; 160 UPDATE p SET i = 'world';
161 SELECT * FROM c; 161 SELECT * FROM c;
162 } 162 }
163 } {world} 163 } {world}
164 164
165 #------------------------------------------------------------------------- 165 #-------------------------------------------------------------------------
166 # EVIDENCE-OF: R-15278-54456 The application can can also use a PRAGMA 166 # EVIDENCE-OF: R-08013-37737 The application can also use a PRAGMA
167 # foreign_keys statement to determine if foreign keys are currently 167 # foreign_keys statement to determine if foreign keys are currently
168 # enabled. 168 # enabled.
169
169 # 170 #
170 # This also tests the example code in section 2 of foreignkeys.in. 171 # This also tests the example code in section 2 of foreignkeys.in.
171 # 172 #
172 # EVIDENCE-OF: R-11255-19907 173 # EVIDENCE-OF: R-11255-19907
173 # 174 #
174 reset_db 175 reset_db
175 do_test e_fkey-5.1 { 176 do_test e_fkey-5.1 {
176 execsql { PRAGMA foreign_keys } 177 execsql { PRAGMA foreign_keys }
177 } {0} 178 } {0}
178 do_test e_fkey-5.2 { 179 do_test e_fkey-5.2 {
(...skipping 25 matching lines...) Expand all
204 CREATE TABLE t1(a UNIQUE, b); 205 CREATE TABLE t1(a UNIQUE, b);
205 CREATE TABLE t2(c, d REFERENCES t1(a)); 206 CREATE TABLE t2(c, d REFERENCES t1(a));
206 INSERT INTO t1 VALUES(1, 2); 207 INSERT INTO t1 VALUES(1, 2);
207 INSERT INTO t2 VALUES(2, 1); 208 INSERT INTO t2 VALUES(2, 1);
208 BEGIN; 209 BEGIN;
209 PRAGMA foreign_keys = OFF; 210 PRAGMA foreign_keys = OFF;
210 } 211 }
211 catchsql { 212 catchsql {
212 DELETE FROM t1 213 DELETE FROM t1
213 } 214 }
214 } {1 {foreign key constraint failed}} 215 } {1 {FOREIGN KEY constraint failed}}
215 do_test e_fkey-6.2 { 216 do_test e_fkey-6.2 {
216 execsql { PRAGMA foreign_keys } 217 execsql { PRAGMA foreign_keys }
217 } {1} 218 } {1}
218 do_test e_fkey-6.3 { 219 do_test e_fkey-6.3 {
219 execsql { 220 execsql {
220 COMMIT; 221 COMMIT;
221 PRAGMA foreign_keys = OFF; 222 PRAGMA foreign_keys = OFF;
222 BEGIN; 223 BEGIN;
223 PRAGMA foreign_keys = ON; 224 PRAGMA foreign_keys = ON;
224 DELETE FROM t1; 225 DELETE FROM t1;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 } 259 }
259 } {} 260 } {}
260 261
261 #------------------------------------------------------------------------- 262 #-------------------------------------------------------------------------
262 # EVIDENCE-OF: R-61362-32087 Attempting to insert a row into the track 263 # EVIDENCE-OF: R-61362-32087 Attempting to insert a row into the track
263 # table that does not correspond to any row in the artist table will 264 # table that does not correspond to any row in the artist table will
264 # fail, 265 # fail,
265 # 266 #
266 do_test e_fkey-8.1 { 267 do_test e_fkey-8.1 {
267 catchsql { INSERT INTO track VALUES(1, 'track 1', 1) } 268 catchsql { INSERT INTO track VALUES(1, 'track 1', 1) }
268 } {1 {foreign key constraint failed}} 269 } {1 {FOREIGN KEY constraint failed}}
269 do_test e_fkey-8.2 { 270 do_test e_fkey-8.2 {
270 execsql { INSERT INTO artist VALUES(2, 'artist 1') } 271 execsql { INSERT INTO artist VALUES(2, 'artist 1') }
271 catchsql { INSERT INTO track VALUES(1, 'track 1', 1) } 272 catchsql { INSERT INTO track VALUES(1, 'track 1', 1) }
272 } {1 {foreign key constraint failed}} 273 } {1 {FOREIGN KEY constraint failed}}
273 do_test e_fkey-8.2 { 274 do_test e_fkey-8.2 {
274 execsql { INSERT INTO track VALUES(1, 'track 1', 2) } 275 execsql { INSERT INTO track VALUES(1, 'track 1', 2) }
275 } {} 276 } {}
276 277
277 #------------------------------------------------------------------------- 278 #-------------------------------------------------------------------------
278 # Attempting to delete a row from the 'artist' table while there are 279 # Attempting to delete a row from the 'artist' table while there are
279 # dependent rows in the track table also fails. 280 # dependent rows in the track table also fails.
280 # 281 #
281 # EVIDENCE-OF: R-24401-52400 as will attempting to delete a row from the 282 # EVIDENCE-OF: R-24401-52400 as will attempting to delete a row from the
282 # artist table when there exist dependent rows in the track table 283 # artist table when there exist dependent rows in the track table
283 # 284 #
284 do_test e_fkey-9.1 { 285 do_test e_fkey-9.1 {
285 catchsql { DELETE FROM artist WHERE artistid = 2 } 286 catchsql { DELETE FROM artist WHERE artistid = 2 }
286 } {1 {foreign key constraint failed}} 287 } {1 {FOREIGN KEY constraint failed}}
287 do_test e_fkey-9.2 { 288 do_test e_fkey-9.2 {
288 execsql { 289 execsql {
289 DELETE FROM track WHERE trackartist = 2; 290 DELETE FROM track WHERE trackartist = 2;
290 DELETE FROM artist WHERE artistid = 2; 291 DELETE FROM artist WHERE artistid = 2;
291 } 292 }
292 } {} 293 } {}
293 294
294 #------------------------------------------------------------------------- 295 #-------------------------------------------------------------------------
295 # If the foreign key column (trackartist) in table 'track' is set to NULL, 296 # If the foreign key column (trackartist) in table 'track' is set to NULL,
296 # there is no requirement for a matching row in the 'artist' table. 297 # there is no requirement for a matching row in the 'artist' table.
297 # 298 #
298 # EVIDENCE-OF: R-23980-48859 There is one exception: if the foreign key 299 # EVIDENCE-OF: R-23980-48859 There is one exception: if the foreign key
299 # column in the track table is NULL, then no corresponding entry in the 300 # column in the track table is NULL, then no corresponding entry in the
300 # artist table is required. 301 # artist table is required.
301 # 302 #
302 do_test e_fkey-10.1 { 303 do_test e_fkey-10.1 {
303 execsql { 304 execsql {
304 INSERT INTO track VALUES(1, 'track 1', NULL); 305 INSERT INTO track VALUES(1, 'track 1', NULL);
305 INSERT INTO track VALUES(2, 'track 2', NULL); 306 INSERT INTO track VALUES(2, 'track 2', NULL);
306 } 307 }
307 } {} 308 } {}
308 do_test e_fkey-10.2 { 309 do_test e_fkey-10.2 {
309 execsql { SELECT * FROM artist } 310 execsql { SELECT * FROM artist }
310 } {} 311 } {}
311 do_test e_fkey-10.3 { 312 do_test e_fkey-10.3 {
312 # Setting the trackid to a non-NULL value fails, of course. 313 # Setting the trackid to a non-NULL value fails, of course.
313 catchsql { UPDATE track SET trackartist = 5 WHERE trackid = 1 } 314 catchsql { UPDATE track SET trackartist = 5 WHERE trackid = 1 }
314 } {1 {foreign key constraint failed}} 315 } {1 {FOREIGN KEY constraint failed}}
315 do_test e_fkey-10.4 { 316 do_test e_fkey-10.4 {
316 execsql { 317 execsql {
317 INSERT INTO artist VALUES(5, 'artist 5'); 318 INSERT INTO artist VALUES(5, 'artist 5');
318 UPDATE track SET trackartist = 5 WHERE trackid = 1; 319 UPDATE track SET trackartist = 5 WHERE trackid = 1;
319 } 320 }
320 catchsql { DELETE FROM artist WHERE artistid = 5} 321 catchsql { DELETE FROM artist WHERE artistid = 5}
321 } {1 {foreign key constraint failed}} 322 } {1 {FOREIGN KEY constraint failed}}
322 do_test e_fkey-10.5 { 323 do_test e_fkey-10.5 {
323 execsql { 324 execsql {
324 UPDATE track SET trackartist = NULL WHERE trackid = 1; 325 UPDATE track SET trackartist = NULL WHERE trackid = 1;
325 DELETE FROM artist WHERE artistid = 5; 326 DELETE FROM artist WHERE artistid = 5;
326 } 327 }
327 } {} 328 } {}
328 329
329 #------------------------------------------------------------------------- 330 #-------------------------------------------------------------------------
330 # Test that the following is true fo all rows in the track table: 331 # Test that the following is true fo all rows in the track table:
331 # 332 #
332 # trackartist IS NULL OR 333 # trackartist IS NULL OR
333 # EXISTS(SELECT 1 FROM artist WHERE artistid=trackartist) 334 # EXISTS(SELECT 1 FROM artist WHERE artistid=trackartist)
334 # 335 #
335 # EVIDENCE-OF: R-52486-21352 Expressed in SQL, this means that for every 336 # EVIDENCE-OF: R-52486-21352 Expressed in SQL, this means that for every
336 # row in the track table, the following expression evaluates to true: 337 # row in the track table, the following expression evaluates to true:
337 # trackartist IS NULL OR EXISTS(SELECT 1 FROM artist WHERE 338 # trackartist IS NULL OR EXISTS(SELECT 1 FROM artist WHERE
338 # artistid=trackartist) 339 # artistid=trackartist)
339 340
340 # This procedure executes a test case to check that statement 341 # This procedure executes a test case to check that statement
341 # R-52486-21352 is true after executing the SQL statement passed. 342 # R-52486-21352 is true after executing the SQL statement passed.
342 # as the second argument. 343 # as the second argument.
343 proc test_r52486_21352 {tn sql} { 344 proc test_r52486_21352 {tn sql} {
344 set res [catchsql $sql] 345 set res [catchsql $sql]
345 set results { 346 set results {
346 {0 {}} 347 {0 {}}
347 {1 {PRIMARY KEY must be unique}} 348 {1 {UNIQUE constraint failed: artist.artistid}}
348 {1 {foreign key constraint failed}} 349 {1 {FOREIGN KEY constraint failed}}
349 } 350 }
350 if {[lsearch $results $res]<0} { 351 if {[lsearch $results $res]<0} {
351 error $res 352 error $res
352 } 353 }
353 354
354 do_test e_fkey-11.$tn { 355 do_test e_fkey-11.$tn {
355 execsql { 356 execsql {
356 SELECT count(*) FROM track WHERE NOT ( 357 SELECT count(*) FROM track WHERE NOT (
357 trackartist IS NULL OR 358 trackartist IS NULL OR
358 EXISTS(SELECT 1 FROM artist WHERE artistid=trackartist) 359 EXISTS(SELECT 1 FROM artist WHERE artistid=trackartist)
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 CREATE TABLE track( 403 CREATE TABLE track(
403 trackid INTEGER, 404 trackid INTEGER,
404 trackname TEXT, 405 trackname TEXT,
405 trackartist INTEGER NOT NULL, 406 trackartist INTEGER NOT NULL,
406 FOREIGN KEY(trackartist) REFERENCES artist(artistid) 407 FOREIGN KEY(trackartist) REFERENCES artist(artistid)
407 ); 408 );
408 } 409 }
409 } {} 410 } {}
410 do_test e_fkey-12.2 { 411 do_test e_fkey-12.2 {
411 catchsql { INSERT INTO track VALUES(14, 'Mr. Bojangles', NULL) } 412 catchsql { INSERT INTO track VALUES(14, 'Mr. Bojangles', NULL) }
412 } {1 {track.trackartist may not be NULL}} 413 } {1 {NOT NULL constraint failed: track.trackartist}}
413 414
414 #------------------------------------------------------------------------- 415 #-------------------------------------------------------------------------
415 # EVIDENCE-OF: R-16127-35442 416 # EVIDENCE-OF: R-16127-35442
416 # 417 #
417 # Test an example from foreignkeys.html. 418 # Test an example from foreignkeys.html.
418 # 419 #
419 drop_all_tables 420 drop_all_tables
420 do_test e_fkey-13.1 { 421 do_test e_fkey-13.1 {
421 execsql { 422 execsql {
422 CREATE TABLE artist( 423 CREATE TABLE artist(
423 artistid INTEGER PRIMARY KEY, 424 artistid INTEGER PRIMARY KEY,
424 artistname TEXT 425 artistname TEXT
425 ); 426 );
426 CREATE TABLE track( 427 CREATE TABLE track(
427 trackid INTEGER, 428 trackid INTEGER,
428 trackname TEXT, 429 trackname TEXT,
429 trackartist INTEGER, 430 trackartist INTEGER,
430 FOREIGN KEY(trackartist) REFERENCES artist(artistid) 431 FOREIGN KEY(trackartist) REFERENCES artist(artistid)
431 ); 432 );
432 INSERT INTO artist VALUES(1, 'Dean Martin'); 433 INSERT INTO artist VALUES(1, 'Dean Martin');
433 INSERT INTO artist VALUES(2, 'Frank Sinatra'); 434 INSERT INTO artist VALUES(2, 'Frank Sinatra');
434 INSERT INTO track VALUES(11, 'That''s Amore', 1); 435 INSERT INTO track VALUES(11, 'That''s Amore', 1);
435 INSERT INTO track VALUES(12, 'Christmas Blues', 1); 436 INSERT INTO track VALUES(12, 'Christmas Blues', 1);
436 INSERT INTO track VALUES(13, 'My Way', 2); 437 INSERT INTO track VALUES(13, 'My Way', 2);
437 } 438 }
438 } {} 439 } {}
439 do_test e_fkey-13.2 { 440 do_test e_fkey-13.2 {
440 catchsql { INSERT INTO track VALUES(14, 'Mr. Bojangles', 3) } 441 catchsql { INSERT INTO track VALUES(14, 'Mr. Bojangles', 3) }
441 } {1 {foreign key constraint failed}} 442 } {1 {FOREIGN KEY constraint failed}}
442 do_test e_fkey-13.3 { 443 do_test e_fkey-13.3 {
443 execsql { INSERT INTO track VALUES(14, 'Mr. Bojangles', NULL) } 444 execsql { INSERT INTO track VALUES(14, 'Mr. Bojangles', NULL) }
444 } {} 445 } {}
445 do_test e_fkey-13.4 { 446 do_test e_fkey-13.4 {
446 catchsql { 447 catchsql {
447 UPDATE track SET trackartist = 3 WHERE trackname = 'Mr. Bojangles'; 448 UPDATE track SET trackartist = 3 WHERE trackname = 'Mr. Bojangles';
448 } 449 }
449 } {1 {foreign key constraint failed}} 450 } {1 {FOREIGN KEY constraint failed}}
450 do_test e_fkey-13.5 { 451 do_test e_fkey-13.5 {
451 execsql { 452 execsql {
452 INSERT INTO artist VALUES(3, 'Sammy Davis Jr.'); 453 INSERT INTO artist VALUES(3, 'Sammy Davis Jr.');
453 UPDATE track SET trackartist = 3 WHERE trackname = 'Mr. Bojangles'; 454 UPDATE track SET trackartist = 3 WHERE trackname = 'Mr. Bojangles';
454 INSERT INTO track VALUES(15, 'Boogie Woogie', 3); 455 INSERT INTO track VALUES(15, 'Boogie Woogie', 3);
455 } 456 }
456 } {} 457 } {}
457 458
458 #------------------------------------------------------------------------- 459 #-------------------------------------------------------------------------
459 # EVIDENCE-OF: R-15958-50233 460 # EVIDENCE-OF: R-15958-50233
460 # 461 #
461 # Test the second example from the first section of foreignkeys.html. 462 # Test the second example from the first section of foreignkeys.html.
462 # 463 #
463 do_test e_fkey-14.1 { 464 do_test e_fkey-14.1 {
464 catchsql { 465 catchsql {
465 DELETE FROM artist WHERE artistname = 'Frank Sinatra'; 466 DELETE FROM artist WHERE artistname = 'Frank Sinatra';
466 } 467 }
467 } {1 {foreign key constraint failed}} 468 } {1 {FOREIGN KEY constraint failed}}
468 do_test e_fkey-14.2 { 469 do_test e_fkey-14.2 {
469 execsql { 470 execsql {
470 DELETE FROM track WHERE trackname = 'My Way'; 471 DELETE FROM track WHERE trackname = 'My Way';
471 DELETE FROM artist WHERE artistname = 'Frank Sinatra'; 472 DELETE FROM artist WHERE artistname = 'Frank Sinatra';
472 } 473 }
473 } {} 474 } {}
474 do_test e_fkey-14.3 { 475 do_test e_fkey-14.3 {
475 catchsql { 476 catchsql {
476 UPDATE artist SET artistid=4 WHERE artistname = 'Dean Martin'; 477 UPDATE artist SET artistid=4 WHERE artistname = 'Dean Martin';
477 } 478 }
478 } {1 {foreign key constraint failed}} 479 } {1 {FOREIGN KEY constraint failed}}
479 do_test e_fkey-14.4 { 480 do_test e_fkey-14.4 {
480 execsql { 481 execsql {
481 DELETE FROM track WHERE trackname IN('That''s Amore', 'Christmas Blues'); 482 DELETE FROM track WHERE trackname IN('That''s Amore', 'Christmas Blues');
482 UPDATE artist SET artistid=4 WHERE artistname = 'Dean Martin'; 483 UPDATE artist SET artistid=4 WHERE artistname = 'Dean Martin';
483 } 484 }
484 } {} 485 } {}
485 486
486 487
487 #------------------------------------------------------------------------- 488 #-------------------------------------------------------------------------
488 # EVIDENCE-OF: R-56032-24923 The foreign key constraint is satisfied if 489 # EVIDENCE-OF: R-56032-24923 The foreign key constraint is satisfied if
(...skipping 17 matching lines...) Expand all
506 INSERT INTO par VALUES(1); 507 INSERT INTO par VALUES(1);
507 INSERT INTO par VALUES('1'); 508 INSERT INTO par VALUES('1');
508 INSERT INTO par VALUES(X'31'); 509 INSERT INTO par VALUES(X'31');
509 SELECT typeof(p) FROM par; 510 SELECT typeof(p) FROM par;
510 } 511 }
511 } {integer text blob} 512 } {integer text blob}
512 513
513 proc test_efkey_45 {tn isError sql} { 514 proc test_efkey_45 {tn isError sql} {
514 do_test e_fkey-15.$tn.1 " 515 do_test e_fkey-15.$tn.1 "
515 catchsql {$sql} 516 catchsql {$sql}
516 " [lindex {{0 {}} {1 {foreign key constraint failed}}} $isError] 517 " [lindex {{0 {}} {1 {FOREIGN KEY constraint failed}}} $isError]
517 518
518 do_test e_fkey-15.$tn.2 { 519 do_test e_fkey-15.$tn.2 {
519 execsql { 520 execsql {
520 SELECT * FROM chi WHERE c IS NOT NULL AND c NOT IN (SELECT p FROM par) 521 SELECT * FROM chi WHERE c IS NOT NULL AND c NOT IN (SELECT p FROM par)
521 } 522 }
522 } {} 523 } {}
523 } 524 }
524 525
525 test_efkey_45 1 0 "INSERT INTO chi VALUES(1)" 526 test_efkey_45 1 0 "INSERT INTO chi VALUES(1)"
526 test_efkey_45 2 1 "INSERT INTO chi VALUES('1.0')" 527 test_efkey_45 2 1 "INSERT INTO chi VALUES('1.0')"
(...skipping 23 matching lines...) Expand all
550 execsql { 551 execsql {
551 INSERT INTO t1 VALUES('oNe'); 552 INSERT INTO t1 VALUES('oNe');
552 INSERT INTO t2 VALUES('one'); 553 INSERT INTO t2 VALUES('one');
553 INSERT INTO t2 VALUES('ONE'); 554 INSERT INTO t2 VALUES('ONE');
554 UPDATE t2 SET b = 'OnE'; 555 UPDATE t2 SET b = 'OnE';
555 UPDATE t1 SET a = 'ONE'; 556 UPDATE t1 SET a = 'ONE';
556 } 557 }
557 } {} 558 } {}
558 do_test e_fkey-16.3 { 559 do_test e_fkey-16.3 {
559 catchsql { UPDATE t2 SET b = 'two' WHERE rowid = 1 } 560 catchsql { UPDATE t2 SET b = 'two' WHERE rowid = 1 }
560 } {1 {foreign key constraint failed}} 561 } {1 {FOREIGN KEY constraint failed}}
561 do_test e_fkey-16.4 { 562 do_test e_fkey-16.4 {
562 catchsql { DELETE FROM t1 WHERE rowid = 1 } 563 catchsql { DELETE FROM t1 WHERE rowid = 1 }
563 } {1 {foreign key constraint failed}} 564 } {1 {FOREIGN KEY constraint failed}}
564 565
565 #------------------------------------------------------------------------- 566 #-------------------------------------------------------------------------
566 # Specifically, test that when comparing child and parent key values the 567 # Specifically, test that when comparing child and parent key values the
567 # affinity of the parent key column is applied to the child key value 568 # affinity of the parent key column is applied to the child key value
568 # before the comparison takes place. 569 # before the comparison takes place.
569 # 570 #
570 # EVIDENCE-OF: R-04240-13860 When comparing values, if the parent key 571 # EVIDENCE-OF: R-04240-13860 When comparing values, if the parent key
571 # column has an affinity, then that affinity is applied to the child key 572 # column has an affinity, then that affinity is applied to the child key
572 # value before the comparison is performed. 573 # value before the comparison is performed.
573 # 574 #
(...skipping 11 matching lines...) Expand all
585 INSERT INTO t1 VALUES('three'); 586 INSERT INTO t1 VALUES('three');
586 INSERT INTO t2 VALUES('2.0'); 587 INSERT INTO t2 VALUES('2.0');
587 SELECT b, typeof(b) FROM t2; 588 SELECT b, typeof(b) FROM t2;
588 } 589 }
589 } {2.0 text} 590 } {2.0 text}
590 do_test e_fkey-17.3 { 591 do_test e_fkey-17.3 {
591 execsql { SELECT typeof(a) FROM t1 } 592 execsql { SELECT typeof(a) FROM t1 }
592 } {integer integer text} 593 } {integer integer text}
593 do_test e_fkey-17.4 { 594 do_test e_fkey-17.4 {
594 catchsql { DELETE FROM t1 WHERE rowid = 2 } 595 catchsql { DELETE FROM t1 WHERE rowid = 2 }
595 } {1 {foreign key constraint failed}} 596 } {1 {FOREIGN KEY constraint failed}}
596 597
597 ########################################################################### 598 ###########################################################################
598 ### SECTION 3: Required and Suggested Database Indexes 599 ### SECTION 3: Required and Suggested Database Indexes
599 ########################################################################### 600 ###########################################################################
600 601
601 #------------------------------------------------------------------------- 602 #-------------------------------------------------------------------------
602 # A parent key must be either a PRIMARY KEY, subject to a UNIQUE 603 # A parent key must be either a PRIMARY KEY, subject to a UNIQUE
603 # constraint, or have a UNIQUE index created on it. 604 # constraint, or have a UNIQUE index created on it.
604 # 605 #
605 # EVIDENCE-OF: R-13435-26311 Usually, the parent key of a foreign key 606 # EVIDENCE-OF: R-13435-26311 Usually, the parent key of a foreign key
(...skipping 14 matching lines...) Expand all
620 do_test e_fkey-18.1 { 621 do_test e_fkey-18.1 {
621 execsql { 622 execsql {
622 CREATE TABLE t2(a REFERENCES t1(x)); 623 CREATE TABLE t2(a REFERENCES t1(x));
623 } 624 }
624 } {} 625 } {}
625 proc test_efkey_57 {tn isError sql} { 626 proc test_efkey_57 {tn isError sql} {
626 catchsql { DROP TABLE t1 } 627 catchsql { DROP TABLE t1 }
627 execsql $sql 628 execsql $sql
628 do_test e_fkey-18.$tn { 629 do_test e_fkey-18.$tn {
629 catchsql { INSERT INTO t2 VALUES(NULL) } 630 catchsql { INSERT INTO t2 VALUES(NULL) }
630 } [lindex {{0 {}} {1 {foreign key mismatch}}} $isError] 631 } [lindex {{0 {}} {/1 {foreign key mismatch - ".*" referencing ".*"}/}} \
632 $isError]
631 } 633 }
632 test_efkey_57 2 0 { CREATE TABLE t1(x PRIMARY KEY) } 634 test_efkey_57 2 0 { CREATE TABLE t1(x PRIMARY KEY) }
633 test_efkey_57 3 0 { CREATE TABLE t1(x UNIQUE) } 635 test_efkey_57 3 0 { CREATE TABLE t1(x UNIQUE) }
634 test_efkey_57 4 0 { CREATE TABLE t1(x); CREATE UNIQUE INDEX t1i ON t1(x) } 636 test_efkey_57 4 0 { CREATE TABLE t1(x); CREATE UNIQUE INDEX t1i ON t1(x) }
635 test_efkey_57 5 1 { 637 test_efkey_57 5 1 {
636 CREATE TABLE t1(x); 638 CREATE TABLE t1(x);
637 CREATE UNIQUE INDEX t1i ON t1(x COLLATE nocase); 639 CREATE UNIQUE INDEX t1i ON t1(x COLLATE nocase);
638 } 640 }
639 test_efkey_57 6 1 { CREATE TABLE t1(x) } 641 test_efkey_57 6 1 { CREATE TABLE t1(x) }
640 test_efkey_57 7 1 { CREATE TABLE t1(x, y, PRIMARY KEY(x, y)) } 642 test_efkey_57 7 1 { CREATE TABLE t1(x, y, PRIMARY KEY(x, y)) }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 do_test e_fkey-19.2 { 693 do_test e_fkey-19.2 {
692 execsql { 694 execsql {
693 INSERT INTO parent VALUES(1, 2, 3, 4, 5, 6); 695 INSERT INTO parent VALUES(1, 2, 3, 4, 5, 6);
694 INSERT INTO child1 VALUES('xxx', 1); 696 INSERT INTO child1 VALUES('xxx', 1);
695 INSERT INTO child2 VALUES('xxx', 2); 697 INSERT INTO child2 VALUES('xxx', 2);
696 INSERT INTO child3 VALUES(3, 4); 698 INSERT INTO child3 VALUES(3, 4);
697 } 699 }
698 } {} 700 } {}
699 do_test e_fkey-19.2 { 701 do_test e_fkey-19.2 {
700 catchsql { INSERT INTO child4 VALUES('xxx', 5) } 702 catchsql { INSERT INTO child4 VALUES('xxx', 5) }
701 } {1 {foreign key mismatch}} 703 } {1 {foreign key mismatch - "child4" referencing "parent"}}
702 do_test e_fkey-19.3 { 704 do_test e_fkey-19.3 {
703 catchsql { INSERT INTO child5 VALUES('xxx', 6) } 705 catchsql { INSERT INTO child5 VALUES('xxx', 6) }
704 } {1 {foreign key mismatch}} 706 } {1 {foreign key mismatch - "child5" referencing "parent"}}
705 do_test e_fkey-19.4 { 707 do_test e_fkey-19.4 {
706 catchsql { INSERT INTO child6 VALUES(2, 3) } 708 catchsql { INSERT INTO child6 VALUES(2, 3) }
707 } {1 {foreign key mismatch}} 709 } {1 {foreign key mismatch - "child6" referencing "parent"}}
708 do_test e_fkey-19.5 { 710 do_test e_fkey-19.5 {
709 catchsql { INSERT INTO child7 VALUES(3) } 711 catchsql { INSERT INTO child7 VALUES(3) }
710 } {1 {foreign key mismatch}} 712 } {1 {foreign key mismatch - "child7" referencing "parent"}}
711 713
712 #------------------------------------------------------------------------- 714 #-------------------------------------------------------------------------
713 # Test errors in the database schema that are detected while preparing 715 # Test errors in the database schema that are detected while preparing
714 # DML statements. The error text for these messages always matches 716 # DML statements. The error text for these messages always matches
715 # either "foreign key mismatch" or "no such table*" (using [string match]). 717 # either "foreign key mismatch" or "no such table*" (using [string match]).
716 # 718 #
717 # EVIDENCE-OF: R-45488-08504 If the database schema contains foreign key 719 # EVIDENCE-OF: R-45488-08504 If the database schema contains foreign key
718 # errors that require looking at more than one table definition to 720 # errors that require looking at more than one table definition to
719 # identify, then those errors are not detected when the tables are 721 # identify, then those errors are not detected when the tables are
720 # created. 722 # created.
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 CREATE TABLE p6(a PRIMARY KEY, b); 760 CREATE TABLE p6(a PRIMARY KEY, b);
759 CREATE TABLE c6(c, d, FOREIGN KEY(c, d) REFERENCES p6); 761 CREATE TABLE c6(c, d, FOREIGN KEY(c, d) REFERENCES p6);
760 762
761 CREATE TABLE p7(a, b, PRIMARY KEY(a, b)); 763 CREATE TABLE p7(a, b, PRIMARY KEY(a, b));
762 CREATE TABLE c7(c, d REFERENCES p7); 764 CREATE TABLE c7(c, d REFERENCES p7);
763 } 765 }
764 } {} 766 } {}
765 767
766 foreach {tn tbl ptbl err} { 768 foreach {tn tbl ptbl err} {
767 2 c1 {} "no such table: main.nosuchtable" 769 2 c1 {} "no such table: main.nosuchtable"
768 3 c2 p2 "foreign key mismatch" 770 3 c2 p2 "foreign key mismatch - \"c2\" referencing \"p2\""
769 4 c3 p3 "foreign key mismatch" 771 4 c3 p3 "foreign key mismatch - \"c3\" referencing \"p3\""
770 5 c4 p4 "foreign key mismatch" 772 5 c4 p4 "foreign key mismatch - \"c4\" referencing \"p4\""
771 6 c5 p5 "foreign key mismatch" 773 6 c5 p5 "foreign key mismatch - \"c5\" referencing \"p5\""
772 7 c6 p6 "foreign key mismatch" 774 7 c6 p6 "foreign key mismatch - \"c6\" referencing \"p6\""
773 8 c7 p7 "foreign key mismatch" 775 8 c7 p7 "foreign key mismatch - \"c7\" referencing \"p7\""
774 } { 776 } {
775 do_test e_fkey-20.$tn.1 { 777 do_test e_fkey-20.$tn.1 {
776 catchsql "INSERT INTO $tbl VALUES('a', 'b')" 778 catchsql "INSERT INTO $tbl VALUES('a', 'b')"
777 } [list 1 $err] 779 } [list 1 $err]
778 do_test e_fkey-20.$tn.2 { 780 do_test e_fkey-20.$tn.2 {
779 catchsql "UPDATE $tbl SET c = ?, d = ?" 781 catchsql "UPDATE $tbl SET c = ?, d = ?"
780 } [list 1 $err] 782 } [list 1 $err]
781 do_test e_fkey-20.$tn.3 { 783 do_test e_fkey-20.$tn.3 {
782 catchsql "INSERT INTO $tbl SELECT ?, ?" 784 catchsql "INSERT INTO $tbl SELECT ?, ?"
783 } [list 1 $err] 785 } [list 1 $err]
(...skipping 29 matching lines...) Expand all
813 } 815 }
814 } {} 816 } {}
815 do_test e_fkey-21.2 { 817 do_test e_fkey-21.2 {
816 execsql { 818 execsql {
817 INSERT INTO parent2 VALUES('I', 'II'); 819 INSERT INTO parent2 VALUES('I', 'II');
818 INSERT INTO child8 VALUES('I', 'II'); 820 INSERT INTO child8 VALUES('I', 'II');
819 } 821 }
820 } {} 822 } {}
821 do_test e_fkey-21.3 { 823 do_test e_fkey-21.3 {
822 catchsql { INSERT INTO child9 VALUES('I') } 824 catchsql { INSERT INTO child9 VALUES('I') }
823 } {1 {foreign key mismatch}} 825 } {1 {foreign key mismatch - "child9" referencing "parent2"}}
824 do_test e_fkey-21.4 { 826 do_test e_fkey-21.4 {
825 catchsql { INSERT INTO child9 VALUES('II') } 827 catchsql { INSERT INTO child9 VALUES('II') }
826 } {1 {foreign key mismatch}} 828 } {1 {foreign key mismatch - "child9" referencing "parent2"}}
827 do_test e_fkey-21.5 { 829 do_test e_fkey-21.5 {
828 catchsql { INSERT INTO child9 VALUES(NULL) } 830 catchsql { INSERT INTO child9 VALUES(NULL) }
829 } {1 {foreign key mismatch}} 831 } {1 {foreign key mismatch - "child9" referencing "parent2"}}
830 do_test e_fkey-21.6 { 832 do_test e_fkey-21.6 {
831 catchsql { INSERT INTO child10 VALUES('I', 'II', 'III') } 833 catchsql { INSERT INTO child10 VALUES('I', 'II', 'III') }
832 } {1 {foreign key mismatch}} 834 } {1 {foreign key mismatch - "child10" referencing "parent2"}}
833 do_test e_fkey-21.7 { 835 do_test e_fkey-21.7 {
834 catchsql { INSERT INTO child10 VALUES(1, 2, 3) } 836 catchsql { INSERT INTO child10 VALUES(1, 2, 3) }
835 } {1 {foreign key mismatch}} 837 } {1 {foreign key mismatch - "child10" referencing "parent2"}}
836 do_test e_fkey-21.8 { 838 do_test e_fkey-21.8 {
837 catchsql { INSERT INTO child10 VALUES(NULL, NULL, NULL) } 839 catchsql { INSERT INTO child10 VALUES(NULL, NULL, NULL) }
838 } {1 {foreign key mismatch}} 840 } {1 {foreign key mismatch - "child10" referencing "parent2"}}
839 841
840 #------------------------------------------------------------------------- 842 #-------------------------------------------------------------------------
841 # Test errors that are reported when creating the child table. 843 # Test errors that are reported when creating the child table.
842 # Specifically: 844 # Specifically:
843 # 845 #
844 # * different number of child and parent key columns, and 846 # * different number of child and parent key columns, and
845 # * child columns that do not exist. 847 # * child columns that do not exist.
846 # 848 #
847 # EVIDENCE-OF: R-23682-59820 By contrast, if foreign key errors can be 849 # EVIDENCE-OF: R-23682-59820 By contrast, if foreign key errors can be
848 # recognized simply by looking at the definition of the child table and 850 # recognized simply by looking at the definition of the child table and
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
888 execsql { 890 execsql {
889 CREATE TABLE p1(a, b, PRIMARY KEY(a, b)); 891 CREATE TABLE p1(a, b, PRIMARY KEY(a, b));
890 CREATE TABLE p2(a, b PRIMARY KEY); 892 CREATE TABLE p2(a, b PRIMARY KEY);
891 CREATE TABLE c1(c, d, FOREIGN KEY(c, d) REFERENCES p1); 893 CREATE TABLE c1(c, d, FOREIGN KEY(c, d) REFERENCES p1);
892 CREATE TABLE c2(a, b REFERENCES p2); 894 CREATE TABLE c2(a, b REFERENCES p2);
893 } 895 }
894 } {} 896 } {}
895 proc test_efkey_60 {tn isError sql} { 897 proc test_efkey_60 {tn isError sql} {
896 do_test e_fkey-23.$tn " 898 do_test e_fkey-23.$tn "
897 catchsql {$sql} 899 catchsql {$sql}
898 " [lindex {{0 {}} {1 {foreign key constraint failed}}} $isError] 900 " [lindex {{0 {}} {1 {FOREIGN KEY constraint failed}}} $isError]
899 } 901 }
900 902
901 test_efkey_60 2 1 "INSERT INTO c1 VALUES(239, 231)" 903 test_efkey_60 2 1 "INSERT INTO c1 VALUES(239, 231)"
902 test_efkey_60 3 0 "INSERT INTO p1 VALUES(239, 231)" 904 test_efkey_60 3 0 "INSERT INTO p1 VALUES(239, 231)"
903 test_efkey_60 4 0 "INSERT INTO c1 VALUES(239, 231)" 905 test_efkey_60 4 0 "INSERT INTO c1 VALUES(239, 231)"
904 test_efkey_60 5 1 "INSERT INTO c2 VALUES(239, 231)" 906 test_efkey_60 5 1 "INSERT INTO c2 VALUES(239, 231)"
905 test_efkey_60 6 0 "INSERT INTO p2 VALUES(239, 231)" 907 test_efkey_60 6 0 "INSERT INTO p2 VALUES(239, 231)"
906 test_efkey_60 7 0 "INSERT INTO c2 VALUES(239, 231)" 908 test_efkey_60 7 0 "INSERT INTO c2 VALUES(239, 231)"
907 909
908 #------------------------------------------------------------------------- 910 #-------------------------------------------------------------------------
(...skipping 16 matching lines...) Expand all
925 CREATE TABLE c1(a, b, FOREIGN KEY(a, b) REFERENCES parent(x, y)); 927 CREATE TABLE c1(a, b, FOREIGN KEY(a, b) REFERENCES parent(x, y));
926 CREATE TABLE c2(a, b, FOREIGN KEY(a, b) REFERENCES parent(x, y)); 928 CREATE TABLE c2(a, b, FOREIGN KEY(a, b) REFERENCES parent(x, y));
927 CREATE TABLE c3(a, b, FOREIGN KEY(a, b) REFERENCES parent(x, y)); 929 CREATE TABLE c3(a, b, FOREIGN KEY(a, b) REFERENCES parent(x, y));
928 CREATE INDEX c2i ON c2(a, b); 930 CREATE INDEX c2i ON c2(a, b);
929 CREATE UNIQUE INDEX c3i ON c2(b, a); 931 CREATE UNIQUE INDEX c3i ON c2(b, a);
930 } 932 }
931 } {} 933 } {}
932 proc test_efkey_61 {tn isError sql} { 934 proc test_efkey_61 {tn isError sql} {
933 do_test e_fkey-24.$tn " 935 do_test e_fkey-24.$tn "
934 catchsql {$sql} 936 catchsql {$sql}
935 " [lindex {{0 {}} {1 {foreign key constraint failed}}} $isError] 937 " [lindex {{0 {}} {1 {FOREIGN KEY constraint failed}}} $isError]
936 } 938 }
937 foreach {tn c} [list 2 c1 3 c2 4 c3] { 939 foreach {tn c} [list 2 c1 3 c2 4 c3] {
938 test_efkey_61 $tn.1 1 "INSERT INTO $c VALUES(1, 2)" 940 test_efkey_61 $tn.1 1 "INSERT INTO $c VALUES(1, 2)"
939 test_efkey_61 $tn.2 0 "INSERT INTO parent VALUES(1, 2)" 941 test_efkey_61 $tn.2 0 "INSERT INTO parent VALUES(1, 2)"
940 test_efkey_61 $tn.3 0 "INSERT INTO $c VALUES(1, 2)" 942 test_efkey_61 $tn.3 0 "INSERT INTO $c VALUES(1, 2)"
941 943
942 execsql "DELETE FROM $c ; DELETE FROM parent" 944 execsql "DELETE FROM $c ; DELETE FROM parent"
943 } 945 }
944 946
945 #------------------------------------------------------------------------- 947 #-------------------------------------------------------------------------
(...skipping 20 matching lines...) Expand all
966 trackartist INTEGER, 968 trackartist INTEGER,
967 FOREIGN KEY(trackartist) REFERENCES artist(artistid) 969 FOREIGN KEY(trackartist) REFERENCES artist(artistid)
968 ); 970 );
969 } 971 }
970 } {} 972 } {}
971 do_execsql_test e_fkey-25.2 { 973 do_execsql_test e_fkey-25.2 {
972 PRAGMA foreign_keys = OFF; 974 PRAGMA foreign_keys = OFF;
973 EXPLAIN QUERY PLAN DELETE FROM artist WHERE 1; 975 EXPLAIN QUERY PLAN DELETE FROM artist WHERE 1;
974 EXPLAIN QUERY PLAN SELECT rowid FROM track WHERE trackartist = ?; 976 EXPLAIN QUERY PLAN SELECT rowid FROM track WHERE trackartist = ?;
975 } { 977 } {
976 0 0 0 {SCAN TABLE artist (~1000000 rows)} 978 0 0 0 {SCAN TABLE artist}
977 0 0 0 {SCAN TABLE track (~100000 rows)} 979 0 0 0 {SCAN TABLE track}
978 } 980 }
979 do_execsql_test e_fkey-25.3 { 981 do_execsql_test e_fkey-25.3 {
980 PRAGMA foreign_keys = ON; 982 PRAGMA foreign_keys = ON;
981 EXPLAIN QUERY PLAN DELETE FROM artist WHERE 1; 983 EXPLAIN QUERY PLAN DELETE FROM artist WHERE 1;
982 } { 984 } {
983 0 0 0 {SCAN TABLE artist (~1000000 rows)} 985 0 0 0 {SCAN TABLE artist}
984 0 0 0 {SCAN TABLE track (~100000 rows)} 986 0 0 0 {SCAN TABLE track}
985 } 987 }
986 do_test e_fkey-25.4 { 988 do_test e_fkey-25.4 {
987 execsql { 989 execsql {
988 INSERT INTO artist VALUES(5, 'artist 5'); 990 INSERT INTO artist VALUES(5, 'artist 5');
989 INSERT INTO artist VALUES(6, 'artist 6'); 991 INSERT INTO artist VALUES(6, 'artist 6');
990 INSERT INTO artist VALUES(7, 'artist 7'); 992 INSERT INTO artist VALUES(7, 'artist 7');
991 INSERT INTO track VALUES(1, 'track 1', 5); 993 INSERT INTO track VALUES(1, 'track 1', 5);
992 INSERT INTO track VALUES(2, 'track 2', 6); 994 INSERT INTO track VALUES(2, 'track 2', 6);
993 } 995 }
994 } {} 996 } {}
995 997
996 do_test e_fkey-25.5 { 998 do_test e_fkey-25.5 {
997 concat \ 999 concat \
998 [execsql { SELECT rowid FROM track WHERE trackartist = 5 }] \ 1000 [execsql { SELECT rowid FROM track WHERE trackartist = 5 }] \
999 [catchsql { DELETE FROM artist WHERE artistid = 5 }] 1001 [catchsql { DELETE FROM artist WHERE artistid = 5 }]
1000 } {1 1 {foreign key constraint failed}} 1002 } {1 1 {FOREIGN KEY constraint failed}}
1001 1003
1002 do_test e_fkey-25.6 { 1004 do_test e_fkey-25.6 {
1003 concat \ 1005 concat \
1004 [execsql { SELECT rowid FROM track WHERE trackartist = 7 }] \ 1006 [execsql { SELECT rowid FROM track WHERE trackartist = 7 }] \
1005 [catchsql { DELETE FROM artist WHERE artistid = 7 }] 1007 [catchsql { DELETE FROM artist WHERE artistid = 7 }]
1006 } {0 {}} 1008 } {0 {}}
1007 1009
1008 do_test e_fkey-25.7 { 1010 do_test e_fkey-25.7 {
1009 concat \ 1011 concat \
1010 [execsql { SELECT rowid FROM track WHERE trackartist = 6 }] \ 1012 [execsql { SELECT rowid FROM track WHERE trackartist = 6 }] \
1011 [catchsql { DELETE FROM artist WHERE artistid = 6 }] 1013 [catchsql { DELETE FROM artist WHERE artistid = 6 }]
1012 } {2 1 {foreign key constraint failed}} 1014 } {2 1 {FOREIGN KEY constraint failed}}
1013 1015
1014 #------------------------------------------------------------------------- 1016 #-------------------------------------------------------------------------
1015 # EVIDENCE-OF: R-47936-10044 Or, more generally: 1017 # EVIDENCE-OF: R-47936-10044 Or, more generally:
1016 # SELECT rowid FROM <child-table> WHERE <child-key> = :parent_key_value 1018 # SELECT rowid FROM <child-table> WHERE <child-key> = :parent_key_value
1017 # 1019 #
1018 # Test that when a row is deleted from the parent table of an FK 1020 # Test that when a row is deleted from the parent table of an FK
1019 # constraint, the child table is queried for orphaned rows. The 1021 # constraint, the child table is queried for orphaned rows. The
1020 # query is equivalent to: 1022 # query is equivalent to:
1021 # 1023 #
1022 # SELECT rowid FROM <child-table> WHERE <child-key> = :parent_key_value 1024 # SELECT rowid FROM <child-table> WHERE <child-key> = :parent_key_value
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1091 ); 1093 );
1092 CREATE INDEX trackindex ON track(trackartist); 1094 CREATE INDEX trackindex ON track(trackartist);
1093 } 1095 }
1094 } {} 1096 } {}
1095 do_test e_fkey-27.2 { 1097 do_test e_fkey-27.2 {
1096 eqp { INSERT INTO artist VALUES(?, ?) } 1098 eqp { INSERT INTO artist VALUES(?, ?) }
1097 } {} 1099 } {}
1098 do_execsql_test e_fkey-27.3 { 1100 do_execsql_test e_fkey-27.3 {
1099 EXPLAIN QUERY PLAN UPDATE artist SET artistid = ?, artistname = ? 1101 EXPLAIN QUERY PLAN UPDATE artist SET artistid = ?, artistname = ?
1100 } { 1102 } {
1101 0 0 0 {SCAN TABLE artist (~1000000 rows)} 1103 0 0 0 {SCAN TABLE artist}
1102 0 0 0 {SEARCH TABLE track USING COVERING INDEX trackindex (trackartist=?) (~10 rows)} 1104 0 0 0 {SEARCH TABLE track USING COVERING INDEX trackindex (trackartist=?)}
1103 0 0 0 {SEARCH TABLE track USING COVERING INDEX trackindex (trackartist=?) (~10 rows)} 1105 0 0 0 {SEARCH TABLE track USING COVERING INDEX trackindex (trackartist=?)}
1104 } 1106 }
1105 do_execsql_test e_fkey-27.4 { 1107 do_execsql_test e_fkey-27.4 {
1106 EXPLAIN QUERY PLAN DELETE FROM artist 1108 EXPLAIN QUERY PLAN DELETE FROM artist
1107 } { 1109 } {
1108 0 0 0 {SCAN TABLE artist (~1000000 rows)} 1110 0 0 0 {SCAN TABLE artist}
1109 0 0 0 {SEARCH TABLE track USING COVERING INDEX trackindex (trackartist=?) (~10 rows)} 1111 0 0 0 {SEARCH TABLE track USING COVERING INDEX trackindex (trackartist=?)}
1110 } 1112 }
1111 1113
1112 1114
1113 ########################################################################### 1115 ###########################################################################
1114 ### SECTION 4.1: Composite Foreign Key Constraints 1116 ### SECTION 4.1: Composite Foreign Key Constraints
1115 ########################################################################### 1117 ###########################################################################
1116 1118
1117 #------------------------------------------------------------------------- 1119 #-------------------------------------------------------------------------
1118 # Check that parent and child keys must have the same number of columns. 1120 # Check that parent and child keys must have the same number of columns.
1119 # 1121 #
(...skipping 24 matching lines...) Expand all
1144 drop_all_tables 1146 drop_all_tables
1145 do_test e_fkey-28.$tn [list catchsql $sql] [list 1 $err] 1147 do_test e_fkey-28.$tn [list catchsql $sql] [list 1 $err]
1146 } 1148 }
1147 do_test e_fkey-28.8 { 1149 do_test e_fkey-28.8 {
1148 drop_all_tables 1150 drop_all_tables
1149 execsql { 1151 execsql {
1150 CREATE TABLE p(x PRIMARY KEY); 1152 CREATE TABLE p(x PRIMARY KEY);
1151 CREATE TABLE c(a, b, FOREIGN KEY(a,b) REFERENCES p); 1153 CREATE TABLE c(a, b, FOREIGN KEY(a,b) REFERENCES p);
1152 } 1154 }
1153 catchsql {DELETE FROM p} 1155 catchsql {DELETE FROM p}
1154 } {1 {foreign key mismatch}} 1156 } {1 {foreign key mismatch - "c" referencing "p"}}
1155 do_test e_fkey-28.9 { 1157 do_test e_fkey-28.9 {
1156 drop_all_tables 1158 drop_all_tables
1157 execsql { 1159 execsql {
1158 CREATE TABLE p(x, y, PRIMARY KEY(x,y)); 1160 CREATE TABLE p(x, y, PRIMARY KEY(x,y));
1159 CREATE TABLE c(a REFERENCES p); 1161 CREATE TABLE c(a REFERENCES p);
1160 } 1162 }
1161 catchsql {DELETE FROM p} 1163 catchsql {DELETE FROM p}
1162 } {1 {foreign key mismatch}} 1164 } {1 {foreign key mismatch - "c" referencing "p"}}
1163 1165
1164 1166
1165 #------------------------------------------------------------------------- 1167 #-------------------------------------------------------------------------
1166 # EVIDENCE-OF: R-24676-09859 1168 # EVIDENCE-OF: R-24676-09859
1167 # 1169 #
1168 # Test the example schema in the "Composite Foreign Key Constraints" 1170 # Test the example schema in the "Composite Foreign Key Constraints"
1169 # section. 1171 # section.
1170 # 1172 #
1171 do_test e_fkey-29.1 { 1173 do_test e_fkey-29.1 {
1172 execsql { 1174 execsql {
(...skipping 18 matching lines...) Expand all
1191 INSERT INTO album VALUES('Elvis Presley', 'Elvis'' Christmas Album', NULL); 1193 INSERT INTO album VALUES('Elvis Presley', 'Elvis'' Christmas Album', NULL);
1192 INSERT INTO song VALUES( 1194 INSERT INTO song VALUES(
1193 1, 'Elvis Presley', 'Elvis'' Christmas Album', 'Here Comes Santa Clause' 1195 1, 'Elvis Presley', 'Elvis'' Christmas Album', 'Here Comes Santa Clause'
1194 ); 1196 );
1195 } 1197 }
1196 } {} 1198 } {}
1197 do_test e_fkey-29.3 { 1199 do_test e_fkey-29.3 {
1198 catchsql { 1200 catchsql {
1199 INSERT INTO song VALUES(2, 'Elvis Presley', 'Elvis Is Back!', 'Fever'); 1201 INSERT INTO song VALUES(2, 'Elvis Presley', 'Elvis Is Back!', 'Fever');
1200 } 1202 }
1201 } {1 {foreign key constraint failed}} 1203 } {1 {FOREIGN KEY constraint failed}}
1202 1204
1203 1205
1204 #------------------------------------------------------------------------- 1206 #-------------------------------------------------------------------------
1205 # EVIDENCE-OF: R-33626-48418 In SQLite, if any of the child key columns 1207 # EVIDENCE-OF: R-33626-48418 In SQLite, if any of the child key columns
1206 # (in this case songartist and songalbum) are NULL, then there is no 1208 # (in this case songartist and songalbum) are NULL, then there is no
1207 # requirement for a corresponding row in the parent table. 1209 # requirement for a corresponding row in the parent table.
1208 # 1210 #
1209 do_test e_fkey-30.1 { 1211 do_test e_fkey-30.1 {
1210 execsql { 1212 execsql {
1211 INSERT INTO song VALUES(2, 'Elvis Presley', NULL, 'Fever'); 1213 INSERT INTO song VALUES(2, 'Elvis Presley', NULL, 'Fever');
(...skipping 20 matching lines...) Expand all
1232 do_test e_fkey-31.1 { 1234 do_test e_fkey-31.1 {
1233 execsql { 1235 execsql {
1234 CREATE TABLE king(a, b, PRIMARY KEY(a)); 1236 CREATE TABLE king(a, b, PRIMARY KEY(a));
1235 CREATE TABLE prince(c REFERENCES king, d); 1237 CREATE TABLE prince(c REFERENCES king, d);
1236 } 1238 }
1237 } {} 1239 } {}
1238 1240
1239 do_test e_fkey-31.2 { 1241 do_test e_fkey-31.2 {
1240 # Execute a statement that violates the immediate FK constraint. 1242 # Execute a statement that violates the immediate FK constraint.
1241 catchsql { INSERT INTO prince VALUES(1, 2) } 1243 catchsql { INSERT INTO prince VALUES(1, 2) }
1242 } {1 {foreign key constraint failed}} 1244 } {1 {FOREIGN KEY constraint failed}}
1243 1245
1244 do_test e_fkey-31.3 { 1246 do_test e_fkey-31.3 {
1245 # This time, use a trigger to fix the constraint violation before the 1247 # This time, use a trigger to fix the constraint violation before the
1246 # statement has finished executing. Then execute the same statement as 1248 # statement has finished executing. Then execute the same statement as
1247 # in the previous test case. This time, no error. 1249 # in the previous test case. This time, no error.
1248 execsql { 1250 execsql {
1249 CREATE TRIGGER kt AFTER INSERT ON prince WHEN 1251 CREATE TRIGGER kt AFTER INSERT ON prince WHEN
1250 NOT EXISTS (SELECT a FROM king WHERE a = new.c) 1252 NOT EXISTS (SELECT a FROM king WHERE a = new.c)
1251 BEGIN 1253 BEGIN
1252 INSERT INTO king VALUES(new.c, NULL); 1254 INSERT INTO king VALUES(new.c, NULL);
1253 END 1255 END
1254 } 1256 }
1255 execsql { INSERT INTO prince VALUES(1, 2) } 1257 execsql { INSERT INTO prince VALUES(1, 2) }
1256 } {} 1258 } {}
1257 1259
1258 # Test that operating inside a transaction makes no difference to 1260 # Test that operating inside a transaction makes no difference to
1259 # immediate constraint violation handling. 1261 # immediate constraint violation handling.
1260 do_test e_fkey-31.4 { 1262 do_test e_fkey-31.4 {
1261 execsql { 1263 execsql {
1262 BEGIN; 1264 BEGIN;
1263 INSERT INTO prince VALUES(2, 3); 1265 INSERT INTO prince VALUES(2, 3);
1264 DROP TRIGGER kt; 1266 DROP TRIGGER kt;
1265 } 1267 }
1266 catchsql { INSERT INTO prince VALUES(3, 4) } 1268 catchsql { INSERT INTO prince VALUES(3, 4) }
1267 } {1 {foreign key constraint failed}} 1269 } {1 {FOREIGN KEY constraint failed}}
1268 do_test e_fkey-31.5 { 1270 do_test e_fkey-31.5 {
1269 execsql { 1271 execsql {
1270 COMMIT; 1272 COMMIT;
1271 SELECT * FROM king; 1273 SELECT * FROM king;
1272 } 1274 }
1273 } {1 {} 2 {}} 1275 } {1 {} 2 {}}
1274 1276
1275 #------------------------------------------------------------------------- 1277 #-------------------------------------------------------------------------
1276 # Test that if a deferred constraint is violated within a transaction, 1278 # Test that if a deferred constraint is violated within a transaction,
1277 # nothing happens immediately and the database is allowed to persist 1279 # nothing happens immediately and the database is allowed to persist
(...skipping 10 matching lines...) Expand all
1288 # EVIDENCE-OF: R-55147-47664 For as long as the user has an open 1290 # EVIDENCE-OF: R-55147-47664 For as long as the user has an open
1289 # transaction, the database is allowed to exist in a state that violates 1291 # transaction, the database is allowed to exist in a state that violates
1290 # any number of deferred foreign key constraints. 1292 # any number of deferred foreign key constraints.
1291 # 1293 #
1292 # EVIDENCE-OF: R-29604-30395 However, COMMIT will fail as long as 1294 # EVIDENCE-OF: R-29604-30395 However, COMMIT will fail as long as
1293 # foreign key constraints remain in violation. 1295 # foreign key constraints remain in violation.
1294 # 1296 #
1295 proc test_efkey_34 {tn isError sql} { 1297 proc test_efkey_34 {tn isError sql} {
1296 do_test e_fkey-32.$tn " 1298 do_test e_fkey-32.$tn "
1297 catchsql {$sql} 1299 catchsql {$sql}
1298 " [lindex {{0 {}} {1 {foreign key constraint failed}}} $isError] 1300 " [lindex {{0 {}} {1 {FOREIGN KEY constraint failed}}} $isError]
1299 } 1301 }
1300 drop_all_tables 1302 drop_all_tables
1301 1303
1302 test_efkey_34 1 0 { 1304 test_efkey_34 1 0 {
1303 CREATE TABLE ll(k PRIMARY KEY); 1305 CREATE TABLE ll(k PRIMARY KEY);
1304 CREATE TABLE kk(c REFERENCES ll DEFERRABLE INITIALLY DEFERRED); 1306 CREATE TABLE kk(c REFERENCES ll DEFERRABLE INITIALLY DEFERRED);
1305 } 1307 }
1306 test_efkey_34 2 0 "BEGIN" 1308 test_efkey_34 2 0 "BEGIN"
1307 test_efkey_34 3 0 "INSERT INTO kk VALUES(5)" 1309 test_efkey_34 3 0 "INSERT INTO kk VALUES(5)"
1308 test_efkey_34 4 0 "INSERT INTO kk VALUES(10)" 1310 test_efkey_34 4 0 "INSERT INTO kk VALUES(10)"
(...skipping 10 matching lines...) Expand all
1319 # EVIDENCE-OF: R-56844-61705 If the current statement is not inside an 1321 # EVIDENCE-OF: R-56844-61705 If the current statement is not inside an
1320 # explicit transaction (a BEGIN/COMMIT/ROLLBACK block), then an implicit 1322 # explicit transaction (a BEGIN/COMMIT/ROLLBACK block), then an implicit
1321 # transaction is committed as soon as the statement has finished 1323 # transaction is committed as soon as the statement has finished
1322 # executing. In this case deferred constraints behave the same as 1324 # executing. In this case deferred constraints behave the same as
1323 # immediate constraints. 1325 # immediate constraints.
1324 # 1326 #
1325 drop_all_tables 1327 drop_all_tables
1326 proc test_efkey_35 {tn isError sql} { 1328 proc test_efkey_35 {tn isError sql} {
1327 do_test e_fkey-33.$tn " 1329 do_test e_fkey-33.$tn "
1328 catchsql {$sql} 1330 catchsql {$sql}
1329 " [lindex {{0 {}} {1 {foreign key constraint failed}}} $isError] 1331 " [lindex {{0 {}} {1 {FOREIGN KEY constraint failed}}} $isError]
1330 } 1332 }
1331 do_test e_fkey-33.1 { 1333 do_test e_fkey-33.1 {
1332 execsql { 1334 execsql {
1333 CREATE TABLE parent(x, y); 1335 CREATE TABLE parent(x, y);
1334 CREATE UNIQUE INDEX pi ON parent(x, y); 1336 CREATE UNIQUE INDEX pi ON parent(x, y);
1335 CREATE TABLE child(a, b, 1337 CREATE TABLE child(a, b,
1336 FOREIGN KEY(a, b) REFERENCES parent(x, y) DEFERRABLE INITIALLY DEFERRED 1338 FOREIGN KEY(a, b) REFERENCES parent(x, y) DEFERRABLE INITIALLY DEFERRED
1337 ); 1339 );
1338 } 1340 }
1339 } {} 1341 } {}
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1409 INSERT INTO c3 VALUES('g', 'h', 'i'); 1411 INSERT INTO c3 VALUES('g', 'h', 'i');
1410 INSERT INTO c4 VALUES('j', 'k', 'l'); 1412 INSERT INTO c4 VALUES('j', 'k', 'l');
1411 INSERT INTO c5 VALUES('m', 'n', 'o'); 1413 INSERT INTO c5 VALUES('m', 'n', 'o');
1412 INSERT INTO c6 VALUES('p', 'q', 'r'); 1414 INSERT INTO c6 VALUES('p', 'q', 'r');
1413 INSERT INTO c7 VALUES('s', 't', 'u'); 1415 INSERT INTO c7 VALUES('s', 't', 'u');
1414 } 1416 }
1415 } {} 1417 } {}
1416 1418
1417 proc test_efkey_29 {tn sql isError} { 1419 proc test_efkey_29 {tn sql isError} {
1418 do_test e_fkey-34.$tn "catchsql {$sql}" [ 1420 do_test e_fkey-34.$tn "catchsql {$sql}" [
1419 lindex {{0 {}} {1 {foreign key constraint failed}}} $isError 1421 lindex {{0 {}} {1 {FOREIGN KEY constraint failed}}} $isError
1420 ] 1422 ]
1421 } 1423 }
1422 test_efkey_29 2 "BEGIN" 0 1424 test_efkey_29 2 "BEGIN" 0
1423 test_efkey_29 3 "DELETE FROM parent WHERE x = 'a'" 1 1425 test_efkey_29 3 "DELETE FROM parent WHERE x = 'a'" 1
1424 test_efkey_29 4 "DELETE FROM parent WHERE x = 'd'" 1 1426 test_efkey_29 4 "DELETE FROM parent WHERE x = 'd'" 1
1425 test_efkey_29 5 "DELETE FROM parent WHERE x = 'g'" 1 1427 test_efkey_29 5 "DELETE FROM parent WHERE x = 'g'" 1
1426 test_efkey_29 6 "DELETE FROM parent WHERE x = 'j'" 1 1428 test_efkey_29 6 "DELETE FROM parent WHERE x = 'j'" 1
1427 test_efkey_29 7 "DELETE FROM parent WHERE x = 'm'" 1 1429 test_efkey_29 7 "DELETE FROM parent WHERE x = 'm'" 1
1428 test_efkey_29 8 "DELETE FROM parent WHERE x = 'p'" 1 1430 test_efkey_29 8 "DELETE FROM parent WHERE x = 'p'" 1
1429 test_efkey_29 9 "DELETE FROM parent WHERE x = 's'" 0 1431 test_efkey_29 9 "DELETE FROM parent WHERE x = 's'" 0
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1483 trackartist INTEGER REFERENCES artist(artistid) DEFERRABLE INITIALLY DEFER RED 1485 trackartist INTEGER REFERENCES artist(artistid) DEFERRABLE INITIALLY DEFER RED
1484 ); 1486 );
1485 } 1487 }
1486 } {} 1488 } {}
1487 do_test e_fkey-35.2 { 1489 do_test e_fkey-35.2 {
1488 execsql { 1490 execsql {
1489 BEGIN; 1491 BEGIN;
1490 INSERT INTO track VALUES(1, 'White Christmas', 5); 1492 INSERT INTO track VALUES(1, 'White Christmas', 5);
1491 } 1493 }
1492 catchsql COMMIT 1494 catchsql COMMIT
1493 } {1 {foreign key constraint failed}} 1495 } {1 {FOREIGN KEY constraint failed}}
1494 do_test e_fkey-35.3 { 1496 do_test e_fkey-35.3 {
1495 execsql { 1497 execsql {
1496 INSERT INTO artist VALUES(5, 'Bing Crosby'); 1498 INSERT INTO artist VALUES(5, 'Bing Crosby');
1497 COMMIT; 1499 COMMIT;
1498 } 1500 }
1499 } {} 1501 } {}
1500 1502
1501 #------------------------------------------------------------------------- 1503 #-------------------------------------------------------------------------
1502 # Verify that a nested savepoint may be released without satisfying 1504 # Verify that a nested savepoint may be released without satisfying
1503 # deferred foreign key constraints. 1505 # deferred foreign key constraints.
(...skipping 16 matching lines...) Expand all
1520 do_test e_fkey-36.2 { 1522 do_test e_fkey-36.2 {
1521 execsql { 1523 execsql {
1522 BEGIN; 1524 BEGIN;
1523 SAVEPOINT one; 1525 SAVEPOINT one;
1524 INSERT INTO t1 VALUES(4, 5); 1526 INSERT INTO t1 VALUES(4, 5);
1525 RELEASE one; 1527 RELEASE one;
1526 } 1528 }
1527 } {} 1529 } {}
1528 do_test e_fkey-36.3 { 1530 do_test e_fkey-36.3 {
1529 catchsql COMMIT 1531 catchsql COMMIT
1530 } {1 {foreign key constraint failed}} 1532 } {1 {FOREIGN KEY constraint failed}}
1531 do_test e_fkey-36.4 { 1533 do_test e_fkey-36.4 {
1532 execsql { 1534 execsql {
1533 UPDATE t1 SET a = 5 WHERE a = 4; 1535 UPDATE t1 SET a = 5 WHERE a = 4;
1534 COMMIT; 1536 COMMIT;
1535 } 1537 }
1536 } {} 1538 } {}
1537 1539
1538 1540
1539 #------------------------------------------------------------------------- 1541 #-------------------------------------------------------------------------
1540 # Check that a transaction savepoint (an outermost savepoint opened when 1542 # Check that a transaction savepoint (an outermost savepoint opened when
1541 # the database was in auto-commit mode) cannot be released without 1543 # the database was in auto-commit mode) cannot be released without
1542 # satisfying deferred foreign key constraints. It may be rolled back. 1544 # satisfying deferred foreign key constraints. It may be rolled back.
1543 # 1545 #
1544 # EVIDENCE-OF: R-44295-13823 A transaction savepoint (a non-nested 1546 # EVIDENCE-OF: R-44295-13823 A transaction savepoint (a non-nested
1545 # savepoint that was opened while there was not currently an open 1547 # savepoint that was opened while there was not currently an open
1546 # transaction), on the other hand, is subject to the same restrictions 1548 # transaction), on the other hand, is subject to the same restrictions
1547 # as a COMMIT - attempting to RELEASE it while the database is in such a 1549 # as a COMMIT - attempting to RELEASE it while the database is in such a
1548 # state will fail. 1550 # state will fail.
1549 # 1551 #
1550 do_test e_fkey-37.1 { 1552 do_test e_fkey-37.1 {
1551 execsql { 1553 execsql {
1552 SAVEPOINT one; 1554 SAVEPOINT one;
1553 SAVEPOINT two; 1555 SAVEPOINT two;
1554 INSERT INTO t1 VALUES(6, 7); 1556 INSERT INTO t1 VALUES(6, 7);
1555 RELEASE two; 1557 RELEASE two;
1556 } 1558 }
1557 } {} 1559 } {}
1558 do_test e_fkey-37.2 { 1560 do_test e_fkey-37.2 {
1559 catchsql {RELEASE one} 1561 catchsql {RELEASE one}
1560 } {1 {foreign key constraint failed}} 1562 } {1 {FOREIGN KEY constraint failed}}
1561 do_test e_fkey-37.3 { 1563 do_test e_fkey-37.3 {
1562 execsql { 1564 execsql {
1563 UPDATE t1 SET a = 7 WHERE a = 6; 1565 UPDATE t1 SET a = 7 WHERE a = 6;
1564 RELEASE one; 1566 RELEASE one;
1565 } 1567 }
1566 } {} 1568 } {}
1567 do_test e_fkey-37.4 { 1569 do_test e_fkey-37.4 {
1568 execsql { 1570 execsql {
1569 SAVEPOINT one; 1571 SAVEPOINT one;
1570 SAVEPOINT two; 1572 SAVEPOINT two;
1571 INSERT INTO t1 VALUES(9, 10); 1573 INSERT INTO t1 VALUES(9, 10);
1572 RELEASE two; 1574 RELEASE two;
1573 } 1575 }
1574 } {} 1576 } {}
1575 do_test e_fkey-37.5 { 1577 do_test e_fkey-37.5 {
1576 catchsql {RELEASE one} 1578 catchsql {RELEASE one}
1577 } {1 {foreign key constraint failed}} 1579 } {1 {FOREIGN KEY constraint failed}}
1578 do_test e_fkey-37.6 { 1580 do_test e_fkey-37.6 {
1579 execsql {ROLLBACK TO one ; RELEASE one} 1581 execsql {ROLLBACK TO one ; RELEASE one}
1580 } {} 1582 } {}
1581 1583
1582 #------------------------------------------------------------------------- 1584 #-------------------------------------------------------------------------
1583 # Test that if a COMMIT operation fails due to deferred foreign key 1585 # Test that if a COMMIT operation fails due to deferred foreign key
1584 # constraints, any nested savepoints remain open. 1586 # constraints, any nested savepoints remain open.
1585 # 1587 #
1586 # EVIDENCE-OF: R-37736-42616 If a COMMIT statement (or the RELEASE of a 1588 # EVIDENCE-OF: R-37736-42616 If a COMMIT statement (or the RELEASE of a
1587 # transaction SAVEPOINT) fails because the database is currently in a 1589 # transaction SAVEPOINT) fails because the database is currently in a
(...skipping 10 matching lines...) Expand all
1598 execsql { 1600 execsql {
1599 BEGIN; 1601 BEGIN;
1600 INSERT INTO t1 VALUES(4, 4); 1602 INSERT INTO t1 VALUES(4, 4);
1601 SAVEPOINT one; 1603 SAVEPOINT one;
1602 INSERT INTO t1 VALUES(5, 6); 1604 INSERT INTO t1 VALUES(5, 6);
1603 SELECT * FROM t1; 1605 SELECT * FROM t1;
1604 } 1606 }
1605 } {1 1 2 2 3 3 4 4 5 6} 1607 } {1 1 2 2 3 3 4 4 5 6}
1606 do_test e_fkey-38.3 { 1608 do_test e_fkey-38.3 {
1607 catchsql COMMIT 1609 catchsql COMMIT
1608 } {1 {foreign key constraint failed}} 1610 } {1 {FOREIGN KEY constraint failed}}
1609 do_test e_fkey-38.4 { 1611 do_test e_fkey-38.4 {
1610 execsql { 1612 execsql {
1611 ROLLBACK TO one; 1613 ROLLBACK TO one;
1612 COMMIT; 1614 COMMIT;
1613 SELECT * FROM t1; 1615 SELECT * FROM t1;
1614 } 1616 }
1615 } {1 1 2 2 3 3 4 4} 1617 } {1 1 2 2 3 3 4 4}
1616 1618
1617 do_test e_fkey-38.5 { 1619 do_test e_fkey-38.5 {
1618 execsql { 1620 execsql {
1619 SAVEPOINT a; 1621 SAVEPOINT a;
1620 INSERT INTO t1 VALUES(5, 5); 1622 INSERT INTO t1 VALUES(5, 5);
1621 SAVEPOINT b; 1623 SAVEPOINT b;
1622 INSERT INTO t1 VALUES(6, 7); 1624 INSERT INTO t1 VALUES(6, 7);
1623 SAVEPOINT c; 1625 SAVEPOINT c;
1624 INSERT INTO t1 VALUES(7, 8); 1626 INSERT INTO t1 VALUES(7, 8);
1625 } 1627 }
1626 } {} 1628 } {}
1627 do_test e_fkey-38.6 { 1629 do_test e_fkey-38.6 {
1628 catchsql {RELEASE a} 1630 catchsql {RELEASE a}
1629 } {1 {foreign key constraint failed}} 1631 } {1 {FOREIGN KEY constraint failed}}
1630 do_test e_fkey-38.7 { 1632 do_test e_fkey-38.7 {
1631 execsql {ROLLBACK TO c} 1633 execsql {ROLLBACK TO c}
1632 catchsql {RELEASE a} 1634 catchsql {RELEASE a}
1633 } {1 {foreign key constraint failed}} 1635 } {1 {FOREIGN KEY constraint failed}}
1634 do_test e_fkey-38.8 { 1636 do_test e_fkey-38.8 {
1635 execsql { 1637 execsql {
1636 ROLLBACK TO b; 1638 ROLLBACK TO b;
1637 RELEASE a; 1639 RELEASE a;
1638 SELECT * FROM t1; 1640 SELECT * FROM t1;
1639 } 1641 }
1640 } {1 1 2 2 3 3 4 4 5 5} 1642 } {1 1 2 2 3 3 4 4 5 5}
1641 1643
1642 ########################################################################### 1644 ###########################################################################
1643 ### SECTION 4.3: ON DELETE and ON UPDATE Actions 1645 ### SECTION 4.3: ON DELETE and ON UPDATE Actions
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1774 do_test e_fkey-41.2 { 1776 do_test e_fkey-41.2 {
1775 execsql { 1777 execsql {
1776 BEGIN; 1778 BEGIN;
1777 UPDATE parent SET p1='k' WHERE p1='j'; 1779 UPDATE parent SET p1='k' WHERE p1='j';
1778 DELETE FROM parent WHERE p1='l'; 1780 DELETE FROM parent WHERE p1='l';
1779 SELECT * FROM child; 1781 SELECT * FROM child;
1780 } 1782 }
1781 } {j k l m} 1783 } {j k l m}
1782 do_test e_fkey-41.3 { 1784 do_test e_fkey-41.3 {
1783 catchsql COMMIT 1785 catchsql COMMIT
1784 } {1 {foreign key constraint failed}} 1786 } {1 {FOREIGN KEY constraint failed}}
1785 do_test e_fkey-41.4 { 1787 do_test e_fkey-41.4 {
1786 execsql ROLLBACK 1788 execsql ROLLBACK
1787 } {} 1789 } {}
1788 1790
1789 #------------------------------------------------------------------------- 1791 #-------------------------------------------------------------------------
1790 # Test that "RESTRICT" means the application is prohibited from deleting 1792 # Test that "RESTRICT" means the application is prohibited from deleting
1791 # or updating a parent table row when there exists one or more child keys 1793 # or updating a parent table row when there exists one or more child keys
1792 # mapped to it. 1794 # mapped to it.
1793 # 1795 #
1794 # EVIDENCE-OF: R-04272-38653 The "RESTRICT" action means that the 1796 # EVIDENCE-OF: R-04272-38653 The "RESTRICT" action means that the
(...skipping 17 matching lines...) Expand all
1812 do_test e_fkey-41.2 { 1814 do_test e_fkey-41.2 {
1813 execsql { 1815 execsql {
1814 INSERT INTO parent VALUES('a', 'b'); 1816 INSERT INTO parent VALUES('a', 'b');
1815 INSERT INTO parent VALUES('c', 'd'); 1817 INSERT INTO parent VALUES('c', 'd');
1816 INSERT INTO child1 VALUES('b', 'a'); 1818 INSERT INTO child1 VALUES('b', 'a');
1817 INSERT INTO child2 VALUES('d', 'c'); 1819 INSERT INTO child2 VALUES('d', 'c');
1818 } 1820 }
1819 } {} 1821 } {}
1820 do_test e_fkey-41.3 { 1822 do_test e_fkey-41.3 {
1821 catchsql { DELETE FROM parent WHERE p1 = 'a' } 1823 catchsql { DELETE FROM parent WHERE p1 = 'a' }
1822 } {1 {foreign key constraint failed}} 1824 } {1 {FOREIGN KEY constraint failed}}
1823 do_test e_fkey-41.4 { 1825 do_test e_fkey-41.4 {
1824 catchsql { UPDATE parent SET p2 = 'e' WHERE p1 = 'c' } 1826 catchsql { UPDATE parent SET p2 = 'e' WHERE p1 = 'c' }
1825 } {1 {foreign key constraint failed}} 1827 } {1 {FOREIGN KEY constraint failed}}
1826 1828
1827 #------------------------------------------------------------------------- 1829 #-------------------------------------------------------------------------
1828 # Test that RESTRICT is slightly different from NO ACTION for IMMEDIATE 1830 # Test that RESTRICT is slightly different from NO ACTION for IMMEDIATE
1829 # constraints, in that it is enforced immediately, not at the end of the 1831 # constraints, in that it is enforced immediately, not at the end of the
1830 # statement. 1832 # statement.
1831 # 1833 #
1832 # EVIDENCE-OF: R-37997-42187 The difference between the effect of a 1834 # EVIDENCE-OF: R-37997-42187 The difference between the effect of a
1833 # RESTRICT action and normal foreign key constraint enforcement is that 1835 # RESTRICT action and normal foreign key constraint enforcement is that
1834 # the RESTRICT action processing happens as soon as the field is updated 1836 # the RESTRICT action processing happens as soon as the field is updated
1835 # - not at the end of the current statement as it would with an 1837 # - not at the end of the current statement as it would with an
(...skipping 13 matching lines...) Expand all
1849 INSERT INTO child2 VALUES('key2'); 1851 INSERT INTO child2 VALUES('key2');
1850 1852
1851 CREATE TRIGGER parent_t AFTER UPDATE ON parent BEGIN 1853 CREATE TRIGGER parent_t AFTER UPDATE ON parent BEGIN
1852 UPDATE child1 set c = new.x WHERE c = old.x; 1854 UPDATE child1 set c = new.x WHERE c = old.x;
1853 UPDATE child2 set c = new.x WHERE c = old.x; 1855 UPDATE child2 set c = new.x WHERE c = old.x;
1854 END; 1856 END;
1855 } 1857 }
1856 } {} 1858 } {}
1857 do_test e_fkey-42.2 { 1859 do_test e_fkey-42.2 {
1858 catchsql { UPDATE parent SET x = 'key one' WHERE x = 'key1' } 1860 catchsql { UPDATE parent SET x = 'key one' WHERE x = 'key1' }
1859 } {1 {foreign key constraint failed}} 1861 } {1 {FOREIGN KEY constraint failed}}
1860 do_test e_fkey-42.3 { 1862 do_test e_fkey-42.3 {
1861 execsql { 1863 execsql {
1862 UPDATE parent SET x = 'key two' WHERE x = 'key2'; 1864 UPDATE parent SET x = 'key two' WHERE x = 'key2';
1863 SELECT * FROM child2; 1865 SELECT * FROM child2;
1864 } 1866 }
1865 } {{key two}} 1867 } {{key two}}
1866 1868
1867 drop_all_tables 1869 drop_all_tables
1868 do_test e_fkey-42.4 { 1870 do_test e_fkey-42.4 {
1869 execsql { 1871 execsql {
1870 CREATE TABLE parent(x PRIMARY KEY); 1872 CREATE TABLE parent(x PRIMARY KEY);
1871 CREATE TABLE child1(c REFERENCES parent ON DELETE RESTRICT); 1873 CREATE TABLE child1(c REFERENCES parent ON DELETE RESTRICT);
1872 CREATE TABLE child2(c REFERENCES parent ON DELETE NO ACTION); 1874 CREATE TABLE child2(c REFERENCES parent ON DELETE NO ACTION);
1873 1875
1874 INSERT INTO parent VALUES('key1'); 1876 INSERT INTO parent VALUES('key1');
1875 INSERT INTO parent VALUES('key2'); 1877 INSERT INTO parent VALUES('key2');
1876 INSERT INTO child1 VALUES('key1'); 1878 INSERT INTO child1 VALUES('key1');
1877 INSERT INTO child2 VALUES('key2'); 1879 INSERT INTO child2 VALUES('key2');
1878 1880
1879 CREATE TRIGGER parent_t AFTER DELETE ON parent BEGIN 1881 CREATE TRIGGER parent_t AFTER DELETE ON parent BEGIN
1880 UPDATE child1 SET c = NULL WHERE c = old.x; 1882 UPDATE child1 SET c = NULL WHERE c = old.x;
1881 UPDATE child2 SET c = NULL WHERE c = old.x; 1883 UPDATE child2 SET c = NULL WHERE c = old.x;
1882 END; 1884 END;
1883 } 1885 }
1884 } {} 1886 } {}
1885 do_test e_fkey-42.5 { 1887 do_test e_fkey-42.5 {
1886 catchsql { DELETE FROM parent WHERE x = 'key1' } 1888 catchsql { DELETE FROM parent WHERE x = 'key1' }
1887 } {1 {foreign key constraint failed}} 1889 } {1 {FOREIGN KEY constraint failed}}
1888 do_test e_fkey-42.6 { 1890 do_test e_fkey-42.6 {
1889 execsql { 1891 execsql {
1890 DELETE FROM parent WHERE x = 'key2'; 1892 DELETE FROM parent WHERE x = 'key2';
1891 SELECT * FROM child2; 1893 SELECT * FROM child2;
1892 } 1894 }
1893 } {{}} 1895 } {{}}
1894 1896
1895 drop_all_tables 1897 drop_all_tables
1896 do_test e_fkey-42.7 { 1898 do_test e_fkey-42.7 {
1897 execsql { 1899 execsql {
1898 CREATE TABLE parent(x PRIMARY KEY); 1900 CREATE TABLE parent(x PRIMARY KEY);
1899 CREATE TABLE child1(c REFERENCES parent ON DELETE RESTRICT); 1901 CREATE TABLE child1(c REFERENCES parent ON DELETE RESTRICT);
1900 CREATE TABLE child2(c REFERENCES parent ON DELETE NO ACTION); 1902 CREATE TABLE child2(c REFERENCES parent ON DELETE NO ACTION);
1901 1903
1902 INSERT INTO parent VALUES('key1'); 1904 INSERT INTO parent VALUES('key1');
1903 INSERT INTO parent VALUES('key2'); 1905 INSERT INTO parent VALUES('key2');
1904 INSERT INTO child1 VALUES('key1'); 1906 INSERT INTO child1 VALUES('key1');
1905 INSERT INTO child2 VALUES('key2'); 1907 INSERT INTO child2 VALUES('key2');
1906 } 1908 }
1907 } {} 1909 } {}
1908 do_test e_fkey-42.8 { 1910 do_test e_fkey-42.8 {
1909 catchsql { REPLACE INTO parent VALUES('key1') } 1911 catchsql { REPLACE INTO parent VALUES('key1') }
1910 } {1 {foreign key constraint failed}} 1912 } {1 {FOREIGN KEY constraint failed}}
1911 do_test e_fkey-42.9 { 1913 do_test e_fkey-42.9 {
1912 execsql { 1914 execsql {
1913 REPLACE INTO parent VALUES('key2'); 1915 REPLACE INTO parent VALUES('key2');
1914 SELECT * FROM child2; 1916 SELECT * FROM child2;
1915 } 1917 }
1916 } {key2} 1918 } {key2}
1917 1919
1918 #------------------------------------------------------------------------- 1920 #-------------------------------------------------------------------------
1919 # Test that RESTRICT is enforced immediately, even for a DEFERRED constraint. 1921 # Test that RESTRICT is enforced immediately, even for a DEFERRED constraint.
1920 # 1922 #
(...skipping 15 matching lines...) Expand all
1936 1938
1937 INSERT INTO parent VALUES('key1'); 1939 INSERT INTO parent VALUES('key1');
1938 INSERT INTO parent VALUES('key2'); 1940 INSERT INTO parent VALUES('key2');
1939 INSERT INTO child1 VALUES('key1'); 1941 INSERT INTO child1 VALUES('key1');
1940 INSERT INTO child2 VALUES('key2'); 1942 INSERT INTO child2 VALUES('key2');
1941 BEGIN; 1943 BEGIN;
1942 } 1944 }
1943 } {} 1945 } {}
1944 do_test e_fkey-43.2 { 1946 do_test e_fkey-43.2 {
1945 catchsql { UPDATE parent SET x = 'key one' WHERE x = 'key1' } 1947 catchsql { UPDATE parent SET x = 'key one' WHERE x = 'key1' }
1946 } {1 {foreign key constraint failed}} 1948 } {1 {FOREIGN KEY constraint failed}}
1947 do_test e_fkey-43.3 { 1949 do_test e_fkey-43.3 {
1948 execsql { UPDATE parent SET x = 'key two' WHERE x = 'key2' } 1950 execsql { UPDATE parent SET x = 'key two' WHERE x = 'key2' }
1949 } {} 1951 } {}
1950 do_test e_fkey-43.4 { 1952 do_test e_fkey-43.4 {
1951 catchsql COMMIT 1953 catchsql COMMIT
1952 } {1 {foreign key constraint failed}} 1954 } {1 {FOREIGN KEY constraint failed}}
1953 do_test e_fkey-43.5 { 1955 do_test e_fkey-43.5 {
1954 execsql { 1956 execsql {
1955 UPDATE child2 SET c = 'key two'; 1957 UPDATE child2 SET c = 'key two';
1956 COMMIT; 1958 COMMIT;
1957 } 1959 }
1958 } {} 1960 } {}
1959 1961
1960 drop_all_tables 1962 drop_all_tables
1961 do_test e_fkey-43.6 { 1963 do_test e_fkey-43.6 {
1962 execsql { 1964 execsql {
1963 CREATE TABLE parent(x PRIMARY KEY); 1965 CREATE TABLE parent(x PRIMARY KEY);
1964 CREATE TABLE child1(c REFERENCES parent ON DELETE RESTRICT 1966 CREATE TABLE child1(c REFERENCES parent ON DELETE RESTRICT
1965 DEFERRABLE INITIALLY DEFERRED 1967 DEFERRABLE INITIALLY DEFERRED
1966 ); 1968 );
1967 CREATE TABLE child2(c REFERENCES parent ON DELETE NO ACTION 1969 CREATE TABLE child2(c REFERENCES parent ON DELETE NO ACTION
1968 DEFERRABLE INITIALLY DEFERRED 1970 DEFERRABLE INITIALLY DEFERRED
1969 ); 1971 );
1970 1972
1971 INSERT INTO parent VALUES('key1'); 1973 INSERT INTO parent VALUES('key1');
1972 INSERT INTO parent VALUES('key2'); 1974 INSERT INTO parent VALUES('key2');
1973 INSERT INTO child1 VALUES('key1'); 1975 INSERT INTO child1 VALUES('key1');
1974 INSERT INTO child2 VALUES('key2'); 1976 INSERT INTO child2 VALUES('key2');
1975 BEGIN; 1977 BEGIN;
1976 } 1978 }
1977 } {} 1979 } {}
1978 do_test e_fkey-43.7 { 1980 do_test e_fkey-43.7 {
1979 catchsql { DELETE FROM parent WHERE x = 'key1' } 1981 catchsql { DELETE FROM parent WHERE x = 'key1' }
1980 } {1 {foreign key constraint failed}} 1982 } {1 {FOREIGN KEY constraint failed}}
1981 do_test e_fkey-43.8 { 1983 do_test e_fkey-43.8 {
1982 execsql { DELETE FROM parent WHERE x = 'key2' } 1984 execsql { DELETE FROM parent WHERE x = 'key2' }
1983 } {} 1985 } {}
1984 do_test e_fkey-43.9 { 1986 do_test e_fkey-43.9 {
1985 catchsql COMMIT 1987 catchsql COMMIT
1986 } {1 {foreign key constraint failed}} 1988 } {1 {FOREIGN KEY constraint failed}}
1987 do_test e_fkey-43.10 { 1989 do_test e_fkey-43.10 {
1988 execsql { 1990 execsql {
1989 UPDATE child2 SET c = NULL; 1991 UPDATE child2 SET c = NULL;
1990 COMMIT; 1992 COMMIT;
1991 } 1993 }
1992 } {} 1994 } {}
1993 1995
1994 #------------------------------------------------------------------------- 1996 #-------------------------------------------------------------------------
1995 # Test SET NULL actions. 1997 # Test SET NULL actions.
1996 # 1998 #
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
2053 INSERT INTO pA(rowid, x) VALUES(3, X'ABCD'); 2055 INSERT INTO pA(rowid, x) VALUES(3, X'ABCD');
2054 INSERT INTO pA(rowid, x) VALUES(4, X'1234'); 2056 INSERT INTO pA(rowid, x) VALUES(4, X'1234');
2055 2057
2056 INSERT INTO cA VALUES(X'ABCD'); 2058 INSERT INTO cA VALUES(X'ABCD');
2057 INSERT INTO cB VALUES(X'1234'); 2059 INSERT INTO cB VALUES(X'1234');
2058 } 2060 }
2059 } {} 2061 } {}
2060 do_test e_fkey-45.2 { 2062 do_test e_fkey-45.2 {
2061 execsql { 2063 execsql {
2062 DELETE FROM pA WHERE rowid = 3; 2064 DELETE FROM pA WHERE rowid = 3;
2063 SELECT quote(x) FROM pA; 2065 SELECT quote(x) FROM pA ORDER BY rowid;
2064 } 2066 }
2065 } {X'0000' X'9999' X'1234'} 2067 } {X'0000' X'9999' X'1234'}
2066 do_test e_fkey-45.3 { 2068 do_test e_fkey-45.3 {
2067 execsql { SELECT quote(c) FROM cA } 2069 execsql { SELECT quote(c) FROM cA }
2068 } {X'0000'} 2070 } {X'0000'}
2069 do_test e_fkey-45.4 { 2071 do_test e_fkey-45.4 {
2070 execsql { 2072 execsql {
2071 UPDATE pA SET x = X'8765' WHERE rowid = 4; 2073 UPDATE pA SET x = X'8765' WHERE rowid = 4;
2072 SELECT quote(x) FROM pA; 2074 SELECT quote(x) FROM pA ORDER BY rowid;
2073 } 2075 }
2074 } {X'0000' X'9999' X'8765'} 2076 } {X'0000' X'9999' X'8765'}
2075 do_test e_fkey-45.5 { 2077 do_test e_fkey-45.5 {
2076 execsql { SELECT quote(c) FROM cB } 2078 execsql { SELECT quote(c) FROM cB }
2077 } {X'9999'} 2079 } {X'9999'}
2078 2080
2079 #------------------------------------------------------------------------- 2081 #-------------------------------------------------------------------------
2080 # Test ON DELETE CASCADE actions. 2082 # Test ON DELETE CASCADE actions.
2081 # 2083 #
2082 # EVIDENCE-OF: R-61376-57267 A "CASCADE" action propagates the delete or 2084 # EVIDENCE-OF: R-61376-57267 A "CASCADE" action propagates the delete or
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
2232 } {a two c} 2234 } {a two c}
2233 do_test e_fkey-49.3 { 2235 do_test e_fkey-49.3 {
2234 execsql { 2236 execsql {
2235 ROLLBACK; 2237 ROLLBACK;
2236 DELETE FROM parent WHERE a = 'A'; 2238 DELETE FROM parent WHERE a = 'A';
2237 SELECT * FROM parent; 2239 SELECT * FROM parent;
2238 } 2240 }
2239 } {ONE two three} 2241 } {ONE two three}
2240 do_test e_fkey-49.4 { 2242 do_test e_fkey-49.4 {
2241 catchsql { UPDATE parent SET a = '' WHERE a = 'oNe' } 2243 catchsql { UPDATE parent SET a = '' WHERE a = 'oNe' }
2242 } {1 {foreign key constraint failed}} 2244 } {1 {FOREIGN KEY constraint failed}}
2243 2245
2244 2246
2245 #------------------------------------------------------------------------- 2247 #-------------------------------------------------------------------------
2246 # EVIDENCE-OF: R-11856-19836 2248 # EVIDENCE-OF: R-11856-19836
2247 # 2249 #
2248 # Test an example from the "ON DELETE and ON UPDATE Actions" section 2250 # Test an example from the "ON DELETE and ON UPDATE Actions" section
2249 # of foreignkeys.html. This example shows that adding an "ON DELETE DEFAULT" 2251 # of foreignkeys.html. This example shows that adding an "ON DELETE DEFAULT"
2250 # clause does not abrogate the need to satisfy the foreign key constraint 2252 # clause does not abrogate the need to satisfy the foreign key constraint
2251 # (R-28220-46694). 2253 # (R-28220-46694).
2252 # 2254 #
(...skipping 14 matching lines...) Expand all
2267 trackid INTEGER, 2269 trackid INTEGER,
2268 trackname TEXT, 2270 trackname TEXT,
2269 trackartist INTEGER DEFAULT 0 REFERENCES artist(artistid) ON DELETE SET DE FAULT 2271 trackartist INTEGER DEFAULT 0 REFERENCES artist(artistid) ON DELETE SET DE FAULT
2270 ); 2272 );
2271 INSERT INTO artist VALUES(3, 'Sammy Davis Jr.'); 2273 INSERT INTO artist VALUES(3, 'Sammy Davis Jr.');
2272 INSERT INTO track VALUES(14, 'Mr. Bojangles', 3); 2274 INSERT INTO track VALUES(14, 'Mr. Bojangles', 3);
2273 } 2275 }
2274 } {} 2276 } {}
2275 do_test e_fkey-50.2 { 2277 do_test e_fkey-50.2 {
2276 catchsql { DELETE FROM artist WHERE artistname = 'Sammy Davis Jr.' } 2278 catchsql { DELETE FROM artist WHERE artistname = 'Sammy Davis Jr.' }
2277 } {1 {foreign key constraint failed}} 2279 } {1 {FOREIGN KEY constraint failed}}
2278 do_test e_fkey-50.3 { 2280 do_test e_fkey-50.3 {
2279 execsql { 2281 execsql {
2280 INSERT INTO artist VALUES(0, 'Unknown Artist'); 2282 INSERT INTO artist VALUES(0, 'Unknown Artist');
2281 DELETE FROM artist WHERE artistname = 'Sammy Davis Jr.'; 2283 DELETE FROM artist WHERE artistname = 'Sammy Davis Jr.';
2282 } 2284 }
2283 } {} 2285 } {}
2284 do_test e_fkey-50.4 { 2286 do_test e_fkey-50.4 {
2285 execsql { SELECT * FROM artist } 2287 execsql { SELECT * FROM artist }
2286 } {0 {Unknown Artist}} 2288 } {0 {Unknown Artist}}
2287 do_test e_fkey-50.5 { 2289 do_test e_fkey-50.5 {
(...skipping 30 matching lines...) Expand all
2318 INSERT INTO parent VALUES(new.x+old.x); 2320 INSERT INTO parent VALUES(new.x+old.x);
2319 END; 2321 END;
2320 2322
2321 INSERT INTO parent VALUES(1); 2323 INSERT INTO parent VALUES(1);
2322 INSERT INTO child VALUES(1); 2324 INSERT INTO child VALUES(1);
2323 } 2325 }
2324 } {} 2326 } {}
2325 do_test e_fkey-51.2 { 2327 do_test e_fkey-51.2 {
2326 execsql { 2328 execsql {
2327 UPDATE parent SET x = 22; 2329 UPDATE parent SET x = 22;
2328 SELECT * FROM parent UNION ALL SELECT 'xxx' UNION ALL SELECT a FROM child; 2330 SELECT * FROM parent ORDER BY rowid; SELECT 'xxx' ; SELECT a FROM child;
2329 } 2331 }
2330 } {22 21 23 xxx 22} 2332 } {22 21 23 xxx 22}
2331 do_test e_fkey-51.3 { 2333 do_test e_fkey-51.3 {
2332 execsql { 2334 execsql {
2333 DELETE FROM child; 2335 DELETE FROM child;
2334 DELETE FROM parent; 2336 DELETE FROM parent;
2335 INSERT INTO parent VALUES(-1); 2337 INSERT INTO parent VALUES(-1);
2336 INSERT INTO child VALUES(-1); 2338 INSERT INTO child VALUES(-1);
2337 UPDATE parent SET x = 22; 2339 UPDATE parent SET x = 22;
2338 SELECT * FROM parent UNION ALL SELECT 'xxx' UNION ALL SELECT a FROM child; 2340 SELECT * FROM parent ORDER BY rowid; SELECT 'xxx' ; SELECT a FROM child;
2339 } 2341 }
2340 } {22 23 21 xxx 23} 2342 } {22 23 21 xxx 23}
2341 2343
2342 2344
2343 #------------------------------------------------------------------------- 2345 #-------------------------------------------------------------------------
2344 # Verify that ON UPDATE actions only actually take place if the parent key 2346 # Verify that ON UPDATE actions only actually take place if the parent key
2345 # is set to a new value that is distinct from the old value. The default 2347 # is set to a new value that is distinct from the old value. The default
2346 # collation sequence and affinity are used to determine if the new value 2348 # collation sequence and affinity are used to determine if the new value
2347 # is 'distinct' from the old or not. 2349 # is 'distinct' from the old or not.
2348 # 2350 #
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
2631 # violated, the DROP TABLE statement fails and the table is not dropped. 2633 # violated, the DROP TABLE statement fails and the table is not dropped.
2632 # 2634 #
2633 do_test e_fkey-58.1 { 2635 do_test e_fkey-58.1 {
2634 execsql { 2636 execsql {
2635 DELETE FROM c1; 2637 DELETE FROM c1;
2636 DELETE FROM c2; 2638 DELETE FROM c2;
2637 DELETE FROM c3; 2639 DELETE FROM c3;
2638 } 2640 }
2639 execsql { INSERT INTO c5 VALUES('a', 'b') } 2641 execsql { INSERT INTO c5 VALUES('a', 'b') }
2640 catchsql { DROP TABLE p } 2642 catchsql { DROP TABLE p }
2641 } {1 {foreign key constraint failed}} 2643 } {1 {FOREIGN KEY constraint failed}}
2642 do_test e_fkey-58.2 { 2644 do_test e_fkey-58.2 {
2643 execsql { SELECT * FROM p } 2645 execsql { SELECT * FROM p }
2644 } {a b} 2646 } {a b}
2645 do_test e_fkey-58.3 { 2647 do_test e_fkey-58.3 {
2646 catchsql { 2648 catchsql {
2647 BEGIN; 2649 BEGIN;
2648 DROP TABLE p; 2650 DROP TABLE p;
2649 } 2651 }
2650 } {1 {foreign key constraint failed}} 2652 } {1 {FOREIGN KEY constraint failed}}
2651 do_test e_fkey-58.4 { 2653 do_test e_fkey-58.4 {
2652 execsql { 2654 execsql {
2653 SELECT * FROM p; 2655 SELECT * FROM p;
2654 SELECT * FROM c5; 2656 SELECT * FROM c5;
2655 ROLLBACK; 2657 ROLLBACK;
2656 } 2658 }
2657 } {a b a b} 2659 } {a b a b}
2658 2660
2659 #------------------------------------------------------------------------- 2661 #-------------------------------------------------------------------------
2660 # If a DEFERRED foreign key fails as a result of a DROP TABLE, attempting 2662 # If a DEFERRED foreign key fails as a result of a DROP TABLE, attempting
(...skipping 13 matching lines...) Expand all
2674 } {} 2676 } {}
2675 do_test e_fkey-59.2 { 2677 do_test e_fkey-59.2 {
2676 execsql { INSERT INTO c7 VALUES('a', 'b') } 2678 execsql { INSERT INTO c7 VALUES('a', 'b') }
2677 execsql { 2679 execsql {
2678 BEGIN; 2680 BEGIN;
2679 DROP TABLE p; 2681 DROP TABLE p;
2680 } 2682 }
2681 } {} 2683 } {}
2682 do_test e_fkey-59.3 { 2684 do_test e_fkey-59.3 {
2683 catchsql COMMIT 2685 catchsql COMMIT
2684 } {1 {foreign key constraint failed}} 2686 } {1 {FOREIGN KEY constraint failed}}
2685 do_test e_fkey-59.4 { 2687 do_test e_fkey-59.4 {
2686 execsql { CREATE TABLE p(a, b, PRIMARY KEY(a, b)) } 2688 execsql { CREATE TABLE p(a, b, PRIMARY KEY(a, b)) }
2687 catchsql COMMIT 2689 catchsql COMMIT
2688 } {1 {foreign key constraint failed}} 2690 } {1 {FOREIGN KEY constraint failed}}
2689 do_test e_fkey-59.5 { 2691 do_test e_fkey-59.5 {
2690 execsql { INSERT INTO p VALUES('a', 'b') } 2692 execsql { INSERT INTO p VALUES('a', 'b') }
2691 execsql COMMIT 2693 execsql COMMIT
2692 } {} 2694 } {}
2693 2695
2694 #------------------------------------------------------------------------- 2696 #-------------------------------------------------------------------------
2695 # Any "foreign key mismatch" errors encountered while running an implicit 2697 # Any "foreign key mismatch" errors encountered while running an implicit
2696 # "DELETE FROM tbl" are ignored. 2698 # "DELETE FROM tbl" are ignored.
2697 # 2699 #
2698 # EVIDENCE-OF: R-57242-37005 Any "foreign key mismatch" errors 2700 # EVIDENCE-OF: R-57242-37005 Any "foreign key mismatch" errors
(...skipping 23 matching lines...) Expand all
2722 execsql { 2724 execsql {
2723 BEGIN; 2725 BEGIN;
2724 DROP TABLE p; 2726 DROP TABLE p;
2725 SELECT * FROM c3; 2727 SELECT * FROM c3;
2726 ROLLBACK; 2728 ROLLBACK;
2727 } 2729 }
2728 } {{} 2} 2730 } {{} 2}
2729 do_test e_fkey-60.4 { 2731 do_test e_fkey-60.4 {
2730 execsql { CREATE TABLE nosuchtable(x PRIMARY KEY) } 2732 execsql { CREATE TABLE nosuchtable(x PRIMARY KEY) }
2731 catchsql { DELETE FROM p } 2733 catchsql { DELETE FROM p }
2732 } {1 {foreign key mismatch}} 2734 } {1 {foreign key mismatch - "c2" referencing "p"}}
2733 do_test e_fkey-60.5 { 2735 do_test e_fkey-60.5 {
2734 execsql { DROP TABLE c1 } 2736 execsql { DROP TABLE c1 }
2735 catchsql { DELETE FROM p } 2737 catchsql { DELETE FROM p }
2736 } {1 {foreign key mismatch}} 2738 } {1 {foreign key mismatch - "c2" referencing "p"}}
2737 do_test e_fkey-60.6 { 2739 do_test e_fkey-60.6 {
2738 execsql { DROP TABLE c2 } 2740 execsql { DROP TABLE c2 }
2739 execsql { DELETE FROM p } 2741 execsql { DELETE FROM p }
2740 } {} 2742 } {}
2741 2743
2742 #------------------------------------------------------------------------- 2744 #-------------------------------------------------------------------------
2743 # Test that the special behaviours of ALTER and DROP TABLE are only 2745 # Test that the special behaviors of ALTER and DROP TABLE are only
2744 # activated when foreign keys are enabled. Special behaviours are: 2746 # activated when foreign keys are enabled. Special behaviors are:
2745 # 2747 #
2746 # 1. ADD COLUMN not allowing a REFERENCES clause with a non-NULL 2748 # 1. ADD COLUMN not allowing a REFERENCES clause with a non-NULL
2747 # default value. 2749 # default value.
2748 # 2. Modifying foreign key definitions when a parent table is RENAMEd. 2750 # 2. Modifying foreign key definitions when a parent table is RENAMEd.
2749 # 3. Running an implicit DELETE FROM command as part of DROP TABLE. 2751 # 3. Running an implicit DELETE FROM command as part of DROP TABLE.
2750 # 2752 #
2751 # EVIDENCE-OF: R-54142-41346 The properties of the DROP TABLE and ALTER 2753 # EVIDENCE-OF: R-54142-41346 The properties of the DROP TABLE and ALTER
2752 # TABLE commands described above only apply if foreign keys are enabled. 2754 # TABLE commands described above only apply if foreign keys are enabled.
2753 # 2755 #
2754 do_test e_fkey-61.1.1 { 2756 do_test e_fkey-61.1.1 {
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2829 drop_all_tables 2831 drop_all_tables
2830 do_test e_fkey-62.$zMatch.1 { 2832 do_test e_fkey-62.$zMatch.1 {
2831 execsql " 2833 execsql "
2832 CREATE TABLE p(a, b, c, PRIMARY KEY(b, c)); 2834 CREATE TABLE p(a, b, c, PRIMARY KEY(b, c));
2833 CREATE TABLE c(d, e, f, FOREIGN KEY(e, f) REFERENCES p MATCH $zMatch); 2835 CREATE TABLE c(d, e, f, FOREIGN KEY(e, f) REFERENCES p MATCH $zMatch);
2834 " 2836 "
2835 } {} 2837 } {}
2836 do_test e_fkey-62.$zMatch.2 { 2838 do_test e_fkey-62.$zMatch.2 {
2837 execsql { INSERT INTO p VALUES(1, 2, 3) } 2839 execsql { INSERT INTO p VALUES(1, 2, 3) }
2838 2840
2839 # MATCH SIMPLE behaviour: Allow any child key that contains one or more 2841 # MATCH SIMPLE behavior: Allow any child key that contains one or more
2840 # NULL value to be inserted. Non-NULL values do not have to map to any 2842 # NULL value to be inserted. Non-NULL values do not have to map to any
2841 # parent key values, so long as at least one field of the child key is 2843 # parent key values, so long as at least one field of the child key is
2842 # NULL. 2844 # NULL.
2843 execsql { INSERT INTO c VALUES('w', 2, 3) } 2845 execsql { INSERT INTO c VALUES('w', 2, 3) }
2844 execsql { INSERT INTO c VALUES('x', 'x', NULL) } 2846 execsql { INSERT INTO c VALUES('x', 'x', NULL) }
2845 execsql { INSERT INTO c VALUES('y', NULL, 'x') } 2847 execsql { INSERT INTO c VALUES('y', NULL, 'x') }
2846 execsql { INSERT INTO c VALUES('z', NULL, NULL) } 2848 execsql { INSERT INTO c VALUES('z', NULL, NULL) }
2847 2849
2848 # Check that the FK is enforced properly if there are no NULL values 2850 # Check that the FK is enforced properly if there are no NULL values
2849 # in the child key columns. 2851 # in the child key columns.
2850 catchsql { INSERT INTO c VALUES('a', 2, 4) } 2852 catchsql { INSERT INTO c VALUES('a', 2, 4) }
2851 } {1 {foreign key constraint failed}} 2853 } {1 {FOREIGN KEY constraint failed}}
2852 } 2854 }
2853 2855
2854 #------------------------------------------------------------------------- 2856 #-------------------------------------------------------------------------
2855 # Test that SQLite does not support the SET CONSTRAINT statement. And 2857 # Test that SQLite does not support the SET CONSTRAINT statement. And
2856 # that it is possible to create both immediate and deferred constraints. 2858 # that it is possible to create both immediate and deferred constraints.
2857 # 2859 #
2858 # EVIDENCE-OF: R-21599-16038 In SQLite, a foreign key constraint is 2860 # EVIDENCE-OF: R-21599-16038 In SQLite, a foreign key constraint is
2859 # permanently marked as deferred or immediate when it is created. 2861 # permanently marked as deferred or immediate when it is created.
2860 # 2862 #
2861 drop_all_tables 2863 drop_all_tables
2862 do_test e_fkey-62.1 { 2864 do_test e_fkey-62.1 {
2863 catchsql { SET CONSTRAINTS ALL IMMEDIATE } 2865 catchsql { SET CONSTRAINTS ALL IMMEDIATE }
2864 } {1 {near "SET": syntax error}} 2866 } {1 {near "SET": syntax error}}
2865 do_test e_fkey-62.2 { 2867 do_test e_fkey-62.2 {
2866 catchsql { SET CONSTRAINTS ALL DEFERRED } 2868 catchsql { SET CONSTRAINTS ALL DEFERRED }
2867 } {1 {near "SET": syntax error}} 2869 } {1 {near "SET": syntax error}}
2868 2870
2869 do_test e_fkey-62.3 { 2871 do_test e_fkey-62.3 {
2870 execsql { 2872 execsql {
2871 CREATE TABLE p(a, b, PRIMARY KEY(a, b)); 2873 CREATE TABLE p(a, b, PRIMARY KEY(a, b));
2872 CREATE TABLE cd(c, d, 2874 CREATE TABLE cd(c, d,
2873 FOREIGN KEY(c, d) REFERENCES p DEFERRABLE INITIALLY DEFERRED); 2875 FOREIGN KEY(c, d) REFERENCES p DEFERRABLE INITIALLY DEFERRED);
2874 CREATE TABLE ci(c, d, 2876 CREATE TABLE ci(c, d,
2875 FOREIGN KEY(c, d) REFERENCES p DEFERRABLE INITIALLY IMMEDIATE); 2877 FOREIGN KEY(c, d) REFERENCES p DEFERRABLE INITIALLY IMMEDIATE);
2876 BEGIN; 2878 BEGIN;
2877 } 2879 }
2878 } {} 2880 } {}
2879 do_test e_fkey-62.4 { 2881 do_test e_fkey-62.4 {
2880 catchsql { INSERT INTO ci VALUES('x', 'y') } 2882 catchsql { INSERT INTO ci VALUES('x', 'y') }
2881 } {1 {foreign key constraint failed}} 2883 } {1 {FOREIGN KEY constraint failed}}
2882 do_test e_fkey-62.5 { 2884 do_test e_fkey-62.5 {
2883 catchsql { INSERT INTO cd VALUES('x', 'y') } 2885 catchsql { INSERT INTO cd VALUES('x', 'y') }
2884 } {0 {}} 2886 } {0 {}}
2885 do_test e_fkey-62.6 { 2887 do_test e_fkey-62.6 {
2886 catchsql { COMMIT } 2888 catchsql { COMMIT }
2887 } {1 {foreign key constraint failed}} 2889 } {1 {FOREIGN KEY constraint failed}}
2888 do_test e_fkey-62.7 { 2890 do_test e_fkey-62.7 {
2889 execsql { 2891 execsql {
2890 DELETE FROM cd; 2892 DELETE FROM cd;
2891 COMMIT; 2893 COMMIT;
2892 } 2894 }
2893 } {} 2895 } {}
2894 2896
2895 #------------------------------------------------------------------------- 2897 #-------------------------------------------------------------------------
2896 # Test that the maximum recursion depth of foreign key action programs is 2898 # Test that the maximum recursion depth of foreign key action programs is
2897 # governed by the SQLITE_MAX_TRIGGER_DEPTH and SQLITE_LIMIT_TRIGGER_DEPTH 2899 # governed by the SQLITE_MAX_TRIGGER_DEPTH and SQLITE_LIMIT_TRIGGER_DEPTH
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2938 INSERT INTO t$i VALUES('xxx'); 2940 INSERT INTO t$i VALUES('xxx');
2939 " 2941 "
2940 } 2942 }
2941 execsql COMMIT 2943 execsql COMMIT
2942 catchsql " 2944 catchsql "
2943 UPDATE t0 SET a = 'yyy'; 2945 UPDATE t0 SET a = 'yyy';
2944 SELECT NOT (a='yyy') FROM t$limit; 2946 SELECT NOT (a='yyy') FROM t$limit;
2945 " 2947 "
2946 } 2948 }
2947 2949
2948 do_test e_fkey-63.1.1 { 2950 # If the current build was created using clang with the -fsanitize=address
2949 test_on_delete_recursion $SQLITE_MAX_TRIGGER_DEPTH 2951 # switch, then the library uses considerably more stack space than usual.
2950 } {0 0} 2952 # So much more, that some of the following tests cause stack overflows
2951 do_test e_fkey-63.1.2 { 2953 # if they are run under this configuration.
2952 test_on_delete_recursion [expr $SQLITE_MAX_TRIGGER_DEPTH+1] 2954 #
2953 } {1 {too many levels of trigger recursion}} 2955 if {[clang_sanitize_address]==0} {
2954 do_test e_fkey-63.1.3 { 2956 do_test e_fkey-63.1.1 {
2955 sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 5 2957 test_on_delete_recursion $SQLITE_MAX_TRIGGER_DEPTH
2956 test_on_delete_recursion 5 2958 } {0 0}
2957 } {0 0} 2959 do_test e_fkey-63.1.2 {
2958 do_test e_fkey-63.1.4 { 2960 test_on_delete_recursion [expr $SQLITE_MAX_TRIGGER_DEPTH+1]
2959 test_on_delete_recursion 6 2961 } {1 {too many levels of trigger recursion}}
2960 } {1 {too many levels of trigger recursion}} 2962 do_test e_fkey-63.1.3 {
2961 do_test e_fkey-63.1.5 { 2963 sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 5
2962 sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1000000 2964 test_on_delete_recursion 5
2963 } {5} 2965 } {0 0}
2964 do_test e_fkey-63.2.1 { 2966 do_test e_fkey-63.1.4 {
2965 test_on_update_recursion $SQLITE_MAX_TRIGGER_DEPTH 2967 test_on_delete_recursion 6
2966 } {0 0} 2968 } {1 {too many levels of trigger recursion}}
2967 do_test e_fkey-63.2.2 { 2969 do_test e_fkey-63.1.5 {
2968 test_on_update_recursion [expr $SQLITE_MAX_TRIGGER_DEPTH+1] 2970 sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1000000
2969 } {1 {too many levels of trigger recursion}} 2971 } {5}
2970 do_test e_fkey-63.2.3 { 2972 do_test e_fkey-63.2.1 {
2971 sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 5 2973 test_on_update_recursion $SQLITE_MAX_TRIGGER_DEPTH
2972 test_on_update_recursion 5 2974 } {0 0}
2973 } {0 0} 2975 do_test e_fkey-63.2.2 {
2974 do_test e_fkey-63.2.4 { 2976 test_on_update_recursion [expr $SQLITE_MAX_TRIGGER_DEPTH+1]
2975 test_on_update_recursion 6 2977 } {1 {too many levels of trigger recursion}}
2976 } {1 {too many levels of trigger recursion}} 2978 do_test e_fkey-63.2.3 {
2977 do_test e_fkey-63.2.5 { 2979 sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 5
2978 sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1000000 2980 test_on_update_recursion 5
2979 } {5} 2981 } {0 0}
2982 do_test e_fkey-63.2.4 {
2983 test_on_update_recursion 6
2984 } {1 {too many levels of trigger recursion}}
2985 do_test e_fkey-63.2.5 {
2986 sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1000000
2987 } {5}
2988 }
2980 2989
2981 #------------------------------------------------------------------------- 2990 #-------------------------------------------------------------------------
2982 # The setting of the recursive_triggers pragma does not affect foreign 2991 # The setting of the recursive_triggers pragma does not affect foreign
2983 # key actions. 2992 # key actions.
2984 # 2993 #
2985 # EVIDENCE-OF: R-51769-32730 The PRAGMA recursive_triggers setting does 2994 # EVIDENCE-OF: R-44355-00270 The PRAGMA recursive_triggers setting does
2986 # not not affect the operation of foreign key actions. 2995 # not affect the operation of foreign key actions.
2987 # 2996 #
2988 foreach recursive_triggers_setting [list 0 1 ON OFF] { 2997 foreach recursive_triggers_setting [list 0 1 ON OFF] {
2989 drop_all_tables 2998 drop_all_tables
2990 execsql "PRAGMA recursive_triggers = $recursive_triggers_setting" 2999 execsql "PRAGMA recursive_triggers = $recursive_triggers_setting"
2991 3000
2992 do_test e_fkey-64.$recursive_triggers_setting.1 { 3001 do_test e_fkey-64.$recursive_triggers_setting.1 {
2993 execsql { 3002 execsql {
2994 CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1 ON DELETE CASCADE); 3003 CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1 ON DELETE CASCADE);
2995 INSERT INTO t1 VALUES(1, NULL); 3004 INSERT INTO t1 VALUES(1, NULL);
2996 INSERT INTO t1 VALUES(2, 1); 3005 INSERT INTO t1 VALUES(2, 1);
2997 INSERT INTO t1 VALUES(3, 2); 3006 INSERT INTO t1 VALUES(3, 2);
2998 INSERT INTO t1 VALUES(4, 3); 3007 INSERT INTO t1 VALUES(4, 3);
2999 INSERT INTO t1 VALUES(5, 4); 3008 INSERT INTO t1 VALUES(5, 4);
3000 SELECT count(*) FROM t1; 3009 SELECT count(*) FROM t1;
3001 } 3010 }
3002 } {5} 3011 } {5}
3003 do_test e_fkey-64.$recursive_triggers_setting.2 { 3012 do_test e_fkey-64.$recursive_triggers_setting.2 {
3004 execsql { SELECT count(*) FROM t1 WHERE a = 1 } 3013 execsql { SELECT count(*) FROM t1 WHERE a = 1 }
3005 } {1} 3014 } {1}
3006 do_test e_fkey-64.$recursive_triggers_setting.3 { 3015 do_test e_fkey-64.$recursive_triggers_setting.3 {
3007 execsql { 3016 execsql {
3008 DELETE FROM t1 WHERE a = 1; 3017 DELETE FROM t1 WHERE a = 1;
3009 SELECT count(*) FROM t1; 3018 SELECT count(*) FROM t1;
3010 } 3019 }
3011 } {0} 3020 } {0}
3012 } 3021 }
3013 3022
3014 finish_test 3023 finish_test
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698