OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |