File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sqlite3 / test / e_fkey.test
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 17:04:16 2012 UTC (12 years, 10 months ago) by misho
Branches: sqlite3, MAIN
CVS tags: v3_7_10, HEAD
sqlite3

    1: # 2009 October 7
    2: #
    3: # The author disclaims copyright to this source code.  In place of
    4: # a legal notice, here is a blessing:
    5: #
    6: #    May you do good and not evil.
    7: #    May you find forgiveness for yourself and forgive others.
    8: #    May you share freely, never taking more than you give.
    9: #
   10: #***********************************************************************
   11: #
   12: # This file implements tests to verify the "testable statements" in the
   13: # foreignkeys.in document.
   14: #
   15: # The tests in this file are arranged to mirror the structure of 
   16: # foreignkey.in, with one exception: The statements in section 2, which 
   17: # deals with enabling/disabling foreign key support, is tested first,
   18: # before section 1. This is because some statements in section 2 deal
   19: # with builds that do not include complete foreign key support (because
   20: # either SQLITE_OMIT_TRIGGER or SQLITE_OMIT_FOREIGN_KEY was defined
   21: # at build time).
   22: #
   23: 
   24: set testdir [file dirname $argv0]
   25: source $testdir/tester.tcl
   26: 
   27: proc eqp {sql {db db}} { uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db }
   28: 
   29: ###########################################################################
   30: ### SECTION 2: Enabling Foreign Key Support
   31: ###########################################################################
   32: 
   33: #-------------------------------------------------------------------------
   34: # EVIDENCE-OF: R-33710-56344 In order to use foreign key constraints in
   35: # SQLite, the library must be compiled with neither
   36: # SQLITE_OMIT_FOREIGN_KEY or SQLITE_OMIT_TRIGGER defined.
   37: #
   38: ifcapable trigger&&foreignkey {
   39:   do_test e_fkey-1 {
   40:     execsql {
   41:       PRAGMA foreign_keys = ON;
   42:       CREATE TABLE p(i PRIMARY KEY);
   43:       CREATE TABLE c(j REFERENCES p ON UPDATE CASCADE);
   44:       INSERT INTO p VALUES('hello');
   45:       INSERT INTO c VALUES('hello');
   46:       UPDATE p SET i = 'world';
   47:       SELECT * FROM c;
   48:     }
   49:   } {world}
   50: }
   51: 
   52: #-------------------------------------------------------------------------
   53: # Test the effects of defining OMIT_TRIGGER but not OMIT_FOREIGN_KEY.
   54: #
   55: # EVIDENCE-OF: R-44697-61543 If SQLITE_OMIT_TRIGGER is defined but
   56: # SQLITE_OMIT_FOREIGN_KEY is not, then SQLite behaves as it did prior to
   57: # version 3.6.19 - foreign key definitions are parsed and may be queried
   58: # using PRAGMA foreign_key_list, but foreign key constraints are not
   59: # enforced.
   60: #
   61: # Specifically, test that "PRAGMA foreign_keys" is a no-op in this case.
   62: # When using the pragma to query the current setting, 0 rows are returned.
   63: #
   64: # EVIDENCE-OF: R-22567-44039 The PRAGMA foreign_keys command is a no-op
   65: # in this configuration.
   66: #
   67: # EVIDENCE-OF: R-41784-13339 Tip: If the command "PRAGMA foreign_keys"
   68: # returns no data instead of a single row containing "0" or "1", then
   69: # the version of SQLite you are using does not support foreign keys
   70: # (either because it is older than 3.6.19 or because it was compiled
   71: # with SQLITE_OMIT_FOREIGN_KEY or SQLITE_OMIT_TRIGGER defined).
   72: #
   73: reset_db
   74: ifcapable !trigger&&foreignkey {
   75:   do_test e_fkey-2.1 {
   76:     execsql {
   77:       PRAGMA foreign_keys = ON;
   78:       CREATE TABLE p(i PRIMARY KEY);
   79:       CREATE TABLE c(j REFERENCES p ON UPDATE CASCADE);
   80:       INSERT INTO p VALUES('hello');
   81:       INSERT INTO c VALUES('hello');
   82:       UPDATE p SET i = 'world';
   83:       SELECT * FROM c;
   84:     }
   85:   } {hello}
   86:   do_test e_fkey-2.2 {
   87:     execsql { PRAGMA foreign_key_list(c) }
   88:   } {0 0 p j {} CASCADE {NO ACTION} NONE}
   89:   do_test e_fkey-2.3 {
   90:     execsql { PRAGMA foreign_keys }
   91:   } {}
   92: }
   93: 
   94: 
   95: #-------------------------------------------------------------------------
   96: # Test the effects of defining OMIT_FOREIGN_KEY.
   97: #
   98: # EVIDENCE-OF: R-58428-36660 If OMIT_FOREIGN_KEY is defined, then
   99: # foreign key definitions cannot even be parsed (attempting to specify a
  100: # foreign key definition is a syntax error).
  101: #
  102: # Specifically, test that foreign key constraints cannot even be parsed 
  103: # in such a build.
  104: #
  105: reset_db
  106: ifcapable !foreignkey {
  107:   do_test e_fkey-3.1 {
  108:     execsql { CREATE TABLE p(i PRIMARY KEY) }
  109:     catchsql { CREATE TABLE c(j REFERENCES p ON UPDATE CASCADE) }
  110:   } {1 {near "ON": syntax error}}
  111:   do_test e_fkey-3.2 {
  112:     # This is allowed, as in this build, "REFERENCES" is not a keyword.
  113:     # The declared datatype of column j is "REFERENCES p".
  114:     execsql { CREATE TABLE c(j REFERENCES p) }
  115:   } {}
  116:   do_test e_fkey-3.3 {
  117:     execsql { PRAGMA table_info(c) }
  118:   } {0 j {REFERENCES p} 0 {} 0}
  119:   do_test e_fkey-3.4 {
  120:     execsql { PRAGMA foreign_key_list(c) }
  121:   } {}
  122:   do_test e_fkey-3.5 {
  123:     execsql { PRAGMA foreign_keys }
  124:   } {}
  125: }
  126: 
  127: ifcapable !foreignkey||!trigger { finish_test ; return }
  128: reset_db
  129: 
  130: 
  131: #-------------------------------------------------------------------------
  132: # EVIDENCE-OF: R-07280-60510 Assuming the library is compiled with
  133: # foreign key constraints enabled, it must still be enabled by the
  134: # application at runtime, using the PRAGMA foreign_keys command.
  135: #
  136: # This also tests that foreign key constraints are disabled by default.
  137: #
  138: # EVIDENCE-OF: R-59578-04990 Foreign key constraints are disabled by
  139: # default (for backwards compatibility), so must be enabled separately
  140: # for each database connection separately.
  141: #
  142: drop_all_tables
  143: do_test e_fkey-4.1 {
  144:   execsql {
  145:     CREATE TABLE p(i PRIMARY KEY);
  146:     CREATE TABLE c(j REFERENCES p ON UPDATE CASCADE);
  147:     INSERT INTO p VALUES('hello');
  148:     INSERT INTO c VALUES('hello');
  149:     UPDATE p SET i = 'world';
  150:     SELECT * FROM c;
  151:   } 
  152: } {hello}
  153: do_test e_fkey-4.2 {
  154:   execsql {
  155:     DELETE FROM c;
  156:     DELETE FROM p;
  157:     PRAGMA foreign_keys = ON;
  158:     INSERT INTO p VALUES('hello');
  159:     INSERT INTO c VALUES('hello');
  160:     UPDATE p SET i = 'world';
  161:     SELECT * FROM c;
  162:   } 
  163: } {world}
  164: 
  165: #-------------------------------------------------------------------------
  166: # EVIDENCE-OF: R-15278-54456 The application can can also use a PRAGMA
  167: # foreign_keys statement to determine if foreign keys are currently
  168: # enabled.
  169: #
  170: # This also tests the example code in section 2 of foreignkeys.in.
  171: #
  172: # EVIDENCE-OF: R-11255-19907
  173: # 
  174: reset_db
  175: do_test e_fkey-5.1 {
  176:   execsql { PRAGMA foreign_keys }
  177: } {0}
  178: do_test e_fkey-5.2 {
  179:   execsql { 
  180:     PRAGMA foreign_keys = ON;
  181:     PRAGMA foreign_keys;
  182:   }
  183: } {1}
  184: do_test e_fkey-5.3 {
  185:   execsql { 
  186:     PRAGMA foreign_keys = OFF;
  187:     PRAGMA foreign_keys;
  188:   }
  189: } {0}
  190: 
  191: #-------------------------------------------------------------------------
  192: # Test that it is not possible to enable or disable foreign key support
  193: # while not in auto-commit mode.
  194: #
  195: # EVIDENCE-OF: R-46649-58537 It is not possible to enable or disable
  196: # foreign key constraints in the middle of a multi-statement transaction
  197: # (when SQLite is not in autocommit mode). Attempting to do so does not
  198: # return an error; it simply has no effect.
  199: #
  200: reset_db
  201: do_test e_fkey-6.1 {
  202:   execsql {
  203:     PRAGMA foreign_keys = ON;
  204:     CREATE TABLE t1(a UNIQUE, b);
  205:     CREATE TABLE t2(c, d REFERENCES t1(a));
  206:     INSERT INTO t1 VALUES(1, 2);
  207:     INSERT INTO t2 VALUES(2, 1);
  208:     BEGIN;
  209:       PRAGMA foreign_keys = OFF;
  210:   }
  211:   catchsql {
  212:       DELETE FROM t1
  213:   }
  214: } {1 {foreign key constraint failed}}
  215: do_test e_fkey-6.2 {
  216:   execsql { PRAGMA foreign_keys }
  217: } {1}
  218: do_test e_fkey-6.3 {
  219:   execsql {
  220:     COMMIT;
  221:     PRAGMA foreign_keys = OFF;
  222:     BEGIN;
  223:       PRAGMA foreign_keys = ON;
  224:       DELETE FROM t1;
  225:       PRAGMA foreign_keys;
  226:   }
  227: } {0}
  228: do_test e_fkey-6.4 {
  229:   execsql COMMIT
  230: } {}
  231: 
  232: ###########################################################################
  233: ### SECTION 1: Introduction to Foreign Key Constraints
  234: ###########################################################################
  235: execsql "PRAGMA foreign_keys = ON"
  236: 
  237: #-------------------------------------------------------------------------
  238: # Verify that the syntax in the first example in section 1 is valid.
  239: #
  240: # EVIDENCE-OF: R-04042-24825 To do so, a foreign key definition may be
  241: # added by modifying the declaration of the track table to the
  242: # following: CREATE TABLE track( trackid INTEGER, trackname TEXT,
  243: # trackartist INTEGER, FOREIGN KEY(trackartist) REFERENCES
  244: # artist(artistid) );
  245: #
  246: do_test e_fkey-7.1 {
  247:   execsql {
  248:     CREATE TABLE artist(
  249:       artistid    INTEGER PRIMARY KEY, 
  250:       artistname  TEXT
  251:     );
  252:     CREATE TABLE track(
  253:       trackid     INTEGER, 
  254:       trackname   TEXT, 
  255:       trackartist INTEGER,
  256:       FOREIGN KEY(trackartist) REFERENCES artist(artistid)
  257:     );
  258:   }
  259: } {}
  260: 
  261: #-------------------------------------------------------------------------
  262: # 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: # fail,
  265: #
  266: do_test e_fkey-8.1 {
  267:   catchsql { INSERT INTO track VALUES(1, 'track 1', 1) }
  268: } {1 {foreign key constraint failed}}
  269: do_test e_fkey-8.2 {
  270:   execsql { INSERT INTO artist VALUES(2, 'artist 1') }
  271:   catchsql { INSERT INTO track VALUES(1, 'track 1', 1) }
  272: } {1 {foreign key constraint failed}}
  273: do_test e_fkey-8.2 {
  274:   execsql { INSERT INTO track VALUES(1, 'track 1', 2) }
  275: } {}
  276: 
  277: #-------------------------------------------------------------------------
  278: # Attempting to delete a row from the 'artist' table while there are 
  279: # dependent rows in the track table also fails.
  280: #
  281: # 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: #
  284: do_test e_fkey-9.1 {
  285:   catchsql { DELETE FROM artist WHERE artistid = 2 }
  286: } {1 {foreign key constraint failed}}
  287: do_test e_fkey-9.2 {
  288:   execsql { 
  289:     DELETE FROM track WHERE trackartist = 2;
  290:     DELETE FROM artist WHERE artistid = 2;
  291:   }
  292: } {}
  293: 
  294: #-------------------------------------------------------------------------
  295: # 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: #
  298: # 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: # artist table is required.
  301: #
  302: do_test e_fkey-10.1 {
  303:   execsql {
  304:     INSERT INTO track VALUES(1, 'track 1', NULL);
  305:     INSERT INTO track VALUES(2, 'track 2', NULL);
  306:   }
  307: } {}
  308: do_test e_fkey-10.2 {
  309:   execsql { SELECT * FROM artist }
  310: } {}
  311: do_test e_fkey-10.3 {
  312:   # Setting the trackid to a non-NULL value fails, of course.
  313:   catchsql { UPDATE track SET trackartist = 5 WHERE trackid = 1 }
  314: } {1 {foreign key constraint failed}}
  315: do_test e_fkey-10.4 {
  316:   execsql {
  317:     INSERT INTO artist VALUES(5, 'artist 5');
  318:     UPDATE track SET trackartist = 5 WHERE trackid = 1;
  319:   }
  320:   catchsql { DELETE FROM artist WHERE artistid = 5}
  321: } {1 {foreign key constraint failed}}
  322: do_test e_fkey-10.5 {
  323:   execsql { 
  324:     UPDATE track SET trackartist = NULL WHERE trackid = 1;
  325:     DELETE FROM artist WHERE artistid = 5;
  326:   }
  327: } {}
  328: 
  329: #-------------------------------------------------------------------------
  330: # Test that the following is true fo all rows in the track table:
  331: #
  332: #   trackartist IS NULL OR 
  333: #   EXISTS(SELECT 1 FROM artist WHERE artistid=trackartist)
  334: #
  335: # 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: # trackartist IS NULL OR EXISTS(SELECT 1 FROM artist WHERE
  338: # artistid=trackartist)
  339: 
  340: # This procedure executes a test case to check that statement 
  341: # R-52486-21352 is true after executing the SQL statement passed.
  342: # as the second argument.
  343: proc test_r52486_21352 {tn sql} {
  344:   set res [catchsql $sql]
  345:   set results {
  346:     {0 {}} 
  347:     {1 {PRIMARY KEY must be unique}} 
  348:     {1 {foreign key constraint failed}}
  349:   }
  350:   if {[lsearch $results $res]<0} {
  351:     error $res
  352:   }
  353: 
  354:   do_test e_fkey-11.$tn {
  355:     execsql {
  356:       SELECT count(*) FROM track WHERE NOT (
  357:         trackartist IS NULL OR 
  358:         EXISTS(SELECT 1 FROM artist WHERE artistid=trackartist)
  359:       )
  360:     }
  361:   } {0}
  362: }
  363: 
  364: # Execute a series of random INSERT, UPDATE and DELETE operations
  365: # (some of which may fail due to FK or PK constraint violations) on 
  366: # the two tables in the example schema. Test that R-52486-21352
  367: # is true after executing each operation.
  368: #
  369: set Template {
  370:   {INSERT INTO track VALUES($t, 'track $t', $a)}
  371:   {DELETE FROM track WHERE trackid = $t}
  372:   {UPDATE track SET trackartist = $a WHERE trackid = $t}
  373:   {INSERT INTO artist VALUES($a, 'artist $a')}
  374:   {DELETE FROM artist WHERE artistid = $a}
  375:   {UPDATE artist SET artistid = $a2 WHERE artistid = $a}
  376: }
  377: for {set i 0} {$i < 500} {incr i} {
  378:   set a   [expr int(rand()*10)]
  379:   set a2  [expr int(rand()*10)]
  380:   set t   [expr int(rand()*50)]
  381:   set sql [subst [lindex $Template [expr int(rand()*6)]]]
  382: 
  383:   test_r52486_21352 $i $sql
  384: }
  385: 
  386: #-------------------------------------------------------------------------
  387: # Check that a NOT NULL constraint can be added to the example schema
  388: # to prohibit NULL child keys from being inserted.
  389: #
  390: # EVIDENCE-OF: R-42412-59321 Tip: If the application requires a stricter
  391: # relationship between artist and track, where NULL values are not
  392: # permitted in the trackartist column, simply add the appropriate "NOT
  393: # NULL" constraint to the schema.
  394: #
  395: drop_all_tables
  396: do_test e_fkey-12.1 {
  397:   execsql {
  398:     CREATE TABLE artist(
  399:       artistid    INTEGER PRIMARY KEY, 
  400:       artistname  TEXT
  401:     );
  402:     CREATE TABLE track(
  403:       trackid     INTEGER, 
  404:       trackname   TEXT, 
  405:       trackartist INTEGER NOT NULL,
  406:       FOREIGN KEY(trackartist) REFERENCES artist(artistid)
  407:     );
  408:   }
  409: } {}
  410: do_test e_fkey-12.2 {
  411:   catchsql { INSERT INTO track VALUES(14, 'Mr. Bojangles', NULL) }
  412: } {1 {track.trackartist may not be NULL}}
  413: 
  414: #-------------------------------------------------------------------------
  415: # EVIDENCE-OF: R-16127-35442
  416: #
  417: # Test an example from foreignkeys.html.
  418: #
  419: drop_all_tables
  420: do_test e_fkey-13.1 {
  421:   execsql {
  422:     CREATE TABLE artist(
  423:       artistid    INTEGER PRIMARY KEY, 
  424:       artistname  TEXT
  425:     );
  426:     CREATE TABLE track(
  427:       trackid     INTEGER, 
  428:       trackname   TEXT, 
  429:       trackartist INTEGER,
  430:       FOREIGN KEY(trackartist) REFERENCES artist(artistid)
  431:     );
  432:     INSERT INTO artist VALUES(1, 'Dean Martin');
  433:     INSERT INTO artist VALUES(2, 'Frank Sinatra');
  434:     INSERT INTO track VALUES(11, 'That''s Amore', 1);
  435:     INSERT INTO track VALUES(12, 'Christmas Blues', 1);
  436:     INSERT INTO track VALUES(13, 'My Way', 2);
  437:   }
  438: } {}
  439: do_test e_fkey-13.2 {
  440:   catchsql { INSERT INTO track VALUES(14, 'Mr. Bojangles', 3) }
  441: } {1 {foreign key constraint failed}}
  442: do_test e_fkey-13.3 {
  443:   execsql { INSERT INTO track VALUES(14, 'Mr. Bojangles', NULL) }
  444: } {}
  445: do_test e_fkey-13.4 {
  446:   catchsql { 
  447:     UPDATE track SET trackartist = 3 WHERE trackname = 'Mr. Bojangles';
  448:   }
  449: } {1 {foreign key constraint failed}}
  450: do_test e_fkey-13.5 {
  451:   execsql {
  452:     INSERT INTO artist VALUES(3, 'Sammy Davis Jr.');
  453:     UPDATE track SET trackartist = 3 WHERE trackname = 'Mr. Bojangles';
  454:     INSERT INTO track VALUES(15, 'Boogie Woogie', 3);
  455:   }
  456: } {}
  457: 
  458: #-------------------------------------------------------------------------
  459: # EVIDENCE-OF: R-15958-50233
  460: #
  461: # Test the second example from the first section of foreignkeys.html.
  462: #
  463: do_test e_fkey-14.1 {
  464:   catchsql {
  465:     DELETE FROM artist WHERE artistname = 'Frank Sinatra';
  466:   }
  467: } {1 {foreign key constraint failed}}
  468: do_test e_fkey-14.2 {
  469:   execsql {
  470:     DELETE FROM track WHERE trackname = 'My Way';
  471:     DELETE FROM artist WHERE artistname = 'Frank Sinatra';
  472:   }
  473: } {}
  474: do_test e_fkey-14.3 {
  475:   catchsql {
  476:     UPDATE artist SET artistid=4 WHERE artistname = 'Dean Martin';
  477:   }
  478: } {1 {foreign key constraint failed}}
  479: do_test e_fkey-14.4 {
  480:   execsql {
  481:     DELETE FROM track WHERE trackname IN('That''s Amore', 'Christmas Blues');
  482:     UPDATE artist SET artistid=4 WHERE artistname = 'Dean Martin';
  483:   }
  484: } {}
  485: 
  486: 
  487: #-------------------------------------------------------------------------
  488: # EVIDENCE-OF: R-56032-24923 The foreign key constraint is satisfied if
  489: # for each row in the child table either one or more of the child key
  490: # columns are NULL, or there exists a row in the parent table for which
  491: # each parent key column contains a value equal to the value in its
  492: # associated child key column.
  493: #
  494: # Test also that the usual comparison rules are used when testing if there 
  495: # is a matching row in the parent table of a foreign key constraint.
  496: #
  497: # EVIDENCE-OF: R-57765-12380 In the above paragraph, the term "equal"
  498: # means equal when values are compared using the rules specified here.
  499: #
  500: drop_all_tables
  501: do_test e_fkey-15.1 {
  502:   execsql {
  503:     CREATE TABLE par(p PRIMARY KEY);
  504:     CREATE TABLE chi(c REFERENCES par);
  505: 
  506:     INSERT INTO par VALUES(1);
  507:     INSERT INTO par VALUES('1');
  508:     INSERT INTO par VALUES(X'31');
  509:     SELECT typeof(p) FROM par;
  510:   }
  511: } {integer text blob}
  512: 
  513: proc test_efkey_45 {tn isError sql} {
  514:   do_test e_fkey-15.$tn.1 "
  515:     catchsql {$sql}
  516:   " [lindex {{0 {}} {1 {foreign key constraint failed}}} $isError]
  517: 
  518:   do_test e_fkey-15.$tn.2 {
  519:     execsql {
  520:       SELECT * FROM chi WHERE c IS NOT NULL AND c NOT IN (SELECT p FROM par)
  521:     }
  522:   } {}
  523: }
  524: 
  525: 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 3 0 "INSERT INTO chi VALUES('1')"
  528: test_efkey_45 4 1 "DELETE FROM par WHERE p = '1'"
  529: test_efkey_45 5 0 "DELETE FROM chi WHERE c = '1'"
  530: test_efkey_45 6 0 "DELETE FROM par WHERE p = '1'"
  531: test_efkey_45 7 1 "INSERT INTO chi VALUES('1')"
  532: test_efkey_45 8 0 "INSERT INTO chi VALUES(X'31')"
  533: test_efkey_45 9 1 "INSERT INTO chi VALUES(X'32')"
  534: 
  535: #-------------------------------------------------------------------------
  536: # Specifically, test that when comparing child and parent key values the
  537: # default collation sequence of the parent key column is used.
  538: #
  539: # EVIDENCE-OF: R-15796-47513 When comparing text values, the collating
  540: # sequence associated with the parent key column is always used.
  541: #
  542: drop_all_tables
  543: do_test e_fkey-16.1 {
  544:   execsql {
  545:     CREATE TABLE t1(a COLLATE nocase PRIMARY KEY);
  546:     CREATE TABLE t2(b REFERENCES t1);
  547:   }
  548: } {}
  549: do_test e_fkey-16.2 {
  550:   execsql {
  551:     INSERT INTO t1 VALUES('oNe');
  552:     INSERT INTO t2 VALUES('one');
  553:     INSERT INTO t2 VALUES('ONE');
  554:     UPDATE t2 SET b = 'OnE';
  555:     UPDATE t1 SET a = 'ONE';
  556:   }
  557: } {}
  558: do_test e_fkey-16.3 {
  559:   catchsql { UPDATE t2 SET b = 'two' WHERE rowid = 1 }
  560: } {1 {foreign key constraint failed}}
  561: do_test e_fkey-16.4 {
  562:   catchsql { DELETE FROM t1 WHERE rowid = 1 }
  563: } {1 {foreign key constraint failed}}
  564: 
  565: #-------------------------------------------------------------------------
  566: # 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: # before the comparison takes place.
  569: #
  570: # 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: # value before the comparison is performed.
  573: #
  574: drop_all_tables
  575: do_test e_fkey-17.1 {
  576:   execsql {
  577:     CREATE TABLE t1(a NUMERIC PRIMARY KEY);
  578:     CREATE TABLE t2(b TEXT REFERENCES t1);
  579:   }
  580: } {}
  581: do_test e_fkey-17.2 {
  582:   execsql {
  583:     INSERT INTO t1 VALUES(1);
  584:     INSERT INTO t1 VALUES(2);
  585:     INSERT INTO t1 VALUES('three');
  586:     INSERT INTO t2 VALUES('2.0');
  587:     SELECT b, typeof(b) FROM t2;
  588:   }
  589: } {2.0 text}
  590: do_test e_fkey-17.3 {
  591:   execsql { SELECT typeof(a) FROM t1 }
  592: } {integer integer text}
  593: do_test e_fkey-17.4 {
  594:   catchsql { DELETE FROM t1 WHERE rowid = 2 }
  595: } {1 {foreign key constraint failed}}
  596: 
  597: ###########################################################################
  598: ### SECTION 3: Required and Suggested Database Indexes
  599: ###########################################################################
  600: 
  601: #-------------------------------------------------------------------------
  602: # A parent key must be either a PRIMARY KEY, subject to a UNIQUE 
  603: # constraint, or have a UNIQUE index created on it.
  604: #
  605: # EVIDENCE-OF: R-13435-26311 Usually, the parent key of a foreign key
  606: # constraint is the primary key of the parent table. If they are not the
  607: # primary key, then the parent key columns must be collectively subject
  608: # to a UNIQUE constraint or have a UNIQUE index.
  609: # 
  610: # Also test that if a parent key is not subject to a PRIMARY KEY or UNIQUE
  611: # constraint, but does have a UNIQUE index created on it, then the UNIQUE index
  612: # must use the default collation sequences associated with the parent key
  613: # columns.
  614: #
  615: # EVIDENCE-OF: R-00376-39212 If the parent key columns have a UNIQUE
  616: # index, then that index must use the collation sequences that are
  617: # specified in the CREATE TABLE statement for the parent table.
  618: #
  619: drop_all_tables
  620: do_test e_fkey-18.1 {
  621:   execsql {
  622:     CREATE TABLE t2(a REFERENCES t1(x));
  623:   }
  624: } {}
  625: proc test_efkey_57 {tn isError sql} {
  626:   catchsql { DROP TABLE t1 }
  627:   execsql $sql
  628:   do_test e_fkey-18.$tn {
  629:     catchsql { INSERT INTO t2 VALUES(NULL) }
  630:   } [lindex {{0 {}} {1 {foreign key mismatch}}} $isError]
  631: }
  632: test_efkey_57 2 0 { CREATE TABLE t1(x PRIMARY KEY) }
  633: 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) }
  635: test_efkey_57 5 1 { 
  636:   CREATE TABLE t1(x); 
  637:   CREATE UNIQUE INDEX t1i ON t1(x COLLATE nocase);
  638: }
  639: test_efkey_57 6 1 { CREATE TABLE t1(x) }
  640: test_efkey_57 7 1 { CREATE TABLE t1(x, y, PRIMARY KEY(x, y)) }
  641: test_efkey_57 8 1 { CREATE TABLE t1(x, y, UNIQUE(x, y)) }
  642: test_efkey_57 9 1 { 
  643:   CREATE TABLE t1(x, y); 
  644:   CREATE UNIQUE INDEX t1i ON t1(x, y);
  645: }
  646: 
  647: 
  648: #-------------------------------------------------------------------------
  649: # This block tests an example in foreignkeys.html. Several testable
  650: # statements refer to this example, as follows
  651: #
  652: # EVIDENCE-OF: R-27484-01467
  653: #
  654: # FK Constraints on child1, child2 and child3 are Ok.
  655: #
  656: # Problem with FK on child4:
  657: #
  658: # EVIDENCE-OF: R-51039-44840 The foreign key declared as part of table
  659: # child4 is an error because even though the parent key column is
  660: # indexed, the index is not UNIQUE.
  661: #
  662: # Problem with FK on child5:
  663: #
  664: # EVIDENCE-OF: R-01060-48788 The foreign key for table child5 is an
  665: # error because even though the parent key column has a unique index,
  666: # the index uses a different collating sequence.
  667: #
  668: # Problem with FK on child6 and child7:
  669: #
  670: # EVIDENCE-OF: R-63088-37469 Tables child6 and child7 are incorrect
  671: # because while both have UNIQUE indices on their parent keys, the keys
  672: # are not an exact match to the columns of a single UNIQUE index.
  673: #
  674: drop_all_tables
  675: do_test e_fkey-19.1 {
  676:   execsql {
  677:     CREATE TABLE parent(a PRIMARY KEY, b UNIQUE, c, d, e, f);
  678:     CREATE UNIQUE INDEX i1 ON parent(c, d);
  679:     CREATE INDEX i2 ON parent(e);
  680:     CREATE UNIQUE INDEX i3 ON parent(f COLLATE nocase);
  681: 
  682:     CREATE TABLE child1(f, g REFERENCES parent(a));                       -- Ok
  683:     CREATE TABLE child2(h, i REFERENCES parent(b));                       -- Ok
  684:     CREATE TABLE child3(j, k, FOREIGN KEY(j, k) REFERENCES parent(c, d)); -- Ok
  685:     CREATE TABLE child4(l, m REFERENCES parent(e));                       -- Err
  686:     CREATE TABLE child5(n, o REFERENCES parent(f));                       -- Err
  687:     CREATE TABLE child6(p, q, FOREIGN KEY(p,q) REFERENCES parent(b, c));  -- Err
  688:     CREATE TABLE child7(r REFERENCES parent(c));                          -- Err
  689:   }
  690: } {}
  691: do_test e_fkey-19.2 {
  692:   execsql {
  693:     INSERT INTO parent VALUES(1, 2, 3, 4, 5, 6);
  694:     INSERT INTO child1 VALUES('xxx', 1);
  695:     INSERT INTO child2 VALUES('xxx', 2);
  696:     INSERT INTO child3 VALUES(3, 4);
  697:   }
  698: } {}
  699: do_test e_fkey-19.2 {
  700:   catchsql { INSERT INTO child4 VALUES('xxx', 5) }
  701: } {1 {foreign key mismatch}}
  702: do_test e_fkey-19.3 {
  703:   catchsql { INSERT INTO child5 VALUES('xxx', 6) }
  704: } {1 {foreign key mismatch}}
  705: do_test e_fkey-19.4 {
  706:   catchsql { INSERT INTO child6 VALUES(2, 3) }
  707: } {1 {foreign key mismatch}}
  708: do_test e_fkey-19.5 {
  709:   catchsql { INSERT INTO child7 VALUES(3) }
  710: } {1 {foreign key mismatch}}
  711: 
  712: #-------------------------------------------------------------------------
  713: # Test errors in the database schema that are detected while preparing
  714: # DML statements. The error text for these messages always matches 
  715: # either "foreign key mismatch" or "no such table*" (using [string match]).
  716: #
  717: # EVIDENCE-OF: R-45488-08504 If the database schema contains foreign key
  718: # errors that require looking at more than one table definition to
  719: # identify, then those errors are not detected when the tables are
  720: # created.
  721: #
  722: # EVIDENCE-OF: R-48391-38472 Instead, such errors prevent the
  723: # application from preparing SQL statements that modify the content of
  724: # the child or parent tables in ways that use the foreign keys.
  725: #
  726: # EVIDENCE-OF: R-03108-63659 The English language error message for
  727: # foreign key DML errors is usually "foreign key mismatch" but can also
  728: # be "no such table" if the parent table does not exist.
  729: #
  730: # EVIDENCE-OF: R-60781-26576 Foreign key DML errors are may be reported
  731: # if: The parent table does not exist, or The parent key columns named
  732: # in the foreign key constraint do not exist, or The parent key columns
  733: # named in the foreign key constraint are not the primary key of the
  734: # parent table and are not subject to a unique constraint using
  735: # collating sequence specified in the CREATE TABLE, or The child table
  736: # references the primary key of the parent without specifying the
  737: # primary key columns and the number of primary key columns in the
  738: # parent do not match the number of child key columns.
  739: #
  740: do_test e_fkey-20.1 {
  741:   execsql {
  742:     CREATE TABLE c1(c REFERENCES nosuchtable, d);
  743: 
  744:     CREATE TABLE p2(a, b, UNIQUE(a, b));
  745:     CREATE TABLE c2(c, d, FOREIGN KEY(c, d) REFERENCES p2(a, x));
  746: 
  747:     CREATE TABLE p3(a PRIMARY KEY, b);
  748:     CREATE TABLE c3(c REFERENCES p3(b), d);
  749: 
  750:     CREATE TABLE p4(a PRIMARY KEY, b);
  751:     CREATE UNIQUE INDEX p4i ON p4(b COLLATE nocase);
  752:     CREATE TABLE c4(c REFERENCES p4(b), d);
  753: 
  754:     CREATE TABLE p5(a PRIMARY KEY, b COLLATE nocase);
  755:     CREATE UNIQUE INDEX p5i ON p5(b COLLATE binary);
  756:     CREATE TABLE c5(c REFERENCES p5(b), d);
  757: 
  758:     CREATE TABLE p6(a PRIMARY KEY, b);
  759:     CREATE TABLE c6(c, d, FOREIGN KEY(c, d) REFERENCES p6);
  760: 
  761:     CREATE TABLE p7(a, b, PRIMARY KEY(a, b));
  762:     CREATE TABLE c7(c, d REFERENCES p7);
  763:   }
  764: } {}
  765: 
  766: foreach {tn tbl ptbl err} {
  767:   2 c1 {} "no such table: main.nosuchtable"
  768:   3 c2 p2 "foreign key mismatch"
  769:   4 c3 p3 "foreign key mismatch"
  770:   5 c4 p4 "foreign key mismatch"
  771:   6 c5 p5 "foreign key mismatch"
  772:   7 c6 p6 "foreign key mismatch"
  773:   8 c7 p7 "foreign key mismatch"
  774: } {
  775:   do_test e_fkey-20.$tn.1 {
  776:     catchsql "INSERT INTO $tbl VALUES('a', 'b')"
  777:   } [list 1 $err]
  778:   do_test e_fkey-20.$tn.2 {
  779:     catchsql "UPDATE $tbl SET c = ?, d = ?"
  780:   } [list 1 $err]
  781:   do_test e_fkey-20.$tn.3 {
  782:     catchsql "INSERT INTO $tbl SELECT ?, ?"
  783:   } [list 1 $err]
  784: 
  785:   if {$ptbl ne ""} {
  786:     do_test e_fkey-20.$tn.4 {
  787:       catchsql "DELETE FROM $ptbl"
  788:     } [list 1 $err]
  789:     do_test e_fkey-20.$tn.5 {
  790:       catchsql "UPDATE $ptbl SET a = ?, b = ?"
  791:     } [list 1 $err]
  792:     do_test e_fkey-20.$tn.6 {
  793:       catchsql "INSERT INTO $ptbl SELECT ?, ?"
  794:     } [list 1 $err]
  795:   }
  796: }
  797: 
  798: #-------------------------------------------------------------------------
  799: # EVIDENCE-OF: R-19353-43643
  800: #
  801: # Test the example of foreign key mismatch errors caused by implicitly
  802: # mapping a child key to the primary key of the parent table when the
  803: # child key consists of a different number of columns to that primary key.
  804: # 
  805: drop_all_tables
  806: do_test e_fkey-21.1 {
  807:   execsql {
  808:     CREATE TABLE parent2(a, b, PRIMARY KEY(a,b));
  809: 
  810:     CREATE TABLE child8(x, y, FOREIGN KEY(x,y) REFERENCES parent2);     -- Ok
  811:     CREATE TABLE child9(x REFERENCES parent2);                          -- Err
  812:     CREATE TABLE child10(x,y,z, FOREIGN KEY(x,y,z) REFERENCES parent2); -- Err
  813:   }
  814: } {}
  815: do_test e_fkey-21.2 {
  816:   execsql {
  817:     INSERT INTO parent2 VALUES('I', 'II');
  818:     INSERT INTO child8 VALUES('I', 'II');
  819:   }
  820: } {}
  821: do_test e_fkey-21.3 {
  822:   catchsql { INSERT INTO child9 VALUES('I') }
  823: } {1 {foreign key mismatch}}
  824: do_test e_fkey-21.4 {
  825:   catchsql { INSERT INTO child9 VALUES('II') }
  826: } {1 {foreign key mismatch}}
  827: do_test e_fkey-21.5 {
  828:   catchsql { INSERT INTO child9 VALUES(NULL) }
  829: } {1 {foreign key mismatch}}
  830: do_test e_fkey-21.6 {
  831:   catchsql { INSERT INTO child10 VALUES('I', 'II', 'III') }
  832: } {1 {foreign key mismatch}}
  833: do_test e_fkey-21.7 {
  834:   catchsql { INSERT INTO child10 VALUES(1, 2, 3) }
  835: } {1 {foreign key mismatch}}
  836: do_test e_fkey-21.8 {
  837:   catchsql { INSERT INTO child10 VALUES(NULL, NULL, NULL) }
  838: } {1 {foreign key mismatch}}
  839: 
  840: #-------------------------------------------------------------------------
  841: # Test errors that are reported when creating the child table. 
  842: # Specifically:
  843: #
  844: #   * different number of child and parent key columns, and
  845: #   * child columns that do not exist.
  846: #
  847: # 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
  849: # without having to consult the parent table definition, then the CREATE
  850: # TABLE statement for the child table fails.
  851: #
  852: # These errors are reported whether or not FK support is enabled.
  853: #
  854: # EVIDENCE-OF: R-33883-28833 Foreign key DDL errors are reported
  855: # regardless of whether or not foreign key constraints are enabled when
  856: # the table is created.
  857: #
  858: drop_all_tables
  859: foreach fk [list OFF ON] {
  860:   execsql "PRAGMA foreign_keys = $fk"
  861:   set i 0
  862:   foreach {sql error} {
  863:     "CREATE TABLE child1(a, b, FOREIGN KEY(a, b) REFERENCES p(c))"
  864:       {number of columns in foreign key does not match the number of columns in the referenced table}
  865:     "CREATE TABLE child2(a, b, FOREIGN KEY(a, b) REFERENCES p(c, d, e))"
  866:       {number of columns in foreign key does not match the number of columns in the referenced table}
  867:     "CREATE TABLE child2(a, b, FOREIGN KEY(a, c) REFERENCES p(c, d))"
  868:       {unknown column "c" in foreign key definition}
  869:     "CREATE TABLE child2(a, b, FOREIGN KEY(c, b) REFERENCES p(c, d))"
  870:       {unknown column "c" in foreign key definition}
  871:   } {
  872:     do_test e_fkey-22.$fk.[incr i] {
  873:       catchsql $sql
  874:     } [list 1 $error]
  875:   }
  876: }
  877: 
  878: #-------------------------------------------------------------------------
  879: # Test that a REFERENCING clause that does not specify parent key columns
  880: # implicitly maps to the primary key of the parent table.
  881: #
  882: # EVIDENCE-OF: R-43879-08025 Attaching a "REFERENCES <parent-table>"
  883: # clause to a column definition creates a foreign
  884: # key constraint that maps the column to the primary key of
  885: # <parent-table>.
  886: # 
  887: do_test e_fkey-23.1 {
  888:   execsql {
  889:     CREATE TABLE p1(a, b, PRIMARY KEY(a, b));
  890:     CREATE TABLE p2(a, b PRIMARY KEY);
  891:     CREATE TABLE c1(c, d, FOREIGN KEY(c, d) REFERENCES p1);
  892:     CREATE TABLE c2(a, b REFERENCES p2);
  893:   }
  894: } {}
  895: proc test_efkey_60 {tn isError sql} {
  896:   do_test e_fkey-23.$tn "
  897:     catchsql {$sql}
  898:   " [lindex {{0 {}} {1 {foreign key constraint failed}}} $isError]
  899: }
  900: 
  901: test_efkey_60 2 1 "INSERT INTO c1 VALUES(239, 231)"
  902: test_efkey_60 3 0 "INSERT INTO p1 VALUES(239, 231)"
  903: test_efkey_60 4 0 "INSERT INTO c1 VALUES(239, 231)"
  904: test_efkey_60 5 1 "INSERT INTO c2 VALUES(239, 231)"
  905: test_efkey_60 6 0 "INSERT INTO p2 VALUES(239, 231)"
  906: test_efkey_60 7 0 "INSERT INTO c2 VALUES(239, 231)"
  907: 
  908: #-------------------------------------------------------------------------
  909: # Test that an index on on the child key columns of an FK constraint
  910: # is optional.
  911: #
  912: # EVIDENCE-OF: R-15417-28014 Indices are not required for child key
  913: # columns
  914: #
  915: # Also test that if an index is created on the child key columns, it does
  916: # not make a difference whether or not it is a UNIQUE index.
  917: #
  918: # EVIDENCE-OF: R-15741-50893 The child key index does not have to be
  919: # (and usually will not be) a UNIQUE index.
  920: #
  921: drop_all_tables
  922: do_test e_fkey-24.1 {
  923:   execsql {
  924:     CREATE TABLE parent(x, y, UNIQUE(y, x));
  925:     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));
  927:     CREATE TABLE c3(a, b, FOREIGN KEY(a, b) REFERENCES parent(x, y));
  928:     CREATE INDEX c2i ON c2(a, b);
  929:     CREATE UNIQUE INDEX c3i ON c2(b, a);
  930:   }
  931: } {}
  932: proc test_efkey_61 {tn isError sql} {
  933:   do_test e_fkey-24.$tn "
  934:     catchsql {$sql}
  935:   " [lindex {{0 {}} {1 {foreign key constraint failed}}} $isError]
  936: }
  937: foreach {tn c} [list 2 c1 3 c2 4 c3] {
  938:   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)"
  940:   test_efkey_61 $tn.3 0 "INSERT INTO $c VALUES(1, 2)"
  941: 
  942:   execsql "DELETE FROM $c ; DELETE FROM parent"
  943: }
  944: 
  945: #-------------------------------------------------------------------------
  946: # EVIDENCE-OF: R-00279-52283
  947: #
  948: # Test an example showing that when a row is deleted from the parent 
  949: # table, the child table is queried for orphaned rows as follows:
  950: #
  951: #   SELECT rowid FROM track WHERE trackartist = ?
  952: #
  953: # EVIDENCE-OF: R-23302-30956 If this SELECT returns any rows at all,
  954: # then SQLite concludes that deleting the row from the parent table
  955: # would violate the foreign key constraint and returns an error.
  956: #
  957: do_test e_fkey-25.1 {
  958:   execsql {
  959:     CREATE TABLE artist(
  960:       artistid    INTEGER PRIMARY KEY, 
  961:       artistname  TEXT
  962:     );
  963:     CREATE TABLE track(
  964:       trackid     INTEGER, 
  965:       trackname   TEXT, 
  966:       trackartist INTEGER,
  967:       FOREIGN KEY(trackartist) REFERENCES artist(artistid)
  968:     );
  969:   }
  970: } {}
  971: do_execsql_test e_fkey-25.2 {
  972:   PRAGMA foreign_keys = OFF;
  973:   EXPLAIN QUERY PLAN DELETE FROM artist WHERE 1;
  974:   EXPLAIN QUERY PLAN SELECT rowid FROM track WHERE trackartist = ?;
  975: } {
  976:   0 0 0 {SCAN TABLE artist (~1000000 rows)} 
  977:   0 0 0 {SCAN TABLE track (~100000 rows)}
  978: }
  979: do_execsql_test e_fkey-25.3 {
  980:   PRAGMA foreign_keys = ON;
  981:   EXPLAIN QUERY PLAN DELETE FROM artist WHERE 1;
  982: } {
  983:   0 0 0 {SCAN TABLE artist (~1000000 rows)} 
  984:   0 0 0 {SCAN TABLE track (~100000 rows)}
  985: }
  986: do_test e_fkey-25.4 {
  987:   execsql {
  988:     INSERT INTO artist VALUES(5, 'artist 5');
  989:     INSERT INTO artist VALUES(6, 'artist 6');
  990:     INSERT INTO artist VALUES(7, 'artist 7');
  991:     INSERT INTO track VALUES(1, 'track 1', 5);
  992:     INSERT INTO track VALUES(2, 'track 2', 6);
  993:   }
  994: } {}
  995: 
  996: do_test e_fkey-25.5 {
  997:   concat \
  998:     [execsql { SELECT rowid FROM track WHERE trackartist = 5 }]   \
  999:     [catchsql { DELETE FROM artist WHERE artistid = 5 }]
 1000: } {1 1 {foreign key constraint failed}}
 1001: 
 1002: do_test e_fkey-25.6 {
 1003:   concat \
 1004:     [execsql { SELECT rowid FROM track WHERE trackartist = 7 }]   \
 1005:     [catchsql { DELETE FROM artist WHERE artistid = 7 }]
 1006: } {0 {}}
 1007: 
 1008: do_test e_fkey-25.7 {
 1009:   concat \
 1010:     [execsql { SELECT rowid FROM track WHERE trackartist = 6 }]   \
 1011:     [catchsql { DELETE FROM artist WHERE artistid = 6 }]
 1012: } {2 1 {foreign key constraint failed}}
 1013: 
 1014: #-------------------------------------------------------------------------
 1015: # EVIDENCE-OF: R-47936-10044 Or, more generally:
 1016: # SELECT rowid FROM <child-table> WHERE <child-key> = :parent_key_value
 1017: #
 1018: # 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
 1020: # query is equivalent to:
 1021: #
 1022: #   SELECT rowid FROM <child-table> WHERE <child-key> = :parent_key_value
 1023: #
 1024: # Also test that when a row is inserted into the parent table, or when the 
 1025: # parent key values of an existing row are modified, a query equivalent
 1026: # to the following is planned. In some cases it is not executed, but it
 1027: # is always planned.
 1028: #
 1029: #   SELECT rowid FROM <child-table> WHERE <child-key> = :parent_key_value
 1030: #
 1031: # EVIDENCE-OF: R-61616-46700 Similar queries may be run if the content
 1032: # of the parent key is modified or a new row is inserted into the parent
 1033: # table.
 1034: #
 1035: #
 1036: drop_all_tables
 1037: do_test e_fkey-26.1 {
 1038:   execsql { CREATE TABLE parent(x, y, UNIQUE(y, x)) }
 1039: } {}
 1040: foreach {tn sql} {
 1041:   2 { 
 1042:     CREATE TABLE child(a, b, FOREIGN KEY(a, b) REFERENCES parent(x, y))
 1043:   }
 1044:   3 { 
 1045:     CREATE TABLE child(a, b, FOREIGN KEY(a, b) REFERENCES parent(x, y));
 1046:     CREATE INDEX childi ON child(a, b);
 1047:   }
 1048:   4 { 
 1049:     CREATE TABLE child(a, b, FOREIGN KEY(a, b) REFERENCES parent(x, y));
 1050:     CREATE UNIQUE INDEX childi ON child(b, a);
 1051:   }
 1052: } {
 1053:   execsql $sql
 1054: 
 1055:   execsql {PRAGMA foreign_keys = OFF}
 1056:   set delete [concat \
 1057:       [eqp "DELETE FROM parent WHERE 1"] \
 1058:       [eqp "SELECT rowid FROM child WHERE a = ? AND b = ?"]
 1059:   ]
 1060:   set update [concat \
 1061:       [eqp "UPDATE parent SET x=?, y=?"] \
 1062:       [eqp "SELECT rowid FROM child WHERE a = ? AND b = ?"] \
 1063:       [eqp "SELECT rowid FROM child WHERE a = ? AND b = ?"]
 1064:   ]
 1065:   execsql {PRAGMA foreign_keys = ON}
 1066: 
 1067:   do_test e_fkey-26.$tn.1 { eqp "DELETE FROM parent WHERE 1" } $delete
 1068:   do_test e_fkey-26.$tn.2 { eqp "UPDATE parent set x=?, y=?" } $update
 1069: 
 1070:   execsql {DROP TABLE child}
 1071: }
 1072: 
 1073: #-------------------------------------------------------------------------
 1074: # EVIDENCE-OF: R-14553-34013
 1075: #
 1076: # Test the example schema at the end of section 3. Also test that is
 1077: # is "efficient". In this case "efficient" means that foreign key
 1078: # related operations on the parent table do not provoke linear scans.
 1079: #
 1080: drop_all_tables
 1081: do_test e_fkey-27.1 {
 1082:   execsql {
 1083:     CREATE TABLE artist(
 1084:       artistid    INTEGER PRIMARY KEY, 
 1085:       artistname  TEXT
 1086:     );
 1087:     CREATE TABLE track(
 1088:       trackid     INTEGER,
 1089:       trackname   TEXT, 
 1090:       trackartist INTEGER REFERENCES artist
 1091:     );
 1092:     CREATE INDEX trackindex ON track(trackartist);
 1093:   }
 1094: } {}
 1095: do_test e_fkey-27.2 {
 1096:   eqp { INSERT INTO artist VALUES(?, ?) }
 1097: } {}
 1098: do_execsql_test e_fkey-27.3 {
 1099:   EXPLAIN QUERY PLAN UPDATE artist SET artistid = ?, artistname = ?
 1100: } {
 1101:   0 0 0 {SCAN TABLE artist (~1000000 rows)} 
 1102:   0 0 0 {SEARCH TABLE track USING COVERING INDEX trackindex (trackartist=?) (~10 rows)} 
 1103:   0 0 0 {SEARCH TABLE track USING COVERING INDEX trackindex (trackartist=?) (~10 rows)}
 1104: }
 1105: do_execsql_test e_fkey-27.4 {
 1106:   EXPLAIN QUERY PLAN DELETE FROM artist
 1107: } {
 1108:   0 0 0 {SCAN TABLE artist (~1000000 rows)} 
 1109:   0 0 0 {SEARCH TABLE track USING COVERING INDEX trackindex (trackartist=?) (~10 rows)}
 1110: }
 1111: 
 1112: 
 1113: ###########################################################################
 1114: ### SECTION 4.1: Composite Foreign Key Constraints
 1115: ###########################################################################
 1116: 
 1117: #-------------------------------------------------------------------------
 1118: # Check that parent and child keys must have the same number of columns.
 1119: #
 1120: # EVIDENCE-OF: R-41062-34431 Parent and child keys must have the same
 1121: # cardinality.
 1122: #
 1123: foreach {tn sql err} {
 1124:   1 "CREATE TABLE c(jj REFERENCES p(x, y))" 
 1125:     {foreign key on jj should reference only one column of table p}
 1126: 
 1127:   2 "CREATE TABLE c(jj REFERENCES p())" {near ")": syntax error}
 1128: 
 1129:   3 "CREATE TABLE c(jj, FOREIGN KEY(jj) REFERENCES p(x, y))" 
 1130:     {number of columns in foreign key does not match the number of columns in the referenced table}
 1131: 
 1132:   4 "CREATE TABLE c(jj, FOREIGN KEY(jj) REFERENCES p())" 
 1133:     {near ")": syntax error}
 1134: 
 1135:   5 "CREATE TABLE c(ii, jj, FOREIGN KEY(jj, ii) REFERENCES p())" 
 1136:     {near ")": syntax error}
 1137: 
 1138:   6 "CREATE TABLE c(ii, jj, FOREIGN KEY(jj, ii) REFERENCES p(x))" 
 1139:     {number of columns in foreign key does not match the number of columns in the referenced table}
 1140: 
 1141:   7 "CREATE TABLE c(ii, jj, FOREIGN KEY(jj, ii) REFERENCES p(x,y,z))" 
 1142:     {number of columns in foreign key does not match the number of columns in the referenced table}
 1143: } {
 1144:   drop_all_tables
 1145:   do_test e_fkey-28.$tn [list catchsql $sql] [list 1 $err]
 1146: }
 1147: do_test e_fkey-28.8 {
 1148:   drop_all_tables
 1149:   execsql {
 1150:     CREATE TABLE p(x PRIMARY KEY);
 1151:     CREATE TABLE c(a, b, FOREIGN KEY(a,b) REFERENCES p);
 1152:   }
 1153:   catchsql {DELETE FROM p}
 1154: } {1 {foreign key mismatch}}
 1155: do_test e_fkey-28.9 {
 1156:   drop_all_tables
 1157:   execsql {
 1158:     CREATE TABLE p(x, y, PRIMARY KEY(x,y));
 1159:     CREATE TABLE c(a REFERENCES p);
 1160:   }
 1161:   catchsql {DELETE FROM p}
 1162: } {1 {foreign key mismatch}}
 1163: 
 1164: 
 1165: #-------------------------------------------------------------------------
 1166: # EVIDENCE-OF: R-24676-09859
 1167: #
 1168: # Test the example schema in the "Composite Foreign Key Constraints" 
 1169: # section.
 1170: #
 1171: do_test e_fkey-29.1 {
 1172:   execsql {
 1173:     CREATE TABLE album(
 1174:       albumartist TEXT,
 1175:       albumname TEXT,
 1176:       albumcover BINARY,
 1177:       PRIMARY KEY(albumartist, albumname)
 1178:     );
 1179:     CREATE TABLE song(
 1180:       songid INTEGER,
 1181:       songartist TEXT,
 1182:       songalbum TEXT,
 1183:       songname TEXT,
 1184:       FOREIGN KEY(songartist, songalbum) REFERENCES album(albumartist,albumname)
 1185:     );
 1186:   }
 1187: } {}
 1188: 
 1189: do_test e_fkey-29.2 {
 1190:   execsql {
 1191:     INSERT INTO album VALUES('Elvis Presley', 'Elvis'' Christmas Album', NULL);
 1192:     INSERT INTO song VALUES(
 1193:       1, 'Elvis Presley', 'Elvis'' Christmas Album', 'Here Comes Santa Clause'
 1194:     );
 1195:   }
 1196: } {}
 1197: do_test e_fkey-29.3 {
 1198:   catchsql {
 1199:     INSERT INTO song VALUES(2, 'Elvis Presley', 'Elvis Is Back!', 'Fever');
 1200:   }
 1201: } {1 {foreign key constraint failed}}
 1202: 
 1203: 
 1204: #-------------------------------------------------------------------------
 1205: # 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
 1207: # requirement for a corresponding row in the parent table.
 1208: #
 1209: do_test e_fkey-30.1 {
 1210:   execsql {
 1211:     INSERT INTO song VALUES(2, 'Elvis Presley', NULL, 'Fever');
 1212:     INSERT INTO song VALUES(3, NULL, 'Elvis Is Back', 'Soldier Boy');
 1213:   }
 1214: } {}
 1215: 
 1216: ###########################################################################
 1217: ### SECTION 4.2: Deferred Foreign Key Constraints
 1218: ###########################################################################
 1219: 
 1220: #-------------------------------------------------------------------------
 1221: # Test that if a statement violates an immediate FK constraint, and the
 1222: # database does not satisfy the FK constraint once all effects of the
 1223: # statement have been applied, an error is reported and the effects of
 1224: # the statement rolled back.
 1225: #
 1226: # EVIDENCE-OF: R-09323-30470 If a statement modifies the contents of the
 1227: # database so that an immediate foreign key constraint is in violation
 1228: # at the conclusion the statement, an exception is thrown and the
 1229: # effects of the statement are reverted.
 1230: #
 1231: drop_all_tables
 1232: do_test e_fkey-31.1 {
 1233:   execsql {
 1234:     CREATE TABLE king(a, b, PRIMARY KEY(a));
 1235:     CREATE TABLE prince(c REFERENCES king, d);
 1236:   }
 1237: } {}
 1238: 
 1239: do_test e_fkey-31.2 {
 1240:   # Execute a statement that violates the immediate FK constraint.
 1241:   catchsql { INSERT INTO prince VALUES(1, 2) }
 1242: } {1 {foreign key constraint failed}}
 1243: 
 1244: do_test e_fkey-31.3 {
 1245:   # This time, use a trigger to fix the constraint violation before the
 1246:   # statement has finished executing. Then execute the same statement as
 1247:   # in the previous test case. This time, no error.
 1248:   execsql {
 1249:     CREATE TRIGGER kt AFTER INSERT ON prince WHEN
 1250:       NOT EXISTS (SELECT a FROM king WHERE a = new.c)
 1251:     BEGIN
 1252:       INSERT INTO king VALUES(new.c, NULL);
 1253:     END
 1254:   }
 1255:   execsql { INSERT INTO prince VALUES(1, 2) }
 1256: } {}
 1257: 
 1258: # Test that operating inside a transaction makes no difference to 
 1259: # immediate constraint violation handling.
 1260: do_test e_fkey-31.4 {
 1261:   execsql {
 1262:     BEGIN;
 1263:     INSERT INTO prince VALUES(2, 3);
 1264:     DROP TRIGGER kt;
 1265:   }
 1266:   catchsql { INSERT INTO prince VALUES(3, 4) }
 1267: } {1 {foreign key constraint failed}}
 1268: do_test e_fkey-31.5 {
 1269:   execsql {
 1270:     COMMIT;
 1271:     SELECT * FROM king;
 1272:   }
 1273: } {1 {} 2 {}}
 1274: 
 1275: #-------------------------------------------------------------------------
 1276: # Test that if a deferred constraint is violated within a transaction,
 1277: # nothing happens immediately and the database is allowed to persist
 1278: # in a state that does not satisfy the FK constraint. However attempts
 1279: # to COMMIT the transaction fail until the FK constraint is satisfied.
 1280: #
 1281: # EVIDENCE-OF: R-49178-21358 By contrast, if a statement modifies the
 1282: # contents of the database such that a deferred foreign key constraint
 1283: # is violated, the violation is not reported immediately.
 1284: #
 1285: # EVIDENCE-OF: R-39692-12488 Deferred foreign key constraints are not
 1286: # checked until the transaction tries to COMMIT.
 1287: #
 1288: # 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
 1290: # any number of deferred foreign key constraints.
 1291: #
 1292: # EVIDENCE-OF: R-29604-30395 However, COMMIT will fail as long as
 1293: # foreign key constraints remain in violation.
 1294: #
 1295: proc test_efkey_34 {tn isError sql} {
 1296:   do_test e_fkey-32.$tn "
 1297:     catchsql {$sql}
 1298:   " [lindex {{0 {}} {1 {foreign key constraint failed}}} $isError]
 1299: }
 1300: drop_all_tables
 1301: 
 1302: test_efkey_34  1 0 {
 1303:   CREATE TABLE ll(k PRIMARY KEY);
 1304:   CREATE TABLE kk(c REFERENCES ll DEFERRABLE INITIALLY DEFERRED);
 1305: }
 1306: test_efkey_34  2 0 "BEGIN"
 1307: test_efkey_34  3 0   "INSERT INTO kk VALUES(5)"
 1308: test_efkey_34  4 0   "INSERT INTO kk VALUES(10)"
 1309: test_efkey_34  5 1 "COMMIT"
 1310: test_efkey_34  6 0   "INSERT INTO ll VALUES(10)"
 1311: test_efkey_34  7 1 "COMMIT"
 1312: test_efkey_34  8 0   "INSERT INTO ll VALUES(5)"
 1313: test_efkey_34  9 0 "COMMIT"
 1314: 
 1315: #-------------------------------------------------------------------------
 1316: # When not running inside a transaction, a deferred constraint is similar
 1317: # to an immediate constraint (violations are reported immediately).
 1318: #
 1319: # EVIDENCE-OF: R-56844-61705 If the current statement is not inside an
 1320: # explicit transaction (a BEGIN/COMMIT/ROLLBACK block), then an implicit
 1321: # transaction is committed as soon as the statement has finished
 1322: # executing. In this case deferred constraints behave the same as
 1323: # immediate constraints.
 1324: #
 1325: drop_all_tables
 1326: proc test_efkey_35 {tn isError sql} {
 1327:   do_test e_fkey-33.$tn "
 1328:     catchsql {$sql}
 1329:   " [lindex {{0 {}} {1 {foreign key constraint failed}}} $isError]
 1330: }
 1331: do_test e_fkey-33.1 {
 1332:   execsql {
 1333:     CREATE TABLE parent(x, y);
 1334:     CREATE UNIQUE INDEX pi ON parent(x, y);
 1335:     CREATE TABLE child(a, b,
 1336:       FOREIGN KEY(a, b) REFERENCES parent(x, y) DEFERRABLE INITIALLY DEFERRED
 1337:     );
 1338:   }
 1339: } {}
 1340: test_efkey_35 2 1 "INSERT INTO child  VALUES('x', 'y')"
 1341: test_efkey_35 3 0 "INSERT INTO parent VALUES('x', 'y')"
 1342: test_efkey_35 4 0 "INSERT INTO child  VALUES('x', 'y')"
 1343: 
 1344: 
 1345: #-------------------------------------------------------------------------
 1346: # EVIDENCE-OF: R-12782-61841
 1347: #
 1348: # Test that an FK constraint is made deferred by adding the following
 1349: # to the definition:
 1350: #
 1351: #   DEFERRABLE INITIALLY DEFERRED
 1352: #
 1353: # EVIDENCE-OF: R-09005-28791
 1354: #
 1355: # Also test that adding any of the following to a foreign key definition 
 1356: # makes the constraint IMMEDIATE:
 1357: #
 1358: #   NOT DEFERRABLE INITIALLY DEFERRED
 1359: #   NOT DEFERRABLE INITIALLY IMMEDIATE
 1360: #   NOT DEFERRABLE
 1361: #   DEFERRABLE INITIALLY IMMEDIATE
 1362: #   DEFERRABLE
 1363: #
 1364: # Foreign keys are IMMEDIATE by default (if there is no DEFERRABLE or NOT
 1365: # DEFERRABLE clause).
 1366: #
 1367: # EVIDENCE-OF: R-35290-16460 Foreign key constraints are immediate by
 1368: # default.
 1369: #
 1370: # EVIDENCE-OF: R-30323-21917 Each foreign key constraint in SQLite is
 1371: # classified as either immediate or deferred.
 1372: #
 1373: drop_all_tables
 1374: do_test e_fkey-34.1 {
 1375:   execsql {
 1376:     CREATE TABLE parent(x, y, z, PRIMARY KEY(x,y,z));
 1377:     CREATE TABLE c1(a, b, c,
 1378:       FOREIGN KEY(a, b, c) REFERENCES parent NOT DEFERRABLE INITIALLY DEFERRED
 1379:     );
 1380:     CREATE TABLE c2(a, b, c,
 1381:       FOREIGN KEY(a, b, c) REFERENCES parent NOT DEFERRABLE INITIALLY IMMEDIATE
 1382:     );
 1383:     CREATE TABLE c3(a, b, c,
 1384:       FOREIGN KEY(a, b, c) REFERENCES parent NOT DEFERRABLE
 1385:     );
 1386:     CREATE TABLE c4(a, b, c,
 1387:       FOREIGN KEY(a, b, c) REFERENCES parent DEFERRABLE INITIALLY IMMEDIATE
 1388:     );
 1389:     CREATE TABLE c5(a, b, c,
 1390:       FOREIGN KEY(a, b, c) REFERENCES parent DEFERRABLE
 1391:     );
 1392:     CREATE TABLE c6(a, b, c, FOREIGN KEY(a, b, c) REFERENCES parent);
 1393: 
 1394:     -- This FK constraint is the only deferrable one.
 1395:     CREATE TABLE c7(a, b, c,
 1396:       FOREIGN KEY(a, b, c) REFERENCES parent DEFERRABLE INITIALLY DEFERRED
 1397:     );
 1398: 
 1399:     INSERT INTO parent VALUES('a', 'b', 'c');
 1400:     INSERT INTO parent VALUES('d', 'e', 'f');
 1401:     INSERT INTO parent VALUES('g', 'h', 'i');
 1402:     INSERT INTO parent VALUES('j', 'k', 'l');
 1403:     INSERT INTO parent VALUES('m', 'n', 'o');
 1404:     INSERT INTO parent VALUES('p', 'q', 'r');
 1405:     INSERT INTO parent VALUES('s', 't', 'u');
 1406: 
 1407:     INSERT INTO c1 VALUES('a', 'b', 'c');
 1408:     INSERT INTO c2 VALUES('d', 'e', 'f');
 1409:     INSERT INTO c3 VALUES('g', 'h', 'i');
 1410:     INSERT INTO c4 VALUES('j', 'k', 'l');
 1411:     INSERT INTO c5 VALUES('m', 'n', 'o');
 1412:     INSERT INTO c6 VALUES('p', 'q', 'r');
 1413:     INSERT INTO c7 VALUES('s', 't', 'u');
 1414:   }
 1415: } {}
 1416: 
 1417: proc test_efkey_29 {tn sql isError} {
 1418:   do_test e_fkey-34.$tn "catchsql {$sql}" [
 1419:     lindex {{0 {}} {1 {foreign key constraint failed}}} $isError
 1420:   ]
 1421: }
 1422: test_efkey_29  2 "BEGIN"                                   0
 1423: test_efkey_29  3 "DELETE FROM parent WHERE x = 'a'"        1
 1424: test_efkey_29  4 "DELETE FROM parent WHERE x = 'd'"        1
 1425: test_efkey_29  5 "DELETE FROM parent WHERE x = 'g'"        1
 1426: test_efkey_29  6 "DELETE FROM parent WHERE x = 'j'"        1
 1427: test_efkey_29  7 "DELETE FROM parent WHERE x = 'm'"        1
 1428: test_efkey_29  8 "DELETE FROM parent WHERE x = 'p'"        1
 1429: test_efkey_29  9 "DELETE FROM parent WHERE x = 's'"        0
 1430: test_efkey_29 10 "COMMIT"                                  1
 1431: test_efkey_29 11 "ROLLBACK"                                0
 1432: 
 1433: test_efkey_29  9 "BEGIN"                                   0
 1434: test_efkey_29 10 "UPDATE parent SET z = 'z' WHERE z = 'c'" 1
 1435: test_efkey_29 11 "UPDATE parent SET z = 'z' WHERE z = 'f'" 1
 1436: test_efkey_29 12 "UPDATE parent SET z = 'z' WHERE z = 'i'" 1
 1437: test_efkey_29 13 "UPDATE parent SET z = 'z' WHERE z = 'l'" 1
 1438: test_efkey_29 14 "UPDATE parent SET z = 'z' WHERE z = 'o'" 1
 1439: test_efkey_29 15 "UPDATE parent SET z = 'z' WHERE z = 'r'" 1
 1440: test_efkey_29 16 "UPDATE parent SET z = 'z' WHERE z = 'u'" 0
 1441: test_efkey_29 17 "COMMIT"                                  1
 1442: test_efkey_29 18 "ROLLBACK"                                0
 1443: 
 1444: test_efkey_29 17 "BEGIN"                                   0
 1445: test_efkey_29 18 "INSERT INTO c1 VALUES(1, 2, 3)"          1
 1446: test_efkey_29 19 "INSERT INTO c2 VALUES(1, 2, 3)"          1
 1447: test_efkey_29 20 "INSERT INTO c3 VALUES(1, 2, 3)"          1
 1448: test_efkey_29 21 "INSERT INTO c4 VALUES(1, 2, 3)"          1
 1449: test_efkey_29 22 "INSERT INTO c5 VALUES(1, 2, 3)"          1
 1450: test_efkey_29 22 "INSERT INTO c6 VALUES(1, 2, 3)"          1
 1451: test_efkey_29 22 "INSERT INTO c7 VALUES(1, 2, 3)"          0
 1452: test_efkey_29 23 "COMMIT"                                  1
 1453: test_efkey_29 24 "INSERT INTO parent VALUES(1, 2, 3)"      0
 1454: test_efkey_29 25 "COMMIT"                                  0
 1455: 
 1456: test_efkey_29 26 "BEGIN"                                   0
 1457: test_efkey_29 27 "UPDATE c1 SET a = 10"                    1
 1458: test_efkey_29 28 "UPDATE c2 SET a = 10"                    1
 1459: test_efkey_29 29 "UPDATE c3 SET a = 10"                    1
 1460: test_efkey_29 30 "UPDATE c4 SET a = 10"                    1
 1461: test_efkey_29 31 "UPDATE c5 SET a = 10"                    1
 1462: test_efkey_29 31 "UPDATE c6 SET a = 10"                    1
 1463: test_efkey_29 31 "UPDATE c7 SET a = 10"                    0
 1464: test_efkey_29 32 "COMMIT"                                  1
 1465: test_efkey_29 33 "ROLLBACK"                                0
 1466: 
 1467: #-------------------------------------------------------------------------
 1468: # EVIDENCE-OF: R-24499-57071
 1469: #
 1470: # Test an example from foreignkeys.html dealing with a deferred foreign 
 1471: # key constraint.
 1472: #
 1473: do_test e_fkey-35.1 {
 1474:   drop_all_tables
 1475:   execsql {
 1476:     CREATE TABLE artist(
 1477:       artistid    INTEGER PRIMARY KEY, 
 1478:       artistname  TEXT
 1479:     );
 1480:     CREATE TABLE track(
 1481:       trackid     INTEGER,
 1482:       trackname   TEXT, 
 1483:       trackartist INTEGER REFERENCES artist(artistid) DEFERRABLE INITIALLY DEFERRED
 1484:     );
 1485:   }
 1486: } {}
 1487: do_test e_fkey-35.2 {
 1488:   execsql {
 1489:     BEGIN;
 1490:       INSERT INTO track VALUES(1, 'White Christmas', 5);
 1491:   }
 1492:   catchsql COMMIT
 1493: } {1 {foreign key constraint failed}}
 1494: do_test e_fkey-35.3 {
 1495:   execsql {
 1496:     INSERT INTO artist VALUES(5, 'Bing Crosby');
 1497:     COMMIT;
 1498:   }
 1499: } {}
 1500: 
 1501: #-------------------------------------------------------------------------
 1502: # Verify that a nested savepoint may be released without satisfying 
 1503: # deferred foreign key constraints.
 1504: #
 1505: # EVIDENCE-OF: R-07223-48323 A nested savepoint transaction may be
 1506: # RELEASEd while the database is in a state that does not satisfy a
 1507: # deferred foreign key constraint.
 1508: #
 1509: drop_all_tables
 1510: do_test e_fkey-36.1 {
 1511:   execsql {
 1512:     CREATE TABLE t1(a PRIMARY KEY,
 1513:       b REFERENCES t1 DEFERRABLE INITIALLY DEFERRED
 1514:     );
 1515:     INSERT INTO t1 VALUES(1, 1);
 1516:     INSERT INTO t1 VALUES(2, 2);
 1517:     INSERT INTO t1 VALUES(3, 3);
 1518:   }
 1519: } {}
 1520: do_test e_fkey-36.2 {
 1521:   execsql {
 1522:     BEGIN;
 1523:       SAVEPOINT one;
 1524:         INSERT INTO t1 VALUES(4, 5);
 1525:       RELEASE one;
 1526:   }
 1527: } {}
 1528: do_test e_fkey-36.3 {
 1529:   catchsql COMMIT
 1530: } {1 {foreign key constraint failed}}
 1531: do_test e_fkey-36.4 {
 1532:   execsql {
 1533:     UPDATE t1 SET a = 5 WHERE a = 4;
 1534:     COMMIT;
 1535:   }
 1536: } {}
 1537: 
 1538: 
 1539: #-------------------------------------------------------------------------
 1540: # Check that a transaction savepoint (an outermost savepoint opened when
 1541: # the database was in auto-commit mode) cannot be released without
 1542: # satisfying deferred foreign key constraints. It may be rolled back.
 1543: #
 1544: # EVIDENCE-OF: R-44295-13823 A transaction savepoint (a non-nested
 1545: # savepoint that was opened while there was not currently an open
 1546: # 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
 1548: # state will fail.
 1549: #
 1550: do_test e_fkey-37.1 {
 1551:   execsql {
 1552:     SAVEPOINT one;
 1553:       SAVEPOINT two;
 1554:         INSERT INTO t1 VALUES(6, 7);
 1555:       RELEASE two;
 1556:   }
 1557: } {}
 1558: do_test e_fkey-37.2 {
 1559:   catchsql {RELEASE one}
 1560: } {1 {foreign key constraint failed}}
 1561: do_test e_fkey-37.3 {
 1562:   execsql {
 1563:       UPDATE t1 SET a = 7 WHERE a = 6;
 1564:     RELEASE one;
 1565:   }
 1566: } {}
 1567: do_test e_fkey-37.4 {
 1568:   execsql {
 1569:     SAVEPOINT one;
 1570:       SAVEPOINT two;
 1571:         INSERT INTO t1 VALUES(9, 10);
 1572:       RELEASE two;
 1573:   }
 1574: } {}
 1575: do_test e_fkey-37.5 {
 1576:   catchsql {RELEASE one}
 1577: } {1 {foreign key constraint failed}}
 1578: do_test e_fkey-37.6 {
 1579:   execsql {ROLLBACK TO one ; RELEASE one}
 1580: } {}
 1581: 
 1582: #-------------------------------------------------------------------------
 1583: # Test that if a COMMIT operation fails due to deferred foreign key 
 1584: # constraints, any nested savepoints remain open.
 1585: #
 1586: # 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
 1588: # state that violates a deferred foreign key constraint and there are
 1589: # currently nested savepoints, the nested savepoints remain open.
 1590: #
 1591: do_test e_fkey-38.1 {
 1592:   execsql {
 1593:     DELETE FROM t1 WHERE a>3;
 1594:     SELECT * FROM t1;
 1595:   }
 1596: } {1 1 2 2 3 3}
 1597: do_test e_fkey-38.2 {
 1598:   execsql {
 1599:     BEGIN;
 1600:       INSERT INTO t1 VALUES(4, 4);
 1601:       SAVEPOINT one;
 1602:         INSERT INTO t1 VALUES(5, 6);
 1603:         SELECT * FROM t1;
 1604:   }
 1605: } {1 1 2 2 3 3 4 4 5 6}
 1606: do_test e_fkey-38.3 {
 1607:   catchsql COMMIT
 1608: } {1 {foreign key constraint failed}}
 1609: do_test e_fkey-38.4 {
 1610:   execsql {
 1611:     ROLLBACK TO one;
 1612:     COMMIT;
 1613:     SELECT * FROM t1;
 1614:   }
 1615: } {1 1 2 2 3 3 4 4}
 1616: 
 1617: do_test e_fkey-38.5 {
 1618:   execsql {
 1619:     SAVEPOINT a;
 1620:       INSERT INTO t1 VALUES(5, 5);
 1621:       SAVEPOINT b;
 1622:         INSERT INTO t1 VALUES(6, 7);
 1623:         SAVEPOINT c;
 1624:           INSERT INTO t1 VALUES(7, 8);
 1625:   }
 1626: } {}
 1627: do_test e_fkey-38.6 {
 1628:   catchsql {RELEASE a}
 1629: } {1 {foreign key constraint failed}}
 1630: do_test e_fkey-38.7 {
 1631:   execsql  {ROLLBACK TO c}
 1632:   catchsql {RELEASE a}
 1633: } {1 {foreign key constraint failed}}
 1634: do_test e_fkey-38.8 {
 1635:   execsql  {
 1636:     ROLLBACK TO b;
 1637:     RELEASE a;
 1638:     SELECT * FROM t1;
 1639:   }
 1640: } {1 1 2 2 3 3 4 4 5 5}
 1641: 
 1642: ###########################################################################
 1643: ### SECTION 4.3: ON DELETE and ON UPDATE Actions
 1644: ###########################################################################
 1645: 
 1646: #-------------------------------------------------------------------------
 1647: # Test that configured ON DELETE and ON UPDATE actions take place when
 1648: # deleting or modifying rows of the parent table, respectively.
 1649: #
 1650: # EVIDENCE-OF: R-48270-44282 Foreign key ON DELETE and ON UPDATE clauses
 1651: # are used to configure actions that take place when deleting rows from
 1652: # the parent table (ON DELETE), or modifying the parent key values of
 1653: # existing rows (ON UPDATE).
 1654: #
 1655: # Test that a single FK constraint may have different actions configured
 1656: # for ON DELETE and ON UPDATE.
 1657: #
 1658: # EVIDENCE-OF: R-48124-63225 A single foreign key constraint may have
 1659: # different actions configured for ON DELETE and ON UPDATE.
 1660: #
 1661: do_test e_fkey-39.1 {
 1662:   execsql {
 1663:     CREATE TABLE p(a, b PRIMARY KEY, c);
 1664:     CREATE TABLE c1(d, e, f DEFAULT 'k0' REFERENCES p 
 1665:       ON UPDATE SET DEFAULT
 1666:       ON DELETE SET NULL
 1667:     );
 1668: 
 1669:     INSERT INTO p VALUES(0, 'k0', '');
 1670:     INSERT INTO p VALUES(1, 'k1', 'I');
 1671:     INSERT INTO p VALUES(2, 'k2', 'II');
 1672:     INSERT INTO p VALUES(3, 'k3', 'III');
 1673: 
 1674:     INSERT INTO c1 VALUES(1, 'xx', 'k1');
 1675:     INSERT INTO c1 VALUES(2, 'xx', 'k2');
 1676:     INSERT INTO c1 VALUES(3, 'xx', 'k3');
 1677:   }
 1678: } {}
 1679: do_test e_fkey-39.2 {
 1680:   execsql {
 1681:     UPDATE p SET b = 'k4' WHERE a = 1;
 1682:     SELECT * FROM c1;
 1683:   }
 1684: } {1 xx k0 2 xx k2 3 xx k3}
 1685: do_test e_fkey-39.3 {
 1686:   execsql {
 1687:     DELETE FROM p WHERE a = 2;
 1688:     SELECT * FROM c1;
 1689:   }
 1690: } {1 xx k0 2 xx {} 3 xx k3}
 1691: do_test e_fkey-39.4 {
 1692:   execsql {
 1693:     CREATE UNIQUE INDEX pi ON p(c);
 1694:     REPLACE INTO p VALUES(5, 'k5', 'III');
 1695:     SELECT * FROM c1;
 1696:   }
 1697: } {1 xx k0 2 xx {} 3 xx {}}
 1698: 
 1699: #-------------------------------------------------------------------------
 1700: # Each foreign key in the system has an ON UPDATE and ON DELETE action,
 1701: # either "NO ACTION", "RESTRICT", "SET NULL", "SET DEFAULT" or "CASCADE".
 1702: #
 1703: # EVIDENCE-OF: R-33326-45252 The ON DELETE and ON UPDATE action
 1704: # associated with each foreign key in an SQLite database is one of "NO
 1705: # ACTION", "RESTRICT", "SET NULL", "SET DEFAULT" or "CASCADE".
 1706: #
 1707: # If none is specified explicitly, "NO ACTION" is the default.
 1708: #
 1709: # EVIDENCE-OF: R-19803-45884 If an action is not explicitly specified,
 1710: # it defaults to "NO ACTION".
 1711: # 
 1712: drop_all_tables
 1713: do_test e_fkey-40.1 {
 1714:   execsql {
 1715:     CREATE TABLE parent(x PRIMARY KEY, y);
 1716:     CREATE TABLE child1(a, 
 1717:       b REFERENCES parent ON UPDATE NO ACTION ON DELETE RESTRICT
 1718:     );
 1719:     CREATE TABLE child2(a, 
 1720:       b REFERENCES parent ON UPDATE RESTRICT ON DELETE SET NULL
 1721:     );
 1722:     CREATE TABLE child3(a, 
 1723:       b REFERENCES parent ON UPDATE SET NULL ON DELETE SET DEFAULT
 1724:     );
 1725:     CREATE TABLE child4(a, 
 1726:       b REFERENCES parent ON UPDATE SET DEFAULT ON DELETE CASCADE
 1727:     );
 1728: 
 1729:     -- Create some foreign keys that use the default action - "NO ACTION"
 1730:     CREATE TABLE child5(a, b REFERENCES parent ON UPDATE CASCADE);
 1731:     CREATE TABLE child6(a, b REFERENCES parent ON DELETE RESTRICT);
 1732:     CREATE TABLE child7(a, b REFERENCES parent ON DELETE NO ACTION);
 1733:     CREATE TABLE child8(a, b REFERENCES parent ON UPDATE NO ACTION);
 1734:   }
 1735: } {}
 1736: 
 1737: foreach {tn zTab lRes} {
 1738:   2 child1 {0 0 parent b {} {NO ACTION} RESTRICT NONE}
 1739:   3 child2 {0 0 parent b {} RESTRICT {SET NULL} NONE}
 1740:   4 child3 {0 0 parent b {} {SET NULL} {SET DEFAULT} NONE}
 1741:   5 child4 {0 0 parent b {} {SET DEFAULT} CASCADE NONE}
 1742:   6 child5 {0 0 parent b {} CASCADE {NO ACTION} NONE}
 1743:   7 child6 {0 0 parent b {} {NO ACTION} RESTRICT NONE}
 1744:   8 child7 {0 0 parent b {} {NO ACTION} {NO ACTION} NONE}
 1745:   9 child8 {0 0 parent b {} {NO ACTION} {NO ACTION} NONE}
 1746: } {
 1747:   do_test e_fkey-40.$tn { execsql "PRAGMA foreign_key_list($zTab)" } $lRes
 1748: }
 1749: 
 1750: #-------------------------------------------------------------------------
 1751: # Test that "NO ACTION" means that nothing happens to a child row when
 1752: # it's parent row is updated or deleted.
 1753: #
 1754: # EVIDENCE-OF: R-19971-54976 Configuring "NO ACTION" means just that:
 1755: # when a parent key is modified or deleted from the database, no special
 1756: # action is taken.
 1757: #
 1758: drop_all_tables
 1759: do_test e_fkey-41.1 {
 1760:   execsql {
 1761:     CREATE TABLE parent(p1, p2, PRIMARY KEY(p1, p2));
 1762:     CREATE TABLE child(c1, c2, 
 1763:       FOREIGN KEY(c1, c2) REFERENCES parent
 1764:       ON UPDATE NO ACTION
 1765:       ON DELETE NO ACTION
 1766:       DEFERRABLE INITIALLY DEFERRED
 1767:     );
 1768:     INSERT INTO parent VALUES('j', 'k');
 1769:     INSERT INTO parent VALUES('l', 'm');
 1770:     INSERT INTO child VALUES('j', 'k');
 1771:     INSERT INTO child VALUES('l', 'm');
 1772:   }
 1773: } {}
 1774: do_test e_fkey-41.2 {
 1775:   execsql {
 1776:     BEGIN;
 1777:       UPDATE parent SET p1='k' WHERE p1='j';
 1778:       DELETE FROM parent WHERE p1='l';
 1779:       SELECT * FROM child;
 1780:   }
 1781: } {j k l m}
 1782: do_test e_fkey-41.3 {
 1783:   catchsql COMMIT
 1784: } {1 {foreign key constraint failed}}
 1785: do_test e_fkey-41.4 {
 1786:   execsql ROLLBACK
 1787: } {}
 1788: 
 1789: #-------------------------------------------------------------------------
 1790: # 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
 1792: # mapped to it.
 1793: #
 1794: # EVIDENCE-OF: R-04272-38653 The "RESTRICT" action means that the
 1795: # application is prohibited from deleting (for ON DELETE RESTRICT) or
 1796: # modifying (for ON UPDATE RESTRICT) a parent key when there exists one
 1797: # or more child keys mapped to it.
 1798: #
 1799: drop_all_tables
 1800: do_test e_fkey-41.1 {
 1801:   execsql {
 1802:     CREATE TABLE parent(p1, p2);
 1803:     CREATE UNIQUE INDEX parent_i ON parent(p1, p2);
 1804:     CREATE TABLE child1(c1, c2, 
 1805:       FOREIGN KEY(c2, c1) REFERENCES parent(p1, p2) ON DELETE RESTRICT
 1806:     );
 1807:     CREATE TABLE child2(c1, c2, 
 1808:       FOREIGN KEY(c2, c1) REFERENCES parent(p1, p2) ON UPDATE RESTRICT
 1809:     );
 1810:   }
 1811: } {}
 1812: do_test e_fkey-41.2 {
 1813:   execsql {
 1814:     INSERT INTO parent VALUES('a', 'b');
 1815:     INSERT INTO parent VALUES('c', 'd');
 1816:     INSERT INTO child1 VALUES('b', 'a');
 1817:     INSERT INTO child2 VALUES('d', 'c');
 1818:   }
 1819: } {}
 1820: do_test e_fkey-41.3 {
 1821:   catchsql { DELETE FROM parent WHERE p1 = 'a' }
 1822: } {1 {foreign key constraint failed}}
 1823: do_test e_fkey-41.4 {
 1824:   catchsql { UPDATE parent SET p2 = 'e' WHERE p1 = 'c' }
 1825: } {1 {foreign key constraint failed}}
 1826: 
 1827: #-------------------------------------------------------------------------
 1828: # 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 
 1830: # statement.
 1831: #
 1832: # EVIDENCE-OF: R-37997-42187 The difference between the effect of a
 1833: # RESTRICT action and normal foreign key constraint enforcement is that
 1834: # 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
 1836: # immediate constraint, or at the end of the current transaction as it
 1837: # would with a deferred constraint.
 1838: #
 1839: drop_all_tables
 1840: do_test e_fkey-42.1 {
 1841:   execsql {
 1842:     CREATE TABLE parent(x PRIMARY KEY);
 1843:     CREATE TABLE child1(c REFERENCES parent ON UPDATE RESTRICT);
 1844:     CREATE TABLE child2(c REFERENCES parent ON UPDATE NO ACTION);
 1845: 
 1846:     INSERT INTO parent VALUES('key1');
 1847:     INSERT INTO parent VALUES('key2');
 1848:     INSERT INTO child1 VALUES('key1');
 1849:     INSERT INTO child2 VALUES('key2');
 1850: 
 1851:     CREATE TRIGGER parent_t AFTER UPDATE ON parent BEGIN
 1852:       UPDATE child1 set c = new.x WHERE c = old.x;
 1853:       UPDATE child2 set c = new.x WHERE c = old.x;
 1854:     END;
 1855:   }
 1856: } {}
 1857: do_test e_fkey-42.2 {
 1858:   catchsql { UPDATE parent SET x = 'key one' WHERE x = 'key1' }
 1859: } {1 {foreign key constraint failed}}
 1860: do_test e_fkey-42.3 {
 1861:   execsql { 
 1862:     UPDATE parent SET x = 'key two' WHERE x = 'key2';
 1863:     SELECT * FROM child2;
 1864:   }
 1865: } {{key two}}
 1866: 
 1867: drop_all_tables
 1868: do_test e_fkey-42.4 {
 1869:   execsql {
 1870:     CREATE TABLE parent(x PRIMARY KEY);
 1871:     CREATE TABLE child1(c REFERENCES parent ON DELETE RESTRICT);
 1872:     CREATE TABLE child2(c REFERENCES parent ON DELETE NO ACTION);
 1873: 
 1874:     INSERT INTO parent VALUES('key1');
 1875:     INSERT INTO parent VALUES('key2');
 1876:     INSERT INTO child1 VALUES('key1');
 1877:     INSERT INTO child2 VALUES('key2');
 1878: 
 1879:     CREATE TRIGGER parent_t AFTER DELETE ON parent BEGIN
 1880:       UPDATE child1 SET c = NULL WHERE c = old.x;
 1881:       UPDATE child2 SET c = NULL WHERE c = old.x;
 1882:     END;
 1883:   }
 1884: } {}
 1885: do_test e_fkey-42.5 {
 1886:   catchsql { DELETE FROM parent WHERE x = 'key1' }
 1887: } {1 {foreign key constraint failed}}
 1888: do_test e_fkey-42.6 {
 1889:   execsql { 
 1890:     DELETE FROM parent WHERE x = 'key2';
 1891:     SELECT * FROM child2;
 1892:   }
 1893: } {{}}
 1894: 
 1895: drop_all_tables
 1896: do_test e_fkey-42.7 {
 1897:   execsql {
 1898:     CREATE TABLE parent(x PRIMARY KEY);
 1899:     CREATE TABLE child1(c REFERENCES parent ON DELETE RESTRICT);
 1900:     CREATE TABLE child2(c REFERENCES parent ON DELETE NO ACTION);
 1901: 
 1902:     INSERT INTO parent VALUES('key1');
 1903:     INSERT INTO parent VALUES('key2');
 1904:     INSERT INTO child1 VALUES('key1');
 1905:     INSERT INTO child2 VALUES('key2');
 1906:   }
 1907: } {}
 1908: do_test e_fkey-42.8 {
 1909:   catchsql { REPLACE INTO parent VALUES('key1') }
 1910: } {1 {foreign key constraint failed}}
 1911: do_test e_fkey-42.9 {
 1912:   execsql { 
 1913:     REPLACE INTO parent VALUES('key2');
 1914:     SELECT * FROM child2;
 1915:   }
 1916: } {key2}
 1917: 
 1918: #-------------------------------------------------------------------------
 1919: # Test that RESTRICT is enforced immediately, even for a DEFERRED constraint.
 1920: #
 1921: # EVIDENCE-OF: R-24179-60523 Even if the foreign key constraint it is
 1922: # attached to is deferred, configuring a RESTRICT action causes SQLite
 1923: # to return an error immediately if a parent key with dependent child
 1924: # keys is deleted or modified.
 1925: #
 1926: drop_all_tables
 1927: do_test e_fkey-43.1 {
 1928:   execsql {
 1929:     CREATE TABLE parent(x PRIMARY KEY);
 1930:     CREATE TABLE child1(c REFERENCES parent ON UPDATE RESTRICT
 1931:       DEFERRABLE INITIALLY DEFERRED
 1932:     );
 1933:     CREATE TABLE child2(c REFERENCES parent ON UPDATE NO ACTION
 1934:       DEFERRABLE INITIALLY DEFERRED
 1935:     );
 1936: 
 1937:     INSERT INTO parent VALUES('key1');
 1938:     INSERT INTO parent VALUES('key2');
 1939:     INSERT INTO child1 VALUES('key1');
 1940:     INSERT INTO child2 VALUES('key2');
 1941:     BEGIN;
 1942:   }
 1943: } {}
 1944: do_test e_fkey-43.2 {
 1945:   catchsql { UPDATE parent SET x = 'key one' WHERE x = 'key1' }
 1946: } {1 {foreign key constraint failed}}
 1947: do_test e_fkey-43.3 {
 1948:   execsql { UPDATE parent SET x = 'key two' WHERE x = 'key2' }
 1949: } {}
 1950: do_test e_fkey-43.4 {
 1951:   catchsql COMMIT
 1952: } {1 {foreign key constraint failed}}
 1953: do_test e_fkey-43.5 {
 1954:   execsql {
 1955:     UPDATE child2 SET c = 'key two';
 1956:     COMMIT;
 1957:   }
 1958: } {}
 1959: 
 1960: drop_all_tables
 1961: do_test e_fkey-43.6 {
 1962:   execsql {
 1963:     CREATE TABLE parent(x PRIMARY KEY);
 1964:     CREATE TABLE child1(c REFERENCES parent ON DELETE RESTRICT
 1965:       DEFERRABLE INITIALLY DEFERRED
 1966:     );
 1967:     CREATE TABLE child2(c REFERENCES parent ON DELETE NO ACTION
 1968:       DEFERRABLE INITIALLY DEFERRED
 1969:     );
 1970: 
 1971:     INSERT INTO parent VALUES('key1');
 1972:     INSERT INTO parent VALUES('key2');
 1973:     INSERT INTO child1 VALUES('key1');
 1974:     INSERT INTO child2 VALUES('key2');
 1975:     BEGIN;
 1976:   }
 1977: } {}
 1978: do_test e_fkey-43.7 {
 1979:   catchsql { DELETE FROM parent WHERE x = 'key1' }
 1980: } {1 {foreign key constraint failed}}
 1981: do_test e_fkey-43.8 {
 1982:   execsql { DELETE FROM parent WHERE x = 'key2' }
 1983: } {}
 1984: do_test e_fkey-43.9 {
 1985:   catchsql COMMIT
 1986: } {1 {foreign key constraint failed}}
 1987: do_test e_fkey-43.10 {
 1988:   execsql {
 1989:     UPDATE child2 SET c = NULL;
 1990:     COMMIT;
 1991:   }
 1992: } {}
 1993: 
 1994: #-------------------------------------------------------------------------
 1995: # Test SET NULL actions.
 1996: #
 1997: # EVIDENCE-OF: R-03353-05327 If the configured action is "SET NULL",
 1998: # then when a parent key is deleted (for ON DELETE SET NULL) or modified
 1999: # (for ON UPDATE SET NULL), the child key columns of all rows in the
 2000: # child table that mapped to the parent key are set to contain SQL NULL
 2001: # values.
 2002: #
 2003: drop_all_tables
 2004: do_test e_fkey-44.1 {
 2005:   execsql {
 2006:     CREATE TABLE pA(x PRIMARY KEY);
 2007:     CREATE TABLE cA(c REFERENCES pA ON DELETE SET NULL);
 2008:     CREATE TABLE cB(c REFERENCES pA ON UPDATE SET NULL);
 2009: 
 2010:     INSERT INTO pA VALUES(X'ABCD');
 2011:     INSERT INTO pA VALUES(X'1234');
 2012:     INSERT INTO cA VALUES(X'ABCD');
 2013:     INSERT INTO cB VALUES(X'1234');
 2014:   }
 2015: } {}
 2016: do_test e_fkey-44.2 {
 2017:   execsql {
 2018:     DELETE FROM pA WHERE rowid = 1;
 2019:     SELECT quote(x) FROM pA;
 2020:   }
 2021: } {X'1234'}
 2022: do_test e_fkey-44.3 {
 2023:   execsql {
 2024:     SELECT quote(c) FROM cA;
 2025:   }
 2026: } {NULL}
 2027: do_test e_fkey-44.4 {
 2028:   execsql {
 2029:     UPDATE pA SET x = X'8765' WHERE rowid = 2;
 2030:     SELECT quote(x) FROM pA;
 2031:   }
 2032: } {X'8765'}
 2033: do_test e_fkey-44.5 {
 2034:   execsql { SELECT quote(c) FROM cB }
 2035: } {NULL}
 2036: 
 2037: #-------------------------------------------------------------------------
 2038: # Test SET DEFAULT actions.
 2039: #
 2040: # EVIDENCE-OF: R-43054-54832 The "SET DEFAULT" actions are similar to
 2041: # "SET NULL", except that each of the child key columns is set to
 2042: # contain the columns default value instead of NULL.
 2043: #
 2044: drop_all_tables
 2045: do_test e_fkey-45.1 {
 2046:   execsql {
 2047:     CREATE TABLE pA(x PRIMARY KEY);
 2048:     CREATE TABLE cA(c DEFAULT X'0000' REFERENCES pA ON DELETE SET DEFAULT);
 2049:     CREATE TABLE cB(c DEFAULT X'9999' REFERENCES pA ON UPDATE SET DEFAULT);
 2050: 
 2051:     INSERT INTO pA(rowid, x) VALUES(1, X'0000');
 2052:     INSERT INTO pA(rowid, x) VALUES(2, X'9999');
 2053:     INSERT INTO pA(rowid, x) VALUES(3, X'ABCD');
 2054:     INSERT INTO pA(rowid, x) VALUES(4, X'1234');
 2055: 
 2056:     INSERT INTO cA VALUES(X'ABCD');
 2057:     INSERT INTO cB VALUES(X'1234');
 2058:   }
 2059: } {}
 2060: do_test e_fkey-45.2 {
 2061:   execsql {
 2062:     DELETE FROM pA WHERE rowid = 3;
 2063:     SELECT quote(x) FROM pA;
 2064:   }
 2065: } {X'0000' X'9999' X'1234'}
 2066: do_test e_fkey-45.3 {
 2067:   execsql { SELECT quote(c) FROM cA }
 2068: } {X'0000'}
 2069: do_test e_fkey-45.4 {
 2070:   execsql {
 2071:     UPDATE pA SET x = X'8765' WHERE rowid = 4;
 2072:     SELECT quote(x) FROM pA;
 2073:   }
 2074: } {X'0000' X'9999' X'8765'}
 2075: do_test e_fkey-45.5 {
 2076:   execsql { SELECT quote(c) FROM cB }
 2077: } {X'9999'}
 2078: 
 2079: #-------------------------------------------------------------------------
 2080: # Test ON DELETE CASCADE actions.
 2081: #
 2082: # EVIDENCE-OF: R-61376-57267 A "CASCADE" action propagates the delete or
 2083: # update operation on the parent key to each dependent child key.
 2084: #
 2085: # EVIDENCE-OF: R-61809-62207 For an "ON DELETE CASCADE" action, this
 2086: # means that each row in the child table that was associated with the
 2087: # deleted parent row is also deleted.
 2088: #
 2089: drop_all_tables
 2090: do_test e_fkey-46.1 {
 2091:   execsql {
 2092:     CREATE TABLE p1(a, b UNIQUE);
 2093:     CREATE TABLE c1(c REFERENCES p1(b) ON DELETE CASCADE, d);
 2094:     INSERT INTO p1 VALUES(NULL, NULL);
 2095:     INSERT INTO p1 VALUES(4, 4);
 2096:     INSERT INTO p1 VALUES(5, 5);
 2097:     INSERT INTO c1 VALUES(NULL, NULL);
 2098:     INSERT INTO c1 VALUES(4, 4);
 2099:     INSERT INTO c1 VALUES(5, 5);
 2100:     SELECT count(*) FROM c1;
 2101:   }
 2102: } {3}
 2103: do_test e_fkey-46.2 {
 2104:   execsql {
 2105:     DELETE FROM p1 WHERE a = 4;
 2106:     SELECT d, c FROM c1;
 2107:   }
 2108: } {{} {} 5 5}
 2109: do_test e_fkey-46.3 {
 2110:   execsql {
 2111:     DELETE FROM p1;
 2112:     SELECT d, c FROM c1;
 2113:   }
 2114: } {{} {}}
 2115: do_test e_fkey-46.4 {
 2116:   execsql { SELECT * FROM p1 }
 2117: } {}
 2118: 
 2119: 
 2120: #-------------------------------------------------------------------------
 2121: # Test ON UPDATE CASCADE actions.
 2122: #
 2123: # EVIDENCE-OF: R-13877-64542 For an "ON UPDATE CASCADE" action, it means
 2124: # that the values stored in each dependent child key are modified to
 2125: # match the new parent key values.
 2126: #
 2127: # EVIDENCE-OF: R-61376-57267 A "CASCADE" action propagates the delete or
 2128: # update operation on the parent key to each dependent child key.
 2129: #
 2130: drop_all_tables
 2131: do_test e_fkey-47.1 {
 2132:   execsql {
 2133:     CREATE TABLE p1(a, b UNIQUE);
 2134:     CREATE TABLE c1(c REFERENCES p1(b) ON UPDATE CASCADE, d);
 2135:     INSERT INTO p1 VALUES(NULL, NULL);
 2136:     INSERT INTO p1 VALUES(4, 4);
 2137:     INSERT INTO p1 VALUES(5, 5);
 2138:     INSERT INTO c1 VALUES(NULL, NULL);
 2139:     INSERT INTO c1 VALUES(4, 4);
 2140:     INSERT INTO c1 VALUES(5, 5);
 2141:     SELECT count(*) FROM c1;
 2142:   }
 2143: } {3}
 2144: do_test e_fkey-47.2 {
 2145:   execsql {
 2146:     UPDATE p1 SET b = 10 WHERE b = 5;
 2147:     SELECT d, c FROM c1;
 2148:   }
 2149: } {{} {} 4 4 5 10}
 2150: do_test e_fkey-47.3 {
 2151:   execsql {
 2152:     UPDATE p1 SET b = 11 WHERE b = 4;
 2153:     SELECT d, c FROM c1;
 2154:   }
 2155: } {{} {} 4 11 5 10}
 2156: do_test e_fkey-47.4 {
 2157:   execsql { 
 2158:     UPDATE p1 SET b = 6 WHERE b IS NULL;
 2159:     SELECT d, c FROM c1;
 2160:   }
 2161: } {{} {} 4 11 5 10}
 2162: do_test e_fkey-46.5 {
 2163:   execsql { SELECT * FROM p1 }
 2164: } {{} 6 4 11 5 10}
 2165: 
 2166: #-------------------------------------------------------------------------
 2167: # EVIDENCE-OF: R-65058-57158
 2168: #
 2169: # Test an example from the "ON DELETE and ON UPDATE Actions" section 
 2170: # of foreignkeys.html.
 2171: #
 2172: drop_all_tables
 2173: do_test e_fkey-48.1 {
 2174:   execsql {
 2175:     CREATE TABLE artist(
 2176:       artistid    INTEGER PRIMARY KEY, 
 2177:       artistname  TEXT
 2178:     );
 2179:     CREATE TABLE track(
 2180:       trackid     INTEGER,
 2181:       trackname   TEXT, 
 2182:       trackartist INTEGER REFERENCES artist(artistid) ON UPDATE CASCADE
 2183:     );
 2184: 
 2185:     INSERT INTO artist VALUES(1, 'Dean Martin');
 2186:     INSERT INTO artist VALUES(2, 'Frank Sinatra');
 2187:     INSERT INTO track VALUES(11, 'That''s Amore', 1);
 2188:     INSERT INTO track VALUES(12, 'Christmas Blues', 1);
 2189:     INSERT INTO track VALUES(13, 'My Way', 2);
 2190:   }
 2191: } {}
 2192: do_test e_fkey-48.2 {
 2193:   execsql {
 2194:     UPDATE artist SET artistid = 100 WHERE artistname = 'Dean Martin';
 2195:   }
 2196: } {}
 2197: do_test e_fkey-48.3 {
 2198:   execsql { SELECT * FROM artist }
 2199: } {2 {Frank Sinatra} 100 {Dean Martin}}
 2200: do_test e_fkey-48.4 {
 2201:   execsql { SELECT * FROM track }
 2202: } {11 {That's Amore} 100 12 {Christmas Blues} 100 13 {My Way} 2}
 2203: 
 2204: 
 2205: #-------------------------------------------------------------------------
 2206: # Verify that adding an FK action does not absolve the user of the 
 2207: # requirement not to violate the foreign key constraint.
 2208: #
 2209: # EVIDENCE-OF: R-53968-51642 Configuring an ON UPDATE or ON DELETE
 2210: # action does not mean that the foreign key constraint does not need to
 2211: # be satisfied.
 2212: #
 2213: drop_all_tables
 2214: do_test e_fkey-49.1 {
 2215:   execsql {
 2216:     CREATE TABLE parent(a COLLATE nocase, b, c, PRIMARY KEY(c, a));
 2217:     CREATE TABLE child(d DEFAULT 'a', e, f DEFAULT 'c',
 2218:       FOREIGN KEY(f, d) REFERENCES parent ON UPDATE SET DEFAULT
 2219:     );
 2220: 
 2221:     INSERT INTO parent VALUES('A', 'b', 'c');
 2222:     INSERT INTO parent VALUES('ONE', 'two', 'three');
 2223:     INSERT INTO child VALUES('one', 'two', 'three');
 2224:   }
 2225: } {}
 2226: do_test e_fkey-49.2 {
 2227:   execsql {
 2228:     BEGIN;
 2229:       UPDATE parent SET a = '' WHERE a = 'oNe';
 2230:       SELECT * FROM child;
 2231:   }
 2232: } {a two c}
 2233: do_test e_fkey-49.3 {
 2234:   execsql {
 2235:     ROLLBACK;
 2236:     DELETE FROM parent WHERE a = 'A';
 2237:     SELECT * FROM parent;
 2238:   }
 2239: } {ONE two three}
 2240: do_test e_fkey-49.4 {
 2241:   catchsql { UPDATE parent SET a = '' WHERE a = 'oNe' }
 2242: } {1 {foreign key constraint failed}}
 2243: 
 2244: 
 2245: #-------------------------------------------------------------------------
 2246: # EVIDENCE-OF: R-11856-19836
 2247: #
 2248: # 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"
 2250: # clause does not abrogate the need to satisfy the foreign key constraint
 2251: # (R-28220-46694).
 2252: #
 2253: # EVIDENCE-OF: R-28220-46694 For example, if an "ON DELETE SET DEFAULT"
 2254: # action is configured, but there is no row in the parent table that
 2255: # corresponds to the default values of the child key columns, deleting a
 2256: # parent key while dependent child keys exist still causes a foreign key
 2257: # violation.
 2258: #
 2259: drop_all_tables
 2260: do_test e_fkey-50.1 {
 2261:   execsql {
 2262:     CREATE TABLE artist(
 2263:       artistid    INTEGER PRIMARY KEY, 
 2264:       artistname  TEXT
 2265:     );
 2266:     CREATE TABLE track(
 2267:       trackid     INTEGER,
 2268:       trackname   TEXT, 
 2269:       trackartist INTEGER DEFAULT 0 REFERENCES artist(artistid) ON DELETE SET DEFAULT
 2270:     );
 2271:     INSERT INTO artist VALUES(3, 'Sammy Davis Jr.');
 2272:     INSERT INTO track VALUES(14, 'Mr. Bojangles', 3);
 2273:   }
 2274: } {}
 2275: do_test e_fkey-50.2 {
 2276:   catchsql { DELETE FROM artist WHERE artistname = 'Sammy Davis Jr.' }
 2277: } {1 {foreign key constraint failed}}
 2278: do_test e_fkey-50.3 {
 2279:   execsql {
 2280:     INSERT INTO artist VALUES(0, 'Unknown Artist');
 2281:     DELETE FROM artist WHERE artistname = 'Sammy Davis Jr.';
 2282:   }
 2283: } {}
 2284: do_test e_fkey-50.4 {
 2285:   execsql { SELECT * FROM artist }
 2286: } {0 {Unknown Artist}}
 2287: do_test e_fkey-50.5 {
 2288:   execsql { SELECT * FROM track }
 2289: } {14 {Mr. Bojangles} 0}
 2290: 
 2291: #-------------------------------------------------------------------------
 2292: # EVIDENCE-OF: R-09564-22170
 2293: #
 2294: # Check that the order of steps in an UPDATE or DELETE on a parent 
 2295: # table is as follows:
 2296: #
 2297: #   1. Execute applicable BEFORE trigger programs,
 2298: #   2. Check local (non foreign key) constraints,
 2299: #   3. Update or delete the row in the parent table,
 2300: #   4. Perform any required foreign key actions,
 2301: #   5. Execute applicable AFTER trigger programs. 
 2302: #
 2303: drop_all_tables
 2304: do_test e_fkey-51.1 {
 2305:   proc maxparent {args} { db one {SELECT max(x) FROM parent} }
 2306:   db func maxparent maxparent
 2307: 
 2308:   execsql {
 2309:     CREATE TABLE parent(x PRIMARY KEY);
 2310: 
 2311:     CREATE TRIGGER bu BEFORE UPDATE ON parent BEGIN
 2312:       INSERT INTO parent VALUES(new.x-old.x);
 2313:     END;
 2314:     CREATE TABLE child(
 2315:       a DEFAULT (maxparent()) REFERENCES parent ON UPDATE SET DEFAULT
 2316:     );
 2317:     CREATE TRIGGER au AFTER UPDATE ON parent BEGIN
 2318:       INSERT INTO parent VALUES(new.x+old.x);
 2319:     END;
 2320: 
 2321:     INSERT INTO parent VALUES(1);
 2322:     INSERT INTO child VALUES(1);
 2323:   }
 2324: } {}
 2325: do_test e_fkey-51.2 {
 2326:   execsql {
 2327:     UPDATE parent SET x = 22;
 2328:     SELECT * FROM parent UNION ALL SELECT 'xxx' UNION ALL SELECT a FROM child;
 2329:   }
 2330: } {22 21 23 xxx 22}
 2331: do_test e_fkey-51.3 {
 2332:   execsql {
 2333:     DELETE FROM child;
 2334:     DELETE FROM parent;
 2335:     INSERT INTO parent VALUES(-1);
 2336:     INSERT INTO child VALUES(-1);
 2337:     UPDATE parent SET x = 22;
 2338:     SELECT * FROM parent UNION ALL SELECT 'xxx' UNION ALL SELECT a FROM child;
 2339:   }
 2340: } {22 23 21 xxx 23}
 2341: 
 2342: 
 2343: #-------------------------------------------------------------------------
 2344: # 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
 2346: # collation sequence and affinity are used to determine if the new value
 2347: # is 'distinct' from the old or not.
 2348: #
 2349: # EVIDENCE-OF: R-27383-10246 An ON UPDATE action is only taken if the
 2350: # values of the parent key are modified so that the new parent key
 2351: # values are not equal to the old.
 2352: #
 2353: drop_all_tables
 2354: do_test e_fkey-52.1 {
 2355:   execsql {
 2356:     CREATE TABLE zeus(a INTEGER COLLATE NOCASE, b, PRIMARY KEY(a, b));
 2357:     CREATE TABLE apollo(c, d, 
 2358:       FOREIGN KEY(c, d) REFERENCES zeus ON UPDATE CASCADE
 2359:     );
 2360:     INSERT INTO zeus VALUES('abc', 'xyz');
 2361:     INSERT INTO apollo VALUES('ABC', 'xyz');
 2362:   }
 2363:   execsql {
 2364:     UPDATE zeus SET a = 'aBc';
 2365:     SELECT * FROM apollo;
 2366:   }
 2367: } {ABC xyz}
 2368: do_test e_fkey-52.2 {
 2369:   execsql {
 2370:     UPDATE zeus SET a = 1, b = 1;
 2371:     SELECT * FROM apollo;
 2372:   }
 2373: } {1 1}
 2374: do_test e_fkey-52.3 {
 2375:   execsql {
 2376:     UPDATE zeus SET a = 1, b = 1;
 2377:     SELECT typeof(c), c, typeof(d), d FROM apollo;
 2378:   }
 2379: } {integer 1 integer 1}
 2380: do_test e_fkey-52.4 {
 2381:   execsql {
 2382:     UPDATE zeus SET a = '1';
 2383:     SELECT typeof(c), c, typeof(d), d FROM apollo;
 2384:   }
 2385: } {integer 1 integer 1}
 2386: do_test e_fkey-52.5 {
 2387:   execsql {
 2388:     UPDATE zeus SET b = '1';
 2389:     SELECT typeof(c), c, typeof(d), d FROM apollo;
 2390:   }
 2391: } {integer 1 text 1}
 2392: do_test e_fkey-52.6 {
 2393:   execsql {
 2394:     UPDATE zeus SET b = NULL;
 2395:     SELECT typeof(c), c, typeof(d), d FROM apollo;
 2396:   }
 2397: } {integer 1 null {}}
 2398: 
 2399: #-------------------------------------------------------------------------
 2400: # EVIDENCE-OF: R-35129-58141
 2401: #
 2402: # Test an example from the "ON DELETE and ON UPDATE Actions" section 
 2403: # of foreignkeys.html. This example demonstrates that ON UPDATE actions
 2404: # only take place if at least one parent key column is set to a value 
 2405: # that is distinct from its previous value.
 2406: #
 2407: drop_all_tables
 2408: do_test e_fkey-53.1 {
 2409:   execsql {
 2410:     CREATE TABLE parent(x PRIMARY KEY);
 2411:     CREATE TABLE child(y REFERENCES parent ON UPDATE SET NULL);
 2412:     INSERT INTO parent VALUES('key');
 2413:     INSERT INTO child VALUES('key');
 2414:   }
 2415: } {}
 2416: do_test e_fkey-53.2 {
 2417:   execsql {
 2418:     UPDATE parent SET x = 'key';
 2419:     SELECT IFNULL(y, 'null') FROM child;
 2420:   }
 2421: } {key}
 2422: do_test e_fkey-53.3 {
 2423:   execsql {
 2424:     UPDATE parent SET x = 'key2';
 2425:     SELECT IFNULL(y, 'null') FROM child;
 2426:   }
 2427: } {null}
 2428: 
 2429: ###########################################################################
 2430: ### SECTION 5: CREATE, ALTER and DROP TABLE commands
 2431: ###########################################################################
 2432: 
 2433: #-------------------------------------------------------------------------
 2434: # Test that parent keys are not checked when tables are created.
 2435: #
 2436: # EVIDENCE-OF: R-36018-21755 The parent key definitions of foreign key
 2437: # constraints are not checked when a table is created.
 2438: #
 2439: # EVIDENCE-OF: R-25384-39337 There is nothing stopping the user from
 2440: # creating a foreign key definition that refers to a parent table that
 2441: # does not exist, or to parent key columns that do not exist or are not
 2442: # collectively bound by a PRIMARY KEY or UNIQUE constraint.
 2443: #
 2444: # Child keys are checked to ensure all component columns exist. If parent
 2445: # key columns are explicitly specified, SQLite checks to make sure there
 2446: # are the same number of columns in the child and parent keys. (TODO: This
 2447: # is tested but does not correspond to any testable statement.)
 2448: #
 2449: # Also test that the above statements are true regardless of whether or not
 2450: # foreign keys are enabled:  "A CREATE TABLE command operates the same whether
 2451: # or not foreign key constraints are enabled."
 2452: #
 2453: # EVIDENCE-OF: R-08908-23439 A CREATE TABLE command operates the same
 2454: # whether or not foreign key constraints are enabled.
 2455: # 
 2456: foreach {tn zCreateTbl lRes} {
 2457:   1 "CREATE TABLE t1(a, b REFERENCES t1)"                            {0 {}}
 2458:   2 "CREATE TABLE t1(a, b REFERENCES t2)"                            {0 {}}
 2459:   3 "CREATE TABLE t1(a, b, FOREIGN KEY(a,b) REFERENCES t1)"          {0 {}}
 2460:   4 "CREATE TABLE t1(a, b, FOREIGN KEY(a,b) REFERENCES t2)"          {0 {}}
 2461:   5 "CREATE TABLE t1(a, b, FOREIGN KEY(a,b) REFERENCES t2)"          {0 {}}
 2462:   6 "CREATE TABLE t1(a, b, FOREIGN KEY(a,b) REFERENCES t2(n,d))"     {0 {}}
 2463:   7 "CREATE TABLE t1(a, b, FOREIGN KEY(a,b) REFERENCES t1(a,b))"     {0 {}}
 2464: 
 2465:   A "CREATE TABLE t1(a, b, FOREIGN KEY(c,b) REFERENCES t2)"          
 2466:      {1 {unknown column "c" in foreign key definition}}
 2467:   B "CREATE TABLE t1(a, b, FOREIGN KEY(c,b) REFERENCES t2(d))"          
 2468:      {1 {number of columns in foreign key does not match the number of columns in the referenced table}}
 2469: } {
 2470:   do_test e_fkey-54.$tn.off {
 2471:     drop_all_tables
 2472:     execsql {PRAGMA foreign_keys = OFF}
 2473:     catchsql $zCreateTbl
 2474:   } $lRes
 2475:   do_test e_fkey-54.$tn.on {
 2476:     drop_all_tables
 2477:     execsql {PRAGMA foreign_keys = ON}
 2478:     catchsql $zCreateTbl
 2479:   } $lRes
 2480: }
 2481: 
 2482: #-------------------------------------------------------------------------
 2483: # EVIDENCE-OF: R-47952-62498 It is not possible to use the "ALTER TABLE
 2484: # ... ADD COLUMN" syntax to add a column that includes a REFERENCES
 2485: # clause, unless the default value of the new column is NULL. Attempting
 2486: # to do so returns an error.
 2487: #
 2488: proc test_efkey_6 {tn zAlter isError} {
 2489:   drop_all_tables 
 2490: 
 2491:   do_test e_fkey-56.$tn.1 "
 2492:     execsql { CREATE TABLE tbl(a, b) }
 2493:     [list catchsql $zAlter]
 2494:   " [lindex {{0 {}} {1 {Cannot add a REFERENCES column with non-NULL default value}}} $isError]
 2495: 
 2496: }
 2497: 
 2498: test_efkey_6 1 "ALTER TABLE tbl ADD COLUMN c REFERENCES xx" 0
 2499: test_efkey_6 2 "ALTER TABLE tbl ADD COLUMN c DEFAULT NULL REFERENCES xx" 0
 2500: test_efkey_6 3 "ALTER TABLE tbl ADD COLUMN c DEFAULT 0 REFERENCES xx" 1
 2501: 
 2502: #-------------------------------------------------------------------------
 2503: # Test that ALTER TABLE adjusts REFERENCES clauses when the parent table
 2504: # is RENAMED.
 2505: #
 2506: # EVIDENCE-OF: R-47080-02069 If an "ALTER TABLE ... RENAME TO" command
 2507: # is used to rename a table that is the parent table of one or more
 2508: # foreign key constraints, the definitions of the foreign key
 2509: # constraints are modified to refer to the parent table by its new name
 2510: #
 2511: # Test that these adjustments are visible in the sqlite_master table.
 2512: #
 2513: # EVIDENCE-OF: R-63827-54774 The text of the child CREATE TABLE
 2514: # statement or statements stored in the sqlite_master table are modified
 2515: # to reflect the new parent table name.
 2516: #
 2517: do_test e_fkey-56.1 {
 2518:   drop_all_tables
 2519:   execsql {
 2520:     CREATE TABLE 'p 1 "parent one"'(a REFERENCES 'p 1 "parent one"', b, PRIMARY KEY(b));
 2521: 
 2522:     CREATE TABLE c1(c, d REFERENCES 'p 1 "parent one"' ON UPDATE CASCADE);
 2523:     CREATE TABLE c2(e, f, FOREIGN KEY(f) REFERENCES 'p 1 "parent one"' ON UPDATE CASCADE);
 2524:     CREATE TABLE c3(e, 'f col 2', FOREIGN KEY('f col 2') REFERENCES 'p 1 "parent one"' ON UPDATE CASCADE);
 2525: 
 2526:     INSERT INTO 'p 1 "parent one"' VALUES(1, 1);
 2527:     INSERT INTO c1 VALUES(1, 1);
 2528:     INSERT INTO c2 VALUES(1, 1);
 2529:     INSERT INTO c3 VALUES(1, 1);
 2530: 
 2531:     -- CREATE TABLE q(a, b, PRIMARY KEY(b));
 2532:   }
 2533: } {}
 2534: do_test e_fkey-56.2 {
 2535:   execsql { ALTER TABLE 'p 1 "parent one"' RENAME TO p }
 2536: } {}
 2537: do_test e_fkey-56.3 {
 2538:   execsql {
 2539:     UPDATE p SET a = 'xxx', b = 'xxx';
 2540:     SELECT * FROM p;
 2541:     SELECT * FROM c1;
 2542:     SELECT * FROM c2;
 2543:     SELECT * FROM c3;
 2544:   }
 2545: } {xxx xxx 1 xxx 1 xxx 1 xxx}
 2546: do_test e_fkey-56.4 {
 2547:   execsql { SELECT sql FROM sqlite_master WHERE type = 'table'}
 2548: } [list                                                                     \
 2549:   {CREATE TABLE "p"(a REFERENCES "p", b, PRIMARY KEY(b))}                   \
 2550:   {CREATE TABLE c1(c, d REFERENCES "p" ON UPDATE CASCADE)}                  \
 2551:   {CREATE TABLE c2(e, f, FOREIGN KEY(f) REFERENCES "p" ON UPDATE CASCADE)}  \
 2552:   {CREATE TABLE c3(e, 'f col 2', FOREIGN KEY('f col 2') REFERENCES "p" ON UPDATE CASCADE)} \
 2553: ]
 2554: 
 2555: #-------------------------------------------------------------------------
 2556: # Check that a DROP TABLE does an implicit DELETE FROM. Which does not
 2557: # cause any triggers to fire, but does fire foreign key actions.
 2558: #
 2559: # EVIDENCE-OF: R-14208-23986 If foreign key constraints are enabled when
 2560: # it is prepared, the DROP TABLE command performs an implicit DELETE to
 2561: # remove all rows from the table before dropping it.
 2562: #
 2563: # EVIDENCE-OF: R-11078-03945 The implicit DELETE does not cause any SQL
 2564: # triggers to fire, but may invoke foreign key actions or constraint
 2565: # violations.
 2566: #
 2567: do_test e_fkey-57.1 {
 2568:   drop_all_tables
 2569:   execsql {
 2570:     CREATE TABLE p(a, b, PRIMARY KEY(a, b));
 2571: 
 2572:     CREATE TABLE c1(c, d, FOREIGN KEY(c, d) REFERENCES p ON DELETE SET NULL);
 2573:     CREATE TABLE c2(c, d, FOREIGN KEY(c, d) REFERENCES p ON DELETE SET DEFAULT);
 2574:     CREATE TABLE c3(c, d, FOREIGN KEY(c, d) REFERENCES p ON DELETE CASCADE);
 2575:     CREATE TABLE c4(c, d, FOREIGN KEY(c, d) REFERENCES p ON DELETE RESTRICT);
 2576:     CREATE TABLE c5(c, d, FOREIGN KEY(c, d) REFERENCES p ON DELETE NO ACTION);
 2577: 
 2578:     CREATE TABLE c6(c, d, 
 2579:       FOREIGN KEY(c, d) REFERENCES p ON DELETE RESTRICT 
 2580:       DEFERRABLE INITIALLY DEFERRED
 2581:     );
 2582:     CREATE TABLE c7(c, d, 
 2583:       FOREIGN KEY(c, d) REFERENCES p ON DELETE NO ACTION
 2584:       DEFERRABLE INITIALLY DEFERRED
 2585:     );
 2586: 
 2587:     CREATE TABLE log(msg);
 2588:     CREATE TRIGGER tt AFTER DELETE ON p BEGIN
 2589:       INSERT INTO log VALUES('delete ' || old.rowid);
 2590:     END;
 2591:   }
 2592: } {}
 2593: 
 2594: do_test e_fkey-57.2 {
 2595:   execsql {
 2596:     INSERT INTO p VALUES('a', 'b');
 2597:     INSERT INTO c1 VALUES('a', 'b');
 2598:     INSERT INTO c2 VALUES('a', 'b');
 2599:     INSERT INTO c3 VALUES('a', 'b');
 2600:     BEGIN;
 2601:       DROP TABLE p;
 2602:       SELECT * FROM c1;
 2603:   }
 2604: } {{} {}}
 2605: do_test e_fkey-57.3 {
 2606:   execsql { SELECT * FROM c2 }
 2607: } {{} {}}
 2608: do_test e_fkey-57.4 {
 2609:   execsql { SELECT * FROM c3 }
 2610: } {}
 2611: do_test e_fkey-57.5 {
 2612:   execsql { SELECT * FROM log }
 2613: } {}
 2614: do_test e_fkey-57.6 {
 2615:   execsql ROLLBACK
 2616: } {}
 2617: do_test e_fkey-57.7 {
 2618:   execsql {
 2619:     BEGIN;
 2620:       DELETE FROM p;
 2621:       SELECT * FROM log;
 2622:     ROLLBACK;
 2623:   }
 2624: } {{delete 1}}
 2625: 
 2626: #-------------------------------------------------------------------------
 2627: # If an IMMEDIATE foreign key fails as a result of a DROP TABLE, the
 2628: # DROP TABLE command fails.
 2629: #
 2630: # EVIDENCE-OF: R-32768-47925 If an immediate foreign key constraint is
 2631: # violated, the DROP TABLE statement fails and the table is not dropped.
 2632: #
 2633: do_test e_fkey-58.1 {
 2634:   execsql { 
 2635:     DELETE FROM c1;
 2636:     DELETE FROM c2;
 2637:     DELETE FROM c3;
 2638:   }
 2639:   execsql { INSERT INTO c5 VALUES('a', 'b') }
 2640:   catchsql { DROP TABLE p }
 2641: } {1 {foreign key constraint failed}}
 2642: do_test e_fkey-58.2 {
 2643:   execsql { SELECT * FROM p }
 2644: } {a b}
 2645: do_test e_fkey-58.3 {
 2646:   catchsql {
 2647:     BEGIN;
 2648:       DROP TABLE p;
 2649:   }
 2650: } {1 {foreign key constraint failed}}
 2651: do_test e_fkey-58.4 {
 2652:   execsql {
 2653:     SELECT * FROM p;
 2654:     SELECT * FROM c5;
 2655:     ROLLBACK;
 2656:   }
 2657: } {a b a b}
 2658: 
 2659: #-------------------------------------------------------------------------
 2660: # If a DEFERRED foreign key fails as a result of a DROP TABLE, attempting
 2661: # to commit the transaction fails unless the violation is fixed.
 2662: #
 2663: # EVIDENCE-OF: R-05903-08460 If a deferred foreign key constraint is
 2664: # violated, then an error is reported when the user attempts to commit
 2665: # the transaction if the foreign key constraint violations still exist
 2666: # at that point.
 2667: #
 2668: do_test e_fkey-59.1 {
 2669:   execsql { 
 2670:     DELETE FROM c1 ; DELETE FROM c2 ; DELETE FROM c3 ;
 2671:     DELETE FROM c4 ; DELETE FROM c5 ; DELETE FROM c6 ;
 2672:     DELETE FROM c7 
 2673:   }
 2674: } {}
 2675: do_test e_fkey-59.2 {
 2676:   execsql { INSERT INTO c7 VALUES('a', 'b') }
 2677:   execsql {
 2678:     BEGIN;
 2679:       DROP TABLE p;
 2680:   }
 2681: } {}
 2682: do_test e_fkey-59.3 {
 2683:   catchsql COMMIT
 2684: } {1 {foreign key constraint failed}}
 2685: do_test e_fkey-59.4 {
 2686:   execsql { CREATE TABLE p(a, b, PRIMARY KEY(a, b)) }
 2687:   catchsql COMMIT
 2688: } {1 {foreign key constraint failed}}
 2689: do_test e_fkey-59.5 {
 2690:   execsql { INSERT INTO p VALUES('a', 'b') }
 2691:   execsql COMMIT
 2692: } {}
 2693: 
 2694: #-------------------------------------------------------------------------
 2695: # Any "foreign key mismatch" errors encountered while running an implicit
 2696: # "DELETE FROM tbl" are ignored.
 2697: #
 2698: # EVIDENCE-OF: R-57242-37005 Any "foreign key mismatch" errors
 2699: # encountered as part of an implicit DELETE are ignored.
 2700: #
 2701: drop_all_tables
 2702: do_test e_fkey-60.1 {
 2703:   execsql {
 2704:     PRAGMA foreign_keys = OFF;
 2705: 
 2706:     CREATE TABLE p(a PRIMARY KEY, b REFERENCES nosuchtable);
 2707:     CREATE TABLE c1(c, d, FOREIGN KEY(c, d) REFERENCES a);
 2708:     CREATE TABLE c2(c REFERENCES p(b), d);
 2709:     CREATE TABLE c3(c REFERENCES p ON DELETE SET NULL, d);
 2710: 
 2711:     INSERT INTO p VALUES(1, 2);
 2712:     INSERT INTO c1 VALUES(1, 2);
 2713:     INSERT INTO c2 VALUES(1, 2);
 2714:     INSERT INTO c3 VALUES(1, 2);
 2715:   }
 2716: } {}
 2717: do_test e_fkey-60.2 {
 2718:   execsql { PRAGMA foreign_keys = ON }
 2719:   catchsql { DELETE FROM p }
 2720: } {1 {no such table: main.nosuchtable}}
 2721: do_test e_fkey-60.3 {
 2722:   execsql {
 2723:     BEGIN;
 2724:       DROP TABLE p;
 2725:       SELECT * FROM c3;
 2726:     ROLLBACK;
 2727:   }
 2728: } {{} 2}
 2729: do_test e_fkey-60.4 {
 2730:   execsql { CREATE TABLE nosuchtable(x PRIMARY KEY) }
 2731:   catchsql { DELETE FROM p }
 2732: } {1 {foreign key mismatch}}
 2733: do_test e_fkey-60.5 {
 2734:   execsql { DROP TABLE c1 }
 2735:   catchsql { DELETE FROM p }
 2736: } {1 {foreign key mismatch}}
 2737: do_test e_fkey-60.6 {
 2738:   execsql { DROP TABLE c2 }
 2739:   execsql { DELETE FROM p }
 2740: } {}
 2741: 
 2742: #-------------------------------------------------------------------------
 2743: # Test that the special behaviours of ALTER and DROP TABLE are only
 2744: # activated when foreign keys are enabled. Special behaviours are:
 2745: #
 2746: #   1. ADD COLUMN not allowing a REFERENCES clause with a non-NULL 
 2747: #      default value.
 2748: #   2. Modifying foreign key definitions when a parent table is RENAMEd.
 2749: #   3. Running an implicit DELETE FROM command as part of DROP TABLE.
 2750: #
 2751: # 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.
 2753: #
 2754: do_test e_fkey-61.1.1 {
 2755:   drop_all_tables
 2756:   execsql { CREATE TABLE t1(a, b) }
 2757:   catchsql { ALTER TABLE t1 ADD COLUMN c DEFAULT 'xxx' REFERENCES t2 }
 2758: } {1 {Cannot add a REFERENCES column with non-NULL default value}}
 2759: do_test e_fkey-61.1.2 {
 2760:   execsql { PRAGMA foreign_keys = OFF }
 2761:   execsql { ALTER TABLE t1 ADD COLUMN c DEFAULT 'xxx' REFERENCES t2 }
 2762:   execsql { SELECT sql FROM sqlite_master WHERE name = 't1' }
 2763: } {{CREATE TABLE t1(a, b, c DEFAULT 'xxx' REFERENCES t2)}}
 2764: do_test e_fkey-61.1.3 {
 2765:   execsql { PRAGMA foreign_keys = ON }
 2766: } {}
 2767: 
 2768: do_test e_fkey-61.2.1 {
 2769:   drop_all_tables
 2770:   execsql {
 2771:     CREATE TABLE p(a UNIQUE);
 2772:     CREATE TABLE c(b REFERENCES p(a));
 2773:     BEGIN;
 2774:       ALTER TABLE p RENAME TO parent;
 2775:       SELECT sql FROM sqlite_master WHERE name = 'c';
 2776:     ROLLBACK;
 2777:   }
 2778: } {{CREATE TABLE c(b REFERENCES "parent"(a))}}
 2779: do_test e_fkey-61.2.2 {
 2780:   execsql {
 2781:     PRAGMA foreign_keys = OFF;
 2782:     ALTER TABLE p RENAME TO parent;
 2783:     SELECT sql FROM sqlite_master WHERE name = 'c';
 2784:   }
 2785: } {{CREATE TABLE c(b REFERENCES p(a))}}
 2786: do_test e_fkey-61.2.3 {
 2787:   execsql { PRAGMA foreign_keys = ON }
 2788: } {}
 2789: 
 2790: do_test e_fkey-61.3.1 {
 2791:   drop_all_tables
 2792:   execsql {
 2793:     CREATE TABLE p(a UNIQUE);
 2794:     CREATE TABLE c(b REFERENCES p(a) ON DELETE SET NULL);
 2795:     INSERT INTO p VALUES('x');
 2796:     INSERT INTO c VALUES('x');
 2797:     BEGIN;
 2798:       DROP TABLE p;
 2799:       SELECT * FROM c;
 2800:     ROLLBACK;
 2801:   }
 2802: } {{}}
 2803: do_test e_fkey-61.3.2 {
 2804:   execsql {
 2805:     PRAGMA foreign_keys = OFF;
 2806:     DROP TABLE p;
 2807:     SELECT * FROM c;
 2808:   }
 2809: } {x}
 2810: do_test e_fkey-61.3.3 {
 2811:   execsql { PRAGMA foreign_keys = ON }
 2812: } {}
 2813: 
 2814: ###########################################################################
 2815: ### SECTION 6: Limits and Unsupported Features
 2816: ###########################################################################
 2817: 
 2818: #-------------------------------------------------------------------------
 2819: # Test that MATCH clauses are parsed, but SQLite treats every foreign key
 2820: # constraint as if it were "MATCH SIMPLE".
 2821: #
 2822: # EVIDENCE-OF: R-24728-13230 SQLite parses MATCH clauses (i.e. does not
 2823: # report a syntax error if you specify one), but does not enforce them.
 2824: #
 2825: # EVIDENCE-OF: R-24450-46174 All foreign key constraints in SQLite are
 2826: # handled as if MATCH SIMPLE were specified.
 2827: #
 2828: foreach zMatch [list SIMPLE PARTIAL FULL Simple parTIAL FuLL ] {
 2829:   drop_all_tables
 2830:   do_test e_fkey-62.$zMatch.1 {
 2831:     execsql "
 2832:       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);
 2834:     "
 2835:   } {}
 2836:   do_test e_fkey-62.$zMatch.2 {
 2837:     execsql { INSERT INTO p VALUES(1, 2, 3)         }
 2838: 
 2839:     # MATCH SIMPLE behaviour: 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
 2841:     # parent key values, so long as at least one field of the child key is
 2842:     # NULL.
 2843:     execsql { INSERT INTO c VALUES('w', 2, 3)       }
 2844:     execsql { INSERT INTO c VALUES('x', 'x', NULL)  }
 2845:     execsql { INSERT INTO c VALUES('y', NULL, 'x')  }
 2846:     execsql { INSERT INTO c VALUES('z', NULL, NULL) }
 2847: 
 2848:     # Check that the FK is enforced properly if there are no NULL values 
 2849:     # in the child key columns.
 2850:     catchsql { INSERT INTO c VALUES('a', 2, 4) }
 2851:   } {1 {foreign key constraint failed}}
 2852: }
 2853: 
 2854: #-------------------------------------------------------------------------
 2855: # Test that SQLite does not support the SET CONSTRAINT statement. And
 2856: # that it is possible to create both immediate and deferred constraints.
 2857: #
 2858: # EVIDENCE-OF: R-21599-16038 In SQLite, a foreign key constraint is
 2859: # permanently marked as deferred or immediate when it is created.
 2860: #
 2861: drop_all_tables
 2862: do_test e_fkey-62.1 {
 2863:   catchsql { SET CONSTRAINTS ALL IMMEDIATE }
 2864: } {1 {near "SET": syntax error}}
 2865: do_test e_fkey-62.2 {
 2866:   catchsql { SET CONSTRAINTS ALL DEFERRED }
 2867: } {1 {near "SET": syntax error}}
 2868: 
 2869: do_test e_fkey-62.3 {
 2870:   execsql {
 2871:     CREATE TABLE p(a, b, PRIMARY KEY(a, b));
 2872:     CREATE TABLE cd(c, d, 
 2873:       FOREIGN KEY(c, d) REFERENCES p DEFERRABLE INITIALLY DEFERRED);
 2874:     CREATE TABLE ci(c, d, 
 2875:       FOREIGN KEY(c, d) REFERENCES p DEFERRABLE INITIALLY IMMEDIATE);
 2876:     BEGIN;
 2877:   }
 2878: } {}
 2879: do_test e_fkey-62.4 {
 2880:   catchsql { INSERT INTO ci VALUES('x', 'y') }
 2881: } {1 {foreign key constraint failed}}
 2882: do_test e_fkey-62.5 {
 2883:   catchsql { INSERT INTO cd VALUES('x', 'y') }
 2884: } {0 {}}
 2885: do_test e_fkey-62.6 {
 2886:   catchsql { COMMIT }
 2887: } {1 {foreign key constraint failed}}
 2888: do_test e_fkey-62.7 {
 2889:   execsql { 
 2890:     DELETE FROM cd;
 2891:     COMMIT;
 2892:   }
 2893: } {}
 2894: 
 2895: #-------------------------------------------------------------------------
 2896: # 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
 2898: # settings.
 2899: #
 2900: # EVIDENCE-OF: R-42264-30503 The SQLITE_MAX_TRIGGER_DEPTH and
 2901: # SQLITE_LIMIT_TRIGGER_DEPTH settings determine the maximum allowable
 2902: # depth of trigger program recursion. For the purposes of these limits,
 2903: # foreign key actions are considered trigger programs.
 2904: #
 2905: proc test_on_delete_recursion {limit} {
 2906:   drop_all_tables
 2907:   execsql { 
 2908:     BEGIN;
 2909:     CREATE TABLE t0(a PRIMARY KEY, b);
 2910:     INSERT INTO t0 VALUES('x0', NULL);
 2911:   }
 2912:   for {set i 1} {$i <= $limit} {incr i} {
 2913:     execsql "
 2914:       CREATE TABLE t$i (
 2915:         a PRIMARY KEY, b REFERENCES t[expr $i-1] ON DELETE CASCADE
 2916:       );
 2917:       INSERT INTO t$i VALUES('x$i', 'x[expr $i-1]');
 2918:     "
 2919:   }
 2920:   execsql COMMIT
 2921:   catchsql "
 2922:     DELETE FROM t0;
 2923:     SELECT count(*) FROM t$limit;
 2924:   "
 2925: }
 2926: proc test_on_update_recursion {limit} {
 2927:   drop_all_tables
 2928:   execsql { 
 2929:     BEGIN;
 2930:     CREATE TABLE t0(a PRIMARY KEY);
 2931:     INSERT INTO t0 VALUES('xxx');
 2932:   }
 2933:   for {set i 1} {$i <= $limit} {incr i} {
 2934:     set j [expr $i-1]
 2935: 
 2936:     execsql "
 2937:       CREATE TABLE t$i (a PRIMARY KEY REFERENCES t$j ON UPDATE CASCADE);
 2938:       INSERT INTO t$i VALUES('xxx');
 2939:     "
 2940:   }
 2941:   execsql COMMIT
 2942:   catchsql "
 2943:     UPDATE t0 SET a = 'yyy';
 2944:     SELECT NOT (a='yyy') FROM t$limit;
 2945:   "
 2946: }
 2947: 
 2948: do_test e_fkey-63.1.1 {
 2949:   test_on_delete_recursion $SQLITE_MAX_TRIGGER_DEPTH
 2950: } {0 0}
 2951: do_test e_fkey-63.1.2 {
 2952:   test_on_delete_recursion [expr $SQLITE_MAX_TRIGGER_DEPTH+1]
 2953: } {1 {too many levels of trigger recursion}}
 2954: do_test e_fkey-63.1.3 {
 2955:   sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 5
 2956:   test_on_delete_recursion 5
 2957: } {0 0}
 2958: do_test e_fkey-63.1.4 {
 2959:   test_on_delete_recursion 6
 2960: } {1 {too many levels of trigger recursion}}
 2961: do_test e_fkey-63.1.5 {
 2962:   sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1000000
 2963: } {5}
 2964: do_test e_fkey-63.2.1 {
 2965:   test_on_update_recursion $SQLITE_MAX_TRIGGER_DEPTH
 2966: } {0 0}
 2967: do_test e_fkey-63.2.2 {
 2968:   test_on_update_recursion [expr $SQLITE_MAX_TRIGGER_DEPTH+1]
 2969: } {1 {too many levels of trigger recursion}}
 2970: do_test e_fkey-63.2.3 {
 2971:   sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 5
 2972:   test_on_update_recursion 5
 2973: } {0 0}
 2974: do_test e_fkey-63.2.4 {
 2975:   test_on_update_recursion 6
 2976: } {1 {too many levels of trigger recursion}}
 2977: do_test e_fkey-63.2.5 {
 2978:   sqlite3_limit db SQLITE_LIMIT_TRIGGER_DEPTH 1000000
 2979: } {5}
 2980: 
 2981: #-------------------------------------------------------------------------
 2982: # The setting of the recursive_triggers pragma does not affect foreign
 2983: # key actions.
 2984: #
 2985: # EVIDENCE-OF: R-51769-32730 The PRAGMA recursive_triggers setting does
 2986: # not not affect the operation of foreign key actions.
 2987: #
 2988: foreach recursive_triggers_setting [list 0 1 ON OFF] {
 2989:   drop_all_tables
 2990:   execsql "PRAGMA recursive_triggers = $recursive_triggers_setting"
 2991: 
 2992:   do_test e_fkey-64.$recursive_triggers_setting.1 {
 2993:     execsql {
 2994:       CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1 ON DELETE CASCADE);
 2995:       INSERT INTO t1 VALUES(1, NULL);
 2996:       INSERT INTO t1 VALUES(2, 1);
 2997:       INSERT INTO t1 VALUES(3, 2);
 2998:       INSERT INTO t1 VALUES(4, 3);
 2999:       INSERT INTO t1 VALUES(5, 4);
 3000:       SELECT count(*) FROM t1;
 3001:     }
 3002:   } {5}
 3003:   do_test e_fkey-64.$recursive_triggers_setting.2 {
 3004:     execsql { SELECT count(*) FROM t1 WHERE a = 1 }
 3005:   } {1}
 3006:   do_test e_fkey-64.$recursive_triggers_setting.3 {
 3007:     execsql { 
 3008:       DELETE FROM t1 WHERE a = 1;
 3009:       SELECT count(*) FROM t1;
 3010:     }
 3011:   } {0}
 3012: }
 3013: 
 3014: finish_test

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>