CoolFace
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
fkey2.test2048 linesDownload Raw Back to test
1# 2009 September 152#3# The author disclaims copyright to this source code.  In place of4# 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# This file implements regression tests for SQLite library.12#13# This file implements tests for foreign keys.14#15 16set testdir [file dirname $argv0]17source $testdir/tester.tcl18 19ifcapable {!foreignkey||!trigger} {20  finish_test21  return22}23 24#-------------------------------------------------------------------------25# Test structure:26#27# fkey2-1.*: Simple tests to check that immediate and deferred foreign key 28#            constraints work when not inside a transaction.29#            30# fkey2-2.*: Tests to verify that deferred foreign keys work inside31#            explicit transactions (i.e that processing really is deferred).32#33# fkey2-3.*: Tests that a statement transaction is rolled back if an34#            immediate foreign key constraint is violated.35#36# fkey2-4.*: Test that FK actions may recurse even when recursive triggers37#            are disabled.38#39# fkey2-5.*: Check that if foreign-keys are enabled, it is not possible40#            to write to an FK column using the incremental blob API.41#42# fkey2-6.*: Test that FK processing is automatically disabled when 43#            running VACUUM.44#45# fkey2-7.*: Test using an IPK as the key in the child (referencing) table.46#47# fkey2-8.*: Test that enabling/disabling foreign key support while a 48#            transaction is active is not possible.49#50# fkey2-9.*: Test SET DEFAULT actions.51#52# fkey2-10.*: Test errors.53#54# fkey2-11.*: Test CASCADE actions.55#56# fkey2-12.*: Test RESTRICT actions.57#58# fkey2-13.*: Test that FK processing is performed when a row is REPLACED by59#             an UPDATE or INSERT statement.60#61# fkey2-14.*: Test the ALTER TABLE and DROP TABLE commands.62#63# fkey2-15.*: Test that if there are no (known) outstanding foreign key 64#             constraint violations in the database, inserting into a parent65#             table or deleting from a child table does not cause SQLite66#             to check if this has repaired an outstanding violation.67#68# fkey2-16.*: Test that rows that refer to themselves may be inserted, 69#             updated and deleted.70#71# fkey2-17.*: Test that the "count_changes" pragma does not interfere with72#             FK constraint processing.73# 74# fkey2-18.*: Test that the authorization callback is invoked when processing75#             FK constraints.76#77# fkey2-20.*: Test that ON CONFLICT clauses specified as part of statements78#             do not affect the operation of FK constraints.79#80# fkey2-genfkey.*: Tests that were used with the shell tool .genfkey81#            command. Recycled to test the built-in implementation.82#83# fkey2-dd08e5.*:  Tests to verify that ticket dd08e5a988d00decc4a543daa8d84#                  has been fixed.85#86 87 88execsql { PRAGMA foreign_keys = on }89 90set FkeySimpleSchema {91  PRAGMA foreign_keys = on;92  CREATE TABLE t1(a PRIMARY KEY, b);93  CREATE TABLE t2(c REFERENCES t1(a) /D/ , d);94 95  CREATE TABLE t3(a PRIMARY KEY, b);96  CREATE TABLE t4(c REFERENCES t3 /D/, d);97 98  CREATE TABLE t7(a, b INTEGER PRIMARY KEY);99  CREATE TABLE t8(c REFERENCES t7 /D/, d);100 101  CREATE TABLE t9(a REFERENCES nosuchtable, b);102  CREATE TABLE t10(a REFERENCES t9(c) /D/, b);103}104 105 106set FkeySimpleTests {107  1.1  "INSERT INTO t2 VALUES(1, 3)"      {1 {FOREIGN KEY constraint failed}}108  1.2  "INSERT INTO t1 VALUES(1, 2)"      {0 {}}109  1.3  "INSERT INTO t2 VALUES(1, 3)"      {0 {}}110  1.4  "INSERT INTO t2 VALUES(2, 4)"      {1 {FOREIGN KEY constraint failed}}111  1.5  "INSERT INTO t2 VALUES(NULL, 4)"   {0 {}}112  1.6  "UPDATE t2 SET c=2 WHERE d=4"      {1 {FOREIGN KEY constraint failed}}113  1.7  "UPDATE t2 SET c=1 WHERE d=4"      {0 {}}114  1.9  "UPDATE t2 SET c=1 WHERE d=4"      {0 {}}115  1.10 "UPDATE t2 SET c=NULL WHERE d=4"   {0 {}}116  1.11 "DELETE FROM t1 WHERE a=1"         {1 {FOREIGN KEY constraint failed}}117  1.12 "UPDATE t1 SET a = 2"              {1 {FOREIGN KEY constraint failed}}118  1.13 "UPDATE t1 SET a = 1"              {0 {}}119 120  2.1  "INSERT INTO t4 VALUES(1, 3)"      {1 {FOREIGN KEY constraint failed}}121  2.2  "INSERT INTO t3 VALUES(1, 2)"      {0 {}}122  2.3  "INSERT INTO t4 VALUES(1, 3)"      {0 {}}123 124  4.1  "INSERT INTO t8 VALUES(1, 3)"      {1 {FOREIGN KEY constraint failed}}125  4.2  "INSERT INTO t7 VALUES(2, 1)"      {0 {}}126  4.3  "INSERT INTO t8 VALUES(1, 3)"      {0 {}}127  4.4  "INSERT INTO t8 VALUES(2, 4)"      {1 {FOREIGN KEY constraint failed}}128  4.5  "INSERT INTO t8 VALUES(NULL, 4)"   {0 {}}129  4.6  "UPDATE t8 SET c=2 WHERE d=4"      {1 {FOREIGN KEY constraint failed}}130  4.7  "UPDATE t8 SET c=1 WHERE d=4"      {0 {}}131  4.9  "UPDATE t8 SET c=1 WHERE d=4"      {0 {}}132  4.10 "UPDATE t8 SET c=NULL WHERE d=4"   {0 {}}133  4.11 "DELETE FROM t7 WHERE b=1"         {1 {FOREIGN KEY constraint failed}}134  4.12 "UPDATE t7 SET b = 2"              {1 {FOREIGN KEY constraint failed}}135  4.13 "UPDATE t7 SET b = 1"              {0 {}}136  4.14 "INSERT INTO t8 VALUES('a', 'b')"  {1 {FOREIGN KEY constraint failed}}137  4.15 "UPDATE t7 SET b = 5"              {1 {FOREIGN KEY constraint failed}}138  4.16 "UPDATE t7 SET rowid = 5"          {1 {FOREIGN KEY constraint failed}}139  4.17 "UPDATE t7 SET a = 10"             {0 {}}140 141  5.1  "INSERT INTO t9 VALUES(1, 3)"      {1 {no such table: main.nosuchtable}}142  5.2  "INSERT INTO t10 VALUES(1, 3)"  143                            {1 {foreign key mismatch - "t10" referencing "t9"}}144}145 146do_test fkey2-1.1.0 {147  execsql [string map {/D/ {}} $FkeySimpleSchema]148} {}149foreach {tn zSql res} $FkeySimpleTests {150  do_test fkey2-1.1.$tn.1 { catchsql $zSql } $res151  do_test fkey2-1.1.$tn.2 { execsql {PRAGMA foreign_key_check(t1)} } {}152  do_test fkey2-1.1.$tn.3 { execsql {PRAGMA foreign_key_check(t2)} } {}153  do_test fkey2-1.1.$tn.4 { execsql {PRAGMA foreign_key_check(t3)} } {}154  do_test fkey2-1.1.$tn.5 { execsql {PRAGMA foreign_key_check(t4)} } {}155  do_test fkey2-1.1.$tn.6 { execsql {PRAGMA foreign_key_check(t7)} } {}156  do_test fkey2-1.1.$tn.7 { execsql {PRAGMA foreign_key_check(t8)} } {}157}158drop_all_tables159 160do_test fkey2-1.2.0 {161  execsql [string map {/D/ {DEFERRABLE INITIALLY DEFERRED}} $FkeySimpleSchema]162} {}163foreach {tn zSql res} $FkeySimpleTests {164  do_test fkey2-1.2.$tn { catchsql $zSql } $res165  do_test fkey2-1.2.$tn.2 { execsql {PRAGMA foreign_key_check(t1)} } {}166  do_test fkey2-1.2.$tn.3 { execsql {PRAGMA foreign_key_check(t2)} } {}167  do_test fkey2-1.2.$tn.4 { execsql {PRAGMA foreign_key_check(t3)} } {}168  do_test fkey2-1.2.$tn.5 { execsql {PRAGMA foreign_key_check(t4)} } {}169  do_test fkey2-1.2.$tn.6 { execsql {PRAGMA foreign_key_check(t7)} } {}170  do_test fkey2-1.2.$tn.7 { execsql {PRAGMA foreign_key_check(t8)} } {}171}172drop_all_tables173 174do_test fkey2-1.3.0 {175  execsql [string map {/D/ {}} $FkeySimpleSchema]176  execsql { PRAGMA count_changes = 1 }177} {}178foreach {tn zSql res} $FkeySimpleTests {179  if {$res == "0 {}"} { set res {0 1} }180  do_test fkey2-1.3.$tn { catchsql $zSql } $res181  do_test fkey2-1.3.$tn.2 { execsql {PRAGMA foreign_key_check(t1)} } {}182  do_test fkey2-1.3.$tn.3 { execsql {PRAGMA foreign_key_check(t2)} } {}183  do_test fkey2-1.3.$tn.4 { execsql {PRAGMA foreign_key_check(t3)} } {}184  do_test fkey2-1.3.$tn.5 { execsql {PRAGMA foreign_key_check(t4)} } {}185  do_test fkey2-1.3.$tn.6 { execsql {PRAGMA foreign_key_check(t7)} } {}186  do_test fkey2-1.3.$tn.7 { execsql {PRAGMA foreign_key_check(t8)} } {}187}188execsql { PRAGMA count_changes = 0 }189drop_all_tables190 191do_test fkey2-1.4.0 {192  execsql [string map {/D/ {}} $FkeySimpleSchema]193  execsql { PRAGMA count_changes = 1 }194} {}195foreach {tn zSql res} $FkeySimpleTests {196  if {$res == "0 {}"} { set res {0 1} }197  execsql BEGIN198  do_test fkey2-1.4.$tn { catchsql $zSql } $res199  execsql COMMIT200}201execsql { PRAGMA count_changes = 0 }202drop_all_tables203 204# Special test: When the parent key is an IPK, make sure the affinity of205# the IPK is not applied to the child key value before it is inserted206# into the child table.207do_test fkey2-1.5.1 {208  execsql {209    CREATE TABLE i(i INTEGER PRIMARY KEY);210    CREATE TABLE j(j REFERENCES i);211    INSERT INTO i VALUES(35);212    INSERT INTO j VALUES('35.0');213    SELECT j, typeof(j) FROM j;214  }215} {35.0 text}216do_test fkey2-1.5.2 {217  catchsql { DELETE FROM i }218} {1 {FOREIGN KEY constraint failed}}219 220# Same test using a regular primary key with integer affinity.221drop_all_tables222do_test fkey2-1.6.1 {223  execsql {224    CREATE TABLE i(i INT UNIQUE);225    CREATE TABLE j(j REFERENCES i(i));226    INSERT INTO i VALUES('35.0');227    INSERT INTO j VALUES('35.0');228    SELECT j, typeof(j) FROM j;229    SELECT i, typeof(i) FROM i;230  }231} {35.0 text 35 integer}232do_test fkey2-1.6.2 {233  catchsql { DELETE FROM i }234} {1 {FOREIGN KEY constraint failed}}235 236# Use a collation sequence on the parent key.237drop_all_tables238do_test fkey2-1.7.1 {239  execsql {240    CREATE TABLE i(i TEXT COLLATE nocase PRIMARY KEY);241    CREATE TABLE j(j TEXT COLLATE binary REFERENCES i(i));242    INSERT INTO i VALUES('SQLite');243    INSERT INTO j VALUES('sqlite');244  }245  catchsql { DELETE FROM i }246} {1 {FOREIGN KEY constraint failed}}247 248# Use the parent key collation even if it is default and the child key249# has an explicit value.250drop_all_tables251do_test fkey2-1.7.2 {252  execsql {253    CREATE TABLE i(i TEXT PRIMARY KEY);        -- Colseq is "BINARY"254    CREATE TABLE j(j TEXT COLLATE nocase REFERENCES i(i));255    INSERT INTO i VALUES('SQLite');256  }257  catchsql { INSERT INTO j VALUES('sqlite') }258} {1 {FOREIGN KEY constraint failed}}259do_test fkey2-1.7.3 {260  execsql {261    INSERT INTO i VALUES('sqlite');262    INSERT INTO j VALUES('sqlite');263    DELETE FROM i WHERE i = 'SQLite';264  }265  catchsql { DELETE FROM i WHERE i = 'sqlite' }266} {1 {FOREIGN KEY constraint failed}}267 268#-------------------------------------------------------------------------269# This section (test cases fkey2-2.*) contains tests to check that the270# deferred foreign key constraint logic works.271#272proc fkey2-2-test {tn nocommit sql {res {}}} {273  if {$res eq "FKV"} {274    set expected {1 {FOREIGN KEY constraint failed}}275  } else {276    set expected [list 0 $res]277  }278  do_test fkey2-2.$tn [list catchsql $sql] $expected279  if {$nocommit} {280    do_test fkey2-2.${tn}c {281      catchsql COMMIT282    } {1 {FOREIGN KEY constraint failed}}283  }284}285 286fkey2-2-test 1 0 {287  CREATE TABLE node(288    nodeid PRIMARY KEY,289    parent REFERENCES node DEFERRABLE INITIALLY DEFERRED290  );291  CREATE TABLE leaf(292    cellid PRIMARY KEY,293    parent REFERENCES node DEFERRABLE INITIALLY DEFERRED294  );295}296 297fkey2-2-test 1  0 "INSERT INTO node VALUES(1, 0)"       FKV298fkey2-2-test 2  0 "BEGIN"299fkey2-2-test 3  1   "INSERT INTO node VALUES(1, 0)"300fkey2-2-test 4  0   "UPDATE node SET parent = NULL"301fkey2-2-test 5  0 "COMMIT"302fkey2-2-test 6  0 "SELECT * FROM node" {1 {}}303 304fkey2-2-test 7  0 "BEGIN"305fkey2-2-test 8  1   "INSERT INTO leaf VALUES('a', 2)"306fkey2-2-test 9  1   "INSERT INTO node VALUES(2, 0)"307fkey2-2-test 10 0   "UPDATE node SET parent = 1 WHERE nodeid = 2"308fkey2-2-test 11 0 "COMMIT"309fkey2-2-test 12 0 "SELECT * FROM node" {1 {} 2 1}310fkey2-2-test 13 0 "SELECT * FROM leaf" {a 2}311 312fkey2-2-test 14 0 "BEGIN"313fkey2-2-test 15 1   "DELETE FROM node WHERE nodeid = 2"314fkey2-2-test 16 0   "INSERT INTO node VALUES(2, NULL)"315fkey2-2-test 17 0 "COMMIT"316fkey2-2-test 18 0 "SELECT * FROM node" {1 {} 2 {}}317fkey2-2-test 19 0 "SELECT * FROM leaf" {a 2}318 319fkey2-2-test 20 0 "BEGIN"320fkey2-2-test 21 0   "INSERT INTO leaf VALUES('b', 1)"321fkey2-2-test 22 0   "SAVEPOINT save"322fkey2-2-test 23 0     "DELETE FROM node WHERE nodeid = 1"323fkey2-2-test 24 0   "ROLLBACK TO save"324fkey2-2-test 25 0 "COMMIT"325fkey2-2-test 26 0 "SELECT * FROM node" {1 {} 2 {}}326fkey2-2-test 27 0 "SELECT * FROM leaf" {a 2 b 1}327 328fkey2-2-test 28 0 "BEGIN"329fkey2-2-test 29 0   "INSERT INTO leaf VALUES('c', 1)"330fkey2-2-test 30 0   "SAVEPOINT save"331fkey2-2-test 31 0     "DELETE FROM node WHERE nodeid = 1"332fkey2-2-test 32 1   "RELEASE save"333fkey2-2-test 33 1   "DELETE FROM leaf WHERE cellid = 'b'"334fkey2-2-test 34 0   "DELETE FROM leaf WHERE cellid = 'c'"335fkey2-2-test 35 0 "COMMIT"336fkey2-2-test 36 0 "SELECT * FROM node" {2 {}} 337fkey2-2-test 37 0 "SELECT * FROM leaf" {a 2}338 339fkey2-2-test 38 0 "SAVEPOINT outer"340fkey2-2-test 39 1   "INSERT INTO leaf VALUES('d', 3)"341fkey2-2-test 40 1 "RELEASE outer"    FKV342fkey2-2-test 41 1   "INSERT INTO leaf VALUES('e', 3)"343fkey2-2-test 42 0   "INSERT INTO node VALUES(3, 2)"344fkey2-2-test 43 0 "RELEASE outer"345 346fkey2-2-test 44 0 "SAVEPOINT outer"347fkey2-2-test 45 1   "DELETE FROM node WHERE nodeid=3"348fkey2-2-test 47 0   "INSERT INTO node VALUES(3, 2)"349fkey2-2-test 48 0 "ROLLBACK TO outer"350fkey2-2-test 49 0 "RELEASE outer"351 352fkey2-2-test 50 0 "SAVEPOINT outer"353fkey2-2-test 51 1   "INSERT INTO leaf VALUES('f', 4)"354fkey2-2-test 52 1   "SAVEPOINT inner"355fkey2-2-test 53 1     "INSERT INTO leaf VALUES('g', 4)"356fkey2-2-test 54 1  "RELEASE outer"   FKV357fkey2-2-test 55 1   "ROLLBACK TO inner"358fkey2-2-test 56 0  "COMMIT"          FKV359fkey2-2-test 57 0   "INSERT INTO node VALUES(4, NULL)"360fkey2-2-test 58 0 "RELEASE outer"361fkey2-2-test 59 0 "SELECT * FROM node" {2 {} 3 2 4 {}}362fkey2-2-test 60 0 "SELECT * FROM leaf" {a 2 d 3 e 3 f 4}363 364# The following set of tests check that if a statement that affects 365# multiple rows violates some foreign key constraints, then strikes a 366# constraint that causes the statement-transaction to be rolled back, 367# the deferred constraint counter is correctly reset to the value it 368# had before the statement-transaction was opened.369#370fkey2-2-test 61 0 "BEGIN"371fkey2-2-test 62 0   "DELETE FROM leaf"372fkey2-2-test 63 0   "DELETE FROM node"373fkey2-2-test 64 1   "INSERT INTO leaf VALUES('a', 1)"374fkey2-2-test 65 1   "INSERT INTO leaf VALUES('b', 2)"375fkey2-2-test 66 1   "INSERT INTO leaf VALUES('c', 1)"376do_test fkey2-2-test-67 {377  catchsql          "INSERT INTO node SELECT parent, 3 FROM leaf"378} {1 {UNIQUE constraint failed: node.nodeid}}379fkey2-2-test 68 0 "COMMIT"           FKV380fkey2-2-test 69 1   "INSERT INTO node VALUES(1, NULL)"381fkey2-2-test 70 0   "INSERT INTO node VALUES(2, NULL)"382fkey2-2-test 71 0 "COMMIT"383 384fkey2-2-test 72 0 "BEGIN"385fkey2-2-test 73 1   "DELETE FROM node"386fkey2-2-test 74 0   "INSERT INTO node(nodeid) SELECT DISTINCT parent FROM leaf"387fkey2-2-test 75 0 "COMMIT"388 389#-------------------------------------------------------------------------390# Test cases fkey2-3.* test that a program that executes foreign key391# actions (CASCADE, SET DEFAULT, SET NULL etc.) or tests FK constraints392# opens a statement transaction if required.393#394# fkey2-3.1.*: Test UPDATE statements.395# fkey2-3.2.*: Test DELETE statements.396#397drop_all_tables398do_test fkey2-3.1.1 {399  execsql {400    CREATE TABLE ab(a PRIMARY KEY, b);401    CREATE TABLE cd(402      c PRIMARY KEY REFERENCES ab ON UPDATE CASCADE ON DELETE CASCADE, 403      d404    );405    CREATE TABLE ef(406      e REFERENCES cd ON UPDATE CASCADE, 407      f, CHECK (e!=5)408    );409  }410} {}411do_test fkey2-3.1.2 {412  execsql {413    INSERT INTO ab VALUES(1, 'b');414    INSERT INTO cd VALUES(1, 'd');415    INSERT INTO ef VALUES(1, 'e');416  }417} {}418do_test fkey2-3.1.3 {419  catchsql { UPDATE ab SET a = 5 }420} {1 {CHECK constraint failed: e!=5}}421do_test fkey2-3.1.4 {422  execsql { SELECT * FROM ab }423} {1 b}424do_test fkey2-3.1.4 {425  execsql BEGIN;426  catchsql { UPDATE ab SET a = 5 }427} {1 {CHECK constraint failed: e!=5}}428do_test fkey2-3.1.5 {429  execsql COMMIT;430  execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef }431} {1 b 1 d 1 e}432 433do_test fkey2-3.2.1 {434  execsql BEGIN;435  catchsql { DELETE FROM ab }436} {1 {FOREIGN KEY constraint failed}}437do_test fkey2-3.2.2 {438  execsql COMMIT439  execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef }440} {1 b 1 d 1 e}441 442#-------------------------------------------------------------------------443# Test cases fkey2-4.* test that recursive foreign key actions 444# (i.e. CASCADE) are allowed even if recursive triggers are disabled.445#446drop_all_tables447do_test fkey2-4.1 {448  execsql {449    CREATE TABLE t1(450      node PRIMARY KEY, 451      parent REFERENCES t1 ON DELETE CASCADE452    );453    CREATE TABLE t2(node PRIMARY KEY, parent);454    CREATE TRIGGER t2t AFTER DELETE ON t2 BEGIN455      DELETE FROM t2 WHERE parent = old.node;456    END;457    INSERT INTO t1 VALUES(1, NULL);458    INSERT INTO t1 VALUES(2, 1);459    INSERT INTO t1 VALUES(3, 1);460    INSERT INTO t1 VALUES(4, 2);461    INSERT INTO t1 VALUES(5, 2);462    INSERT INTO t1 VALUES(6, 3);463    INSERT INTO t1 VALUES(7, 3);464    INSERT INTO t2 SELECT * FROM t1;465  }466} {}467do_test fkey2-4.2 {468  execsql { PRAGMA recursive_triggers = off }469  execsql { 470    BEGIN;471      DELETE FROM t1 WHERE node = 1;472      SELECT node FROM t1;473  }474} {}475do_test fkey2-4.3 {476  execsql { 477      DELETE FROM t2 WHERE node = 1;478      SELECT node FROM t2;479    ROLLBACK;480  }481} {4 5 6 7}482do_test fkey2-4.4 {483  execsql { PRAGMA recursive_triggers = on }484  execsql { 485    BEGIN;486      DELETE FROM t1 WHERE node = 1;487      SELECT node FROM t1;488  }489} {}490do_test fkey2-4.3 {491  execsql { 492      DELETE FROM t2 WHERE node = 1;493      SELECT node FROM t2;494    ROLLBACK;495  }496} {}497 498#-------------------------------------------------------------------------499# Test cases fkey2-5.* verify that the incremental blob API may not500# write to a foreign key column while foreign-keys are enabled.501#502drop_all_tables503ifcapable incrblob {504  do_test fkey2-5.1 {505    execsql {506      CREATE TABLE t1(a PRIMARY KEY, b);507      CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1(a));508      INSERT INTO t1 VALUES('hello', 'world');509      INSERT INTO t2 VALUES('key', 'hello');510    }511  } {}512  do_test fkey2-5.2 {513    set rc [catch { set fd [db incrblob t2 b 1] } msg]514    list $rc $msg515  } {1 {cannot open foreign key column for writing}}516  do_test fkey2-5.3 {517    set rc [catch { set fd [db incrblob -readonly t2 b 1] } msg]518    close $fd519    set rc520  } {0}521  do_test fkey2-5.4 {522    execsql { PRAGMA foreign_keys = off }523    set rc [catch { set fd [db incrblob t2 b 1] } msg]524    close $fd525    set rc526  } {0}527  do_test fkey2-5.5 {528    execsql { PRAGMA foreign_keys = on }529  } {}530}531 532drop_all_tables533ifcapable vacuum {534  do_test fkey2-6.1 {535    execsql {536      CREATE TABLE t1(a REFERENCES t2(c), b);537      CREATE TABLE t2(c UNIQUE, b);538      INSERT INTO t2 VALUES(1, 2);539      INSERT INTO t1 VALUES(1, 2);540      VACUUM;541    }542  } {}543}544 545#-------------------------------------------------------------------------546# Test that it is possible to use an INTEGER PRIMARY KEY as the child key547# of a foreign constraint.548# 549drop_all_tables550do_test fkey2-7.1 {551  execsql {552    CREATE TABLE t1(a PRIMARY KEY, b);553    CREATE TABLE t2(c INTEGER PRIMARY KEY REFERENCES t1, b);554  }555} {}556do_test fkey2-7.2 {557  catchsql { INSERT INTO t2 VALUES(1, 'A'); }558} {1 {FOREIGN KEY constraint failed}}559do_test fkey2-7.3 {560  execsql { 561    INSERT INTO t1 VALUES(1, 2);562    INSERT INTO t1 VALUES(2, 3);563    INSERT INTO t2 VALUES(1, 'A');564  }565} {}566do_test fkey2-7.4 {567  execsql { UPDATE t2 SET c = 2 }568} {}569do_test fkey2-7.5 {570  catchsql { UPDATE t2 SET c = 3 }571} {1 {FOREIGN KEY constraint failed}}572do_test fkey2-7.6 {573  catchsql { DELETE FROM t1 WHERE a = 2 }574} {1 {FOREIGN KEY constraint failed}}575do_test fkey2-7.7 {576  execsql { DELETE FROM t1 WHERE a = 1 }577} {}578do_test fkey2-7.8 {579  catchsql { UPDATE t1 SET a = 3 }580} {1 {FOREIGN KEY constraint failed}}581do_test fkey2-7.9 {582  catchsql { UPDATE t2 SET rowid = 3 }583} {1 {FOREIGN KEY constraint failed}}584 585#-------------------------------------------------------------------------586# Test that it is not possible to enable/disable FK support while a587# transaction is open.588# 589drop_all_tables590proc fkey2-8-test {tn zSql value} {591  do_test fkey-2.8.$tn.1 [list execsql $zSql] {}592  do_test fkey-2.8.$tn.2 { execsql "PRAGMA foreign_keys" } $value593}594fkey2-8-test  1 { PRAGMA foreign_keys = 0     } 0595fkey2-8-test  2 { PRAGMA foreign_keys = 1     } 1596fkey2-8-test  3 { BEGIN                       } 1597fkey2-8-test  4 { PRAGMA foreign_keys = 0     } 1598fkey2-8-test  5 { COMMIT                      } 1599fkey2-8-test  6 { PRAGMA foreign_keys = 0     } 0600fkey2-8-test  7 { BEGIN                       } 0601fkey2-8-test  8 { PRAGMA foreign_keys = 1     } 0602fkey2-8-test  9 { COMMIT                      } 0603fkey2-8-test 10 { PRAGMA foreign_keys = 1     } 1604fkey2-8-test 11 { PRAGMA foreign_keys = off   } 0605fkey2-8-test 12 { PRAGMA foreign_keys = on    } 1606fkey2-8-test 13 { PRAGMA foreign_keys = no    } 0607fkey2-8-test 14 { PRAGMA foreign_keys = yes   } 1608fkey2-8-test 15 { PRAGMA foreign_keys = false } 0609fkey2-8-test 16 { PRAGMA foreign_keys = true  } 1610 611#-------------------------------------------------------------------------612# The following tests, fkey2-9.*, test SET DEFAULT actions.613#614drop_all_tables615do_test fkey2-9.1.1 {616  execsql {617    CREATE TABLE t1(a INTEGER PRIMARY KEY, b);618    CREATE TABLE t2(619      c INTEGER PRIMARY KEY,620      d INTEGER DEFAULT 1 REFERENCES t1 ON DELETE SET DEFAULT621    );622    DELETE FROM t1;623  }624} {}625do_test fkey2-9.1.2 {626  execsql {627    INSERT INTO t1 VALUES(1, 'one');628    INSERT INTO t1 VALUES(2, 'two');629    INSERT INTO t2 VALUES(1, 2);630    SELECT * FROM t2;631    DELETE FROM t1 WHERE a = 2;632    SELECT * FROM t2;633  }634} {1 2 1 1}635do_test fkey2-9.1.3 {636  execsql {637    INSERT INTO t1 VALUES(2, 'two');638    UPDATE t2 SET d = 2;639    DELETE FROM t1 WHERE a = 1;640    SELECT * FROM t2;641  }642} {1 2}643do_test fkey2-9.1.4 {644  execsql { SELECT * FROM t1 }645} {2 two}646do_test fkey2-9.1.5 {647  catchsql { DELETE FROM t1 }648} {1 {FOREIGN KEY constraint failed}}649 650do_test fkey2-9.2.1 {651  execsql {652    CREATE TABLE pp(a, b, c, PRIMARY KEY(b, c));653    CREATE TABLE cc(d DEFAULT 3, e DEFAULT 1, f DEFAULT 2,654        FOREIGN KEY(f, d) REFERENCES pp 655        ON UPDATE SET DEFAULT 656        ON DELETE SET NULL657    );658    INSERT INTO pp VALUES(1, 2, 3);659    INSERT INTO pp VALUES(4, 5, 6);660    INSERT INTO pp VALUES(7, 8, 9);661  }662} {}663do_test fkey2-9.2.2 {664  execsql {665    INSERT INTO cc VALUES(6, 'A', 5);666    INSERT INTO cc VALUES(6, 'B', 5);667    INSERT INTO cc VALUES(9, 'A', 8);668    INSERT INTO cc VALUES(9, 'B', 8);669    UPDATE pp SET b = 1 WHERE a = 7;670    SELECT * FROM cc;671  }672} {6 A 5 6 B 5 3 A 2 3 B 2}673do_test fkey2-9.2.3 {674  execsql {675    DELETE FROM pp WHERE a = 4;676    SELECT * FROM cc;677  }678} {{} A {} {} B {} 3 A 2 3 B 2}679do_execsql_test fkey2-9.3.0 {680  CREATE TABLE t3(x PRIMARY KEY REFERENCES t3 ON DELETE SET NULL);681  INSERT INTO t3(x) VALUES(12345);682  DROP TABLE t3;683} {}684 685#-------------------------------------------------------------------------686# The following tests, fkey2-10.*, test "foreign key mismatch" and 687# other errors.688#689set tn 0690foreach zSql [list {691  CREATE TABLE p(a PRIMARY KEY, b);692  CREATE TABLE c(x REFERENCES p(c));693} {694  CREATE TABLE c(x REFERENCES v(y));695  CREATE VIEW v AS SELECT x AS y FROM c;696} {697  CREATE TABLE p(a, b, PRIMARY KEY(a, b));698  CREATE TABLE c(x REFERENCES p);699} {700  CREATE TABLE p(a COLLATE binary, b);701  CREATE UNIQUE INDEX i ON p(a COLLATE nocase);702  CREATE TABLE c(x REFERENCES p(a));703}] {704  drop_all_tables705  do_test fkey2-10.1.[incr tn] {706    execsql $zSql707    catchsql { INSERT INTO c DEFAULT VALUES }708  } {/1 {foreign key mismatch - "c" referencing "."}/}709}710 711# "rowid" cannot be used as part of a child or parent key definition 712# unless it happens to be the name of an explicitly declared column.713#714do_test fkey2-10.2.1 {715  drop_all_tables716  catchsql {717    CREATE TABLE t1(a PRIMARY KEY, b);718    CREATE TABLE t2(c, d, FOREIGN KEY(rowid) REFERENCES t1(a));719  }720} {1 {unknown column "rowid" in foreign key definition}}721do_test fkey2-10.2.2 {722  drop_all_tables723  catchsql {724    CREATE TABLE t1(a PRIMARY KEY, b);725    CREATE TABLE t2(rowid, d, FOREIGN KEY(rowid) REFERENCES t1(a));726  }727} {0 {}}728do_test fkey2-10.2.1 {729  drop_all_tables730  catchsql {731    CREATE TABLE t1(a, b);732    CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(rowid));733    INSERT INTO t1(rowid, a, b) VALUES(1, 1, 1);734    INSERT INTO t2 VALUES(1, 1);735  }736} {1 {foreign key mismatch - "t2" referencing "t1"}}737do_test fkey2-10.2.2 {738  drop_all_tables739  catchsql {740    CREATE TABLE t1(rowid PRIMARY KEY, b);741    CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(rowid));742    INSERT INTO t1(rowid, b) VALUES(1, 1);743    INSERT INTO t2 VALUES(1, 1);744  }745} {0 {}}746 747 748#-------------------------------------------------------------------------749# The following tests, fkey2-11.*, test CASCADE actions.750#751drop_all_tables752do_test fkey2-11.1.1 {753  execsql {754    CREATE TABLE t1(a INTEGER PRIMARY KEY, b, rowid, _rowid_, oid);755    CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(a) ON UPDATE CASCADE);756 757    INSERT INTO t1 VALUES(10, 100, 'abc', 'def', 'ghi');758    INSERT INTO t2 VALUES(10, 100);759    UPDATE t1 SET a = 15;760    SELECT * FROM t2;761  }762} {15 100}763 764#-------------------------------------------------------------------------765# The following tests, fkey2-12.*, test RESTRICT actions.766#767drop_all_tables768do_test fkey2-12.1.1 {769  execsql {770    CREATE TABLE t1(a, b PRIMARY KEY);771    CREATE TABLE t2(772      x REFERENCES t1 ON UPDATE RESTRICT DEFERRABLE INITIALLY DEFERRED 773    );774    INSERT INTO t1 VALUES(1, 'one');775    INSERT INTO t1 VALUES(2, 'two');776    INSERT INTO t1 VALUES(3, 'three');777  }778} {}779do_test fkey2-12.1.2 { 780  execsql "BEGIN"781  execsql "INSERT INTO t2 VALUES('two')"782} {}783do_test fkey2-12.1.3 { 784  execsql "UPDATE t1 SET b = 'four' WHERE b = 'one'"785} {}786do_test fkey2-12.1.4 { 787  catchsql "UPDATE t1 SET b = 'five' WHERE b = 'two'"788} {1 {FOREIGN KEY constraint failed}}789do_test fkey2-12.1.5 { 790  execsql "DELETE FROM t1 WHERE b = 'two'"791} {}792do_test fkey2-12.1.6 { 793  catchsql "COMMIT"794} {1 {FOREIGN KEY constraint failed}}795do_test fkey2-12.1.7 { 796  execsql {797    INSERT INTO t1 VALUES(2, 'two');798    COMMIT;799  }800} {}801 802drop_all_tables803do_test fkey2-12.2.1 {804  execsql {805    CREATE TABLE t1(x COLLATE NOCASE PRIMARY KEY);806    CREATE TRIGGER tt1 AFTER DELETE ON t1 807      WHEN EXISTS ( SELECT 1 FROM t2 WHERE old.x = y )808    BEGIN809      INSERT INTO t1 VALUES(old.x);810    END;811    CREATE TABLE t2(y REFERENCES t1);812    INSERT INTO t1 VALUES('A');813    INSERT INTO t1 VALUES('B');814    INSERT INTO t2 VALUES('a');815    INSERT INTO t2 VALUES('b');816 817    SELECT * FROM t1;818    SELECT * FROM t2;819  }820} {A B a b}821do_test fkey2-12.2.2 {822  execsql { DELETE FROM t1 }823  execsql {824    SELECT * FROM t1;825    SELECT * FROM t2;826  }827} {A B a b}828do_test fkey2-12.2.3 {829  execsql {830    DROP TABLE t2;831    CREATE TABLE t2(y REFERENCES t1 ON DELETE RESTRICT);832    INSERT INTO t2 VALUES('a');833    INSERT INTO t2 VALUES('b');834  }835  catchsql { DELETE FROM t1 }836} {1 {FOREIGN KEY constraint failed}}837do_test fkey2-12.2.4 {838  execsql {839    SELECT * FROM t1;840    SELECT * FROM t2;841  }842} {A B a b}843 844drop_all_tables845do_test fkey2-12.3.1 {846  execsql {847    CREATE TABLE up(848      c00, c01, c02, c03, c04, c05, c06, c07, c08, c09,849      c10, c11, c12, c13, c14, c15, c16, c17, c18, c19,850      c20, c21, c22, c23, c24, c25, c26, c27, c28, c29,851      c30, c31, c32, c33, c34, c35, c36, c37, c38, c39,852      PRIMARY KEY(c34, c35)853    );854    CREATE TABLE down(855      c00, c01, c02, c03, c04, c05, c06, c07, c08, c09,856      c10, c11, c12, c13, c14, c15, c16, c17, c18, c19,857      c20, c21, c22, c23, c24, c25, c26, c27, c28, c29,858      c30, c31, c32, c33, c34, c35, c36, c37, c38, c39,859      FOREIGN KEY(c39, c38) REFERENCES up ON UPDATE CASCADE860    );861  }862} {}863do_test fkey2-12.3.2 {864  execsql {865    INSERT INTO up(c34, c35) VALUES('yes', 'no');866    INSERT INTO down(c39, c38) VALUES('yes', 'no');867    UPDATE up SET c34 = 'possibly';868    SELECT c38, c39 FROM down;869    DELETE FROM down;870  }871} {no possibly}872do_test fkey2-12.3.3 {873  catchsql { INSERT INTO down(c39, c38) VALUES('yes', 'no') }874} {1 {FOREIGN KEY constraint failed}}875do_test fkey2-12.3.4 {876  execsql { 877    INSERT INTO up(c34, c35) VALUES('yes', 'no');878    INSERT INTO down(c39, c38) VALUES('yes', 'no');879  }880  catchsql { DELETE FROM up WHERE c34 = 'yes' }881} {1 {FOREIGN KEY constraint failed}}882do_test fkey2-12.3.5 {883  execsql { 884    DELETE FROM up WHERE c34 = 'possibly';885    SELECT c34, c35 FROM up;886    SELECT c39, c38 FROM down;887  }888} {yes no yes no}889 890#-------------------------------------------------------------------------891# The following tests, fkey2-13.*, test that FK processing is performed892# when rows are REPLACEd.893#894drop_all_tables895do_test fkey2-13.1.1 {896  execsql {897    CREATE TABLE pp(a UNIQUE, b, c, PRIMARY KEY(b, c));898    CREATE TABLE cc(d, e, f UNIQUE, FOREIGN KEY(d, e) REFERENCES pp);899    INSERT INTO pp VALUES(1, 2, 3);900    INSERT INTO cc VALUES(2, 3, 1);901  }902} {}903foreach {tn stmt} {904  1   "REPLACE INTO pp VALUES(1, 4, 5)"905  2   "REPLACE INTO pp(rowid, a, b, c) VALUES(1, 2, 3, 4)"906} {907  do_test fkey2-13.1.$tn.1 {908    catchsql $stmt909  } {1 {FOREIGN KEY constraint failed}}910  do_test fkey2-13.1.$tn.2 {911    execsql {912      SELECT * FROM pp;913      SELECT * FROM cc;914    }915  } {1 2 3 2 3 1}916  do_test fkey2-13.1.$tn.3 {917    execsql BEGIN;918    catchsql $stmt919  } {1 {FOREIGN KEY constraint failed}}920  do_test fkey2-13.1.$tn.4 {921    execsql {922      COMMIT;923      SELECT * FROM pp;924      SELECT * FROM cc;925    }926  } {1 2 3 2 3 1}927}928do_test fkey2-13.1.3 {929  execsql { 930    REPLACE INTO pp(rowid, a, b, c) VALUES(1, 2, 2, 3);931    SELECT rowid, * FROM pp;932    SELECT * FROM cc;933  }934} {1 2 2 3 2 3 1}935do_test fkey2-13.1.4 {936  execsql { 937    REPLACE INTO pp(rowid, a, b, c) VALUES(2, 2, 2, 3);938    SELECT rowid, * FROM pp;939    SELECT * FROM cc;940  }941} {2 2 2 3 2 3 1}942 943#-------------------------------------------------------------------------944# The following tests, fkey2-14.*, test that the "DROP TABLE" and "ALTER945# TABLE" commands work as expected wrt foreign key constraints.946#947# fkey2-14.1*: ALTER TABLE ADD COLUMN948# fkey2-14.2*: ALTER TABLE RENAME TABLE949# fkey2-14.3*: DROP TABLE950#951drop_all_tables952ifcapable altertable {953  do_test fkey2-14.1.1 {954    # Adding a column with a REFERENCES clause is not supported.955    execsql { 956      CREATE TABLE t1(a PRIMARY KEY);957      CREATE TABLE t2(a, b);958      INSERT INTO t2 VALUES(1,2);959    }960    catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }961  } {0 {}}962  do_test fkey2-14.1.2 {963    catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }964  } {0 {}}965  do_test fkey2-14.1.3 {966    catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}967  } {0 {}}968  do_test fkey2-14.1.4 {969    catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'}970  } {1 {Cannot add a REFERENCES column with non-NULL default value}}971  do_test fkey2-14.1.5 {972    catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 }973  } {1 {Cannot add a REFERENCES column with non-NULL default value}}974  do_test fkey2-14.1.6 {975    execsql { 976      PRAGMA foreign_keys = off;977      ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;978      PRAGMA foreign_keys = on;979      SELECT sql FROM sqlite_master WHERE name='t2';980    }981  } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}982  983  984  # Test the sqlite_rename_parent() function directly.985  #986  proc test_rename_parent {zCreate zOld zNew} {987    db eval {SELECT sqlite_rename_table(988        'main', 'table', 't1', $zCreate, $zOld, $zNew, 0989    )}990  }991  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db992  do_test fkey2-14.2.1.1 {993    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3994  } {{CREATE TABLE t1(a REFERENCES "t3")}}995  do_test fkey2-14.2.1.2 {996    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3997  } {{CREATE TABLE t1(a REFERENCES t2)}}998  do_test fkey2-14.2.1.3 {999    test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t31000  } {{CREATE TABLE t1(a REFERENCES "t3")}}1001  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db1002  1003  # Test ALTER TABLE RENAME TABLE a bit.1004  #1005  do_test fkey2-14.2.2.1 {1006    drop_all_tables1007    execsql {1008      CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1);1009      CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2);1010      CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);1011    }1012    execsql { SELECT sql FROM sqlite_master WHERE type = 'table'}1013  } [list \1014    {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1)}                     \1015    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)}    \1016    {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)}  \1017  ]1018  do_test fkey2-14.2.2.2 {1019    execsql { ALTER TABLE t1 RENAME TO t4 }1020    execsql { SELECT sql FROM sqlite_master WHERE type = 'table'}1021  } [list \1022    {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4")}                    \1023    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)}     \1024    {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \1025  ]1026  do_test fkey2-14.2.2.3 {1027    catchsql { INSERT INTO t3 VALUES(1, 2, 3) }1028  } {1 {FOREIGN KEY constraint failed}}1029  do_test fkey2-14.2.2.4 {1030    execsql { INSERT INTO t4 VALUES(1, NULL) }1031  } {}1032  do_test fkey2-14.2.2.5 {1033    catchsql { UPDATE t4 SET b = 5 }1034  } {1 {FOREIGN KEY constraint failed}}1035  do_test fkey2-14.2.2.6 {1036    catchsql { UPDATE t4 SET b = 1 }1037  } {0 {}}1038  do_test fkey2-14.2.2.7 {1039    execsql { INSERT INTO t3 VALUES(1, NULL, 1) }1040  } {}1041 1042  # Repeat for TEMP tables1043  #1044  drop_all_tables1045  do_test fkey2-14.1tmp.1 {1046    # Adding a column with a REFERENCES clause is not supported.1047    execsql { 1048      CREATE TEMP TABLE t1(a PRIMARY KEY);1049      CREATE TEMP TABLE t2(a, b);1050      INSERT INTO temp.t2 VALUES(1,2);1051    }1052    catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }1053  } {0 {}}1054  do_test fkey2-14.1tmp.2 {1055    catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }1056  } {0 {}}1057  do_test fkey2-14.1tmp.3 {1058    catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}1059  } {0 {}}1060  do_test fkey2-14.1tmp.4 {1061    catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'}1062  } {1 {Cannot add a REFERENCES column with non-NULL default value}}1063  do_test fkey2-14.1tmp.5 {1064    catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 }1065  } {1 {Cannot add a REFERENCES column with non-NULL default value}}1066  do_test fkey2-14.1tmp.6 {1067    execsql { 1068      PRAGMA foreign_keys = off;1069      ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;1070      PRAGMA foreign_keys = on;1071      SELECT sql FROM temp.sqlite_master WHERE name='t2';1072    }1073  } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}1074 1075  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db1076  do_test fkey2-14.2tmp.1.1 {1077    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t31078  } {{CREATE TABLE t1(a REFERENCES "t3")}}1079  do_test fkey2-14.2tmp.1.2 {1080    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t31081  } {{CREATE TABLE t1(a REFERENCES t2)}}1082  do_test fkey2-14.2tmp.1.3 {1083    test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t31084  } {{CREATE TABLE t1(a REFERENCES "t3")}}1085  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db1086  1087  # Test ALTER TABLE RENAME TABLE a bit.1088  #1089  do_test fkey2-14.2tmp.2.1 {1090    drop_all_tables1091    execsql {1092      CREATE TEMP TABLE t1(a PRIMARY KEY, b REFERENCES t1);1093      CREATE TEMP TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2);1094      CREATE TEMP TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);1095    }1096    execsql { SELECT sql FROM sqlite_temp_master WHERE type = 'table'}1097  } [list \1098    {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1)}                     \1099    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)}    \1100    {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)}  \1101  ]1102  do_test fkey2-14.2tmp.2.2 {1103    execsql { ALTER TABLE t1 RENAME TO t4 }1104    execsql { SELECT sql FROM temp.sqlite_master WHERE type = 'table'}1105  } [list \1106    {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4")}                    \1107    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)}     \1108    {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \1109  ]1110  do_test fkey2-14.2tmp.2.3 {1111    catchsql { INSERT INTO t3 VALUES(1, 2, 3) }1112  } {1 {FOREIGN KEY constraint failed}}1113  do_test fkey2-14.2tmp.2.4 {1114    execsql { INSERT INTO t4 VALUES(1, NULL) }1115  } {}1116  do_test fkey2-14.2tmp.2.5 {1117    catchsql { UPDATE t4 SET b = 5 }1118  } {1 {FOREIGN KEY constraint failed}}1119  do_test fkey2-14.2tmp.2.6 {1120    catchsql { UPDATE t4 SET b = 1 }1121  } {0 {}}1122  do_test fkey2-14.2tmp.2.7 {1123    execsql { INSERT INTO t3 VALUES(1, NULL, 1) }1124  } {}1125 1126  # Repeat for ATTACH-ed tables1127  #1128  drop_all_tables1129  do_test fkey2-14.1aux.1 {1130    # Adding a column with a REFERENCES clause is not supported.1131    execsql { 1132      ATTACH ':memory:' AS aux;1133      CREATE TABLE aux.t1(a PRIMARY KEY);1134      CREATE TABLE aux.t2(a, b);1135      INSERT INTO aux.t2(a,b) VALUES(1,2);1136    }1137    catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }1138  } {0 {}}1139  do_test fkey2-14.1aux.2 {1140    catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }1141  } {0 {}}1142  do_test fkey2-14.1aux.3 {1143    catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}1144  } {0 {}}1145  do_test fkey2-14.1aux.4 {1146    catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'}1147  } {1 {Cannot add a REFERENCES column with non-NULL default value}}1148  do_test fkey2-14.1aux.5 {1149    catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 }1150  } {1 {Cannot add a REFERENCES column with non-NULL default value}}1151  do_test fkey2-14.1aux.6 {1152    execsql { 1153      PRAGMA foreign_keys = off;1154      ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;1155      PRAGMA foreign_keys = on;1156      SELECT sql FROM aux.sqlite_master WHERE name='t2';1157    }1158  } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}1159 1160  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db1161  do_test fkey2-14.2aux.1.1 {1162    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t31163  } {{CREATE TABLE t1(a REFERENCES "t3")}}1164  do_test fkey2-14.2aux.1.2 {1165    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t31166  } {{CREATE TABLE t1(a REFERENCES t2)}}1167  do_test fkey2-14.2aux.1.3 {1168    test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t31169  } {{CREATE TABLE t1(a REFERENCES "t3")}}1170  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db1171  1172  # Test ALTER TABLE RENAME TABLE a bit.1173  #1174  do_test fkey2-14.2aux.2.1 {1175    drop_all_tables1176    execsql {1177      CREATE TABLE aux.t1(a PRIMARY KEY, b REFERENCES t1);1178      CREATE TABLE aux.t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2);1179      CREATE TABLE aux.t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);1180    }1181    execsql { SELECT sql FROM aux.sqlite_master WHERE type = 'table'}1182  } [list \1183    {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1)}                     \1184    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)}    \1185    {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)}  \1186  ]1187  do_test fkey2-14.2aux.2.2 {1188    execsql { ALTER TABLE t1 RENAME TO t4 }1189    execsql { SELECT sql FROM aux.sqlite_master WHERE type = 'table'}1190  } [list \1191    {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4")}                    \1192    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)}     \1193    {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \1194  ]1195  do_test fkey2-14.2aux.2.3 {1196    catchsql { INSERT INTO t3 VALUES(1, 2, 3) }1197  } {1 {FOREIGN KEY constraint failed}}1198  do_test fkey2-14.2aux.2.4 {1199    execsql { INSERT INTO t4 VALUES(1, NULL) }1200  } {}

Showing the first 1,200 of 2048 lines. Download the file for the rest.