xref: /sqlite-3.40.0/test/without_rowid3.test (revision 92e21ef0)
163f0eedfSdrh# 2013-11-02
263f0eedfSdrh#
363f0eedfSdrh# The author disclaims copyright to this source code.  In place of
463f0eedfSdrh# a legal notice, here is a blessing:
563f0eedfSdrh#
663f0eedfSdrh#    May you do good and not evil.
763f0eedfSdrh#    May you find forgiveness for yourself and forgive others.
863f0eedfSdrh#    May you share freely, never taking more than you give.
963f0eedfSdrh#
1063f0eedfSdrh#***********************************************************************
1163f0eedfSdrh# This file implements regression tests for SQLite library.
1263f0eedfSdrh#
1363f0eedfSdrh# This file implements tests for foreign keys on WITHOUT ROWID
1463f0eedfSdrh# tables.
1563f0eedfSdrh#
1663f0eedfSdrh
1763f0eedfSdrhset testdir [file dirname $argv0]
1863f0eedfSdrhsource $testdir/tester.tcl
1963f0eedfSdrh
2063f0eedfSdrhifcapable {!foreignkey||!trigger} {
2163f0eedfSdrh  finish_test
2263f0eedfSdrh  return
2363f0eedfSdrh}
2463f0eedfSdrh
2563f0eedfSdrh#-------------------------------------------------------------------------
2663f0eedfSdrh# Test structure:
2763f0eedfSdrh#
2863f0eedfSdrh# without_rowid3-1.*: Simple tests to check that immediate and deferred foreign key
2963f0eedfSdrh#            constraints work when not inside a transaction.
3063f0eedfSdrh#
3163f0eedfSdrh# without_rowid3-2.*: Tests to verify that deferred foreign keys work inside
3263f0eedfSdrh#            explicit transactions (i.e that processing really is deferred).
3363f0eedfSdrh#
3463f0eedfSdrh# without_rowid3-3.*: Tests that a statement transaction is rolled back if an
3563f0eedfSdrh#            immediate foreign key constraint is violated.
3663f0eedfSdrh#
3763f0eedfSdrh# without_rowid3-4.*: Test that FK actions may recurse even when recursive triggers
3863f0eedfSdrh#            are disabled.
3963f0eedfSdrh#
4063f0eedfSdrh# without_rowid3-5.*: Check that if foreign-keys are enabled, it is not possible
4163f0eedfSdrh#            to write to an FK column using the incremental blob API.
4263f0eedfSdrh#
4363f0eedfSdrh# without_rowid3-6.*: Test that FK processing is automatically disabled when
4463f0eedfSdrh#            running VACUUM.
4563f0eedfSdrh#
4663f0eedfSdrh# without_rowid3-7.*: Test using an IPK as the key in the child (referencing) table.
4763f0eedfSdrh#
4863f0eedfSdrh# without_rowid3-8.*: Test that enabling/disabling foreign key support while a
4963f0eedfSdrh#            transaction is active is not possible.
5063f0eedfSdrh#
5163f0eedfSdrh# without_rowid3-9.*: Test SET DEFAULT actions.
5263f0eedfSdrh#
5363f0eedfSdrh# without_rowid3-10.*: Test errors.
5463f0eedfSdrh#
5563f0eedfSdrh# without_rowid3-11.*: Test CASCADE actions.
5663f0eedfSdrh#
5763f0eedfSdrh# without_rowid3-12.*: Test RESTRICT actions.
5863f0eedfSdrh#
5963f0eedfSdrh# without_rowid3-13.*: Test that FK processing is performed when a row is REPLACED by
6063f0eedfSdrh#             an UPDATE or INSERT statement.
6163f0eedfSdrh#
6263f0eedfSdrh# without_rowid3-14.*: Test the ALTER TABLE and DROP TABLE commands.
6363f0eedfSdrh#
6463f0eedfSdrh# without_rowid3-15.*: Test that if there are no (known) outstanding foreign key
6563f0eedfSdrh#             constraint violations in the database, inserting into a parent
6663f0eedfSdrh#             table or deleting from a child table does not cause SQLite
6763f0eedfSdrh#             to check if this has repaired an outstanding violation.
6863f0eedfSdrh#
6963f0eedfSdrh# without_rowid3-16.*: Test that rows that refer to themselves may be inserted,
7063f0eedfSdrh#             updated and deleted.
7163f0eedfSdrh#
7263f0eedfSdrh# without_rowid3-17.*: Test that the "count_changes" pragma does not interfere with
7363f0eedfSdrh#             FK constraint processing.
7463f0eedfSdrh#
7563f0eedfSdrh# without_rowid3-18.*: Test that the authorization callback is invoked when processing
7663f0eedfSdrh#             FK constraints.
7763f0eedfSdrh#
7863f0eedfSdrh# without_rowid3-20.*: Test that ON CONFLICT clauses specified as part of statements
7963f0eedfSdrh#             do not affect the operation of FK constraints.
8063f0eedfSdrh#
8163f0eedfSdrh# without_rowid3-genfkey.*: Tests that were used with the shell tool .genfkey
8263f0eedfSdrh#            command. Recycled to test the built-in implementation.
8363f0eedfSdrh#
8463f0eedfSdrh# without_rowid3-dd08e5.*:  Tests to verify that ticket dd08e5a988d00decc4a543daa8d
8563f0eedfSdrh#                  has been fixed.
8663f0eedfSdrh#
8763f0eedfSdrh
8863f0eedfSdrh
8963f0eedfSdrhexecsql { PRAGMA foreign_keys = on }
9063f0eedfSdrh
9163f0eedfSdrhset FkeySimpleSchema {
9263f0eedfSdrh  PRAGMA foreign_keys = on;
9363f0eedfSdrh  CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT rowid;
9463f0eedfSdrh  CREATE TABLE t2(c REFERENCES t1(a) /D/ , d);
9563f0eedfSdrh
9663f0eedfSdrh  CREATE TABLE t3(a PRIMARY KEY, b) WITHOUT rowid;
9763f0eedfSdrh  CREATE TABLE t4(c REFERENCES t3 /D/, d);
9863f0eedfSdrh
9963f0eedfSdrh  CREATE TABLE t7(a, b INT PRIMARY KEY) WITHOUT rowid;
10063f0eedfSdrh  CREATE TABLE t8(c REFERENCES t7 /D/, d);
10163f0eedfSdrh
10263f0eedfSdrh  CREATE TABLE t9(a REFERENCES nosuchtable, b);
10363f0eedfSdrh  CREATE TABLE t10(a REFERENCES t9(c) /D/, b);
10463f0eedfSdrh}
10563f0eedfSdrh
10663f0eedfSdrh
10763f0eedfSdrhset FkeySimpleTests {
108f9c8ce3cSdrh  1.1  "INSERT INTO t2 VALUES(1, 3)"      {1 {FOREIGN KEY constraint failed}}
10963f0eedfSdrh  1.2  "INSERT INTO t1 VALUES(1, 2)"      {0 {}}
11063f0eedfSdrh  1.3  "INSERT INTO t2 VALUES(1, 3)"      {0 {}}
111f9c8ce3cSdrh  1.4  "INSERT INTO t2 VALUES(2, 4)"      {1 {FOREIGN KEY constraint failed}}
11263f0eedfSdrh  1.5  "INSERT INTO t2 VALUES(NULL, 4)"   {0 {}}
113f9c8ce3cSdrh  1.6  "UPDATE t2 SET c=2 WHERE d=4"      {1 {FOREIGN KEY constraint failed}}
11463f0eedfSdrh  1.7  "UPDATE t2 SET c=1 WHERE d=4"      {0 {}}
11563f0eedfSdrh  1.9  "UPDATE t2 SET c=1 WHERE d=4"      {0 {}}
11663f0eedfSdrh  1.10 "UPDATE t2 SET c=NULL WHERE d=4"   {0 {}}
117f9c8ce3cSdrh  1.11 "DELETE FROM t1 WHERE a=1"         {1 {FOREIGN KEY constraint failed}}
118f9c8ce3cSdrh  1.12 "UPDATE t1 SET a = 2"              {1 {FOREIGN KEY constraint failed}}
11963f0eedfSdrh  1.13 "UPDATE t1 SET a = 1"              {0 {}}
12063f0eedfSdrh
121f9c8ce3cSdrh  2.1  "INSERT INTO t4 VALUES(1, 3)"      {1 {FOREIGN KEY constraint failed}}
12263f0eedfSdrh  2.2  "INSERT INTO t3 VALUES(1, 2)"      {0 {}}
12363f0eedfSdrh  2.3  "INSERT INTO t4 VALUES(1, 3)"      {0 {}}
12463f0eedfSdrh
125f9c8ce3cSdrh  4.1  "INSERT INTO t8 VALUES(1, 3)"      {1 {FOREIGN KEY constraint failed}}
12663f0eedfSdrh  4.2  "INSERT INTO t7 VALUES(2, 1)"      {0 {}}
12763f0eedfSdrh  4.3  "INSERT INTO t8 VALUES(1, 3)"      {0 {}}
128f9c8ce3cSdrh  4.4  "INSERT INTO t8 VALUES(2, 4)"      {1 {FOREIGN KEY constraint failed}}
12963f0eedfSdrh  4.5  "INSERT INTO t8 VALUES(NULL, 4)"   {0 {}}
130f9c8ce3cSdrh  4.6  "UPDATE t8 SET c=2 WHERE d=4"      {1 {FOREIGN KEY constraint failed}}
13163f0eedfSdrh  4.7  "UPDATE t8 SET c=1 WHERE d=4"      {0 {}}
13263f0eedfSdrh  4.9  "UPDATE t8 SET c=1 WHERE d=4"      {0 {}}
13363f0eedfSdrh  4.10 "UPDATE t8 SET c=NULL WHERE d=4"   {0 {}}
134f9c8ce3cSdrh  4.11 "DELETE FROM t7 WHERE b=1"         {1 {FOREIGN KEY constraint failed}}
135f9c8ce3cSdrh  4.12 "UPDATE t7 SET b = 2"              {1 {FOREIGN KEY constraint failed}}
13663f0eedfSdrh  4.13 "UPDATE t7 SET b = 1"              {0 {}}
137f9c8ce3cSdrh  4.14 "INSERT INTO t8 VALUES('a', 'b')"  {1 {FOREIGN KEY constraint failed}}
138f9c8ce3cSdrh  4.15 "UPDATE t7 SET b = 5"              {1 {FOREIGN KEY constraint failed}}
13963f0eedfSdrh  4.17 "UPDATE t7 SET a = 10"             {0 {}}
14063f0eedfSdrh
14163f0eedfSdrh  5.1  "INSERT INTO t9 VALUES(1, 3)"      {1 {no such table: main.nosuchtable}}
14263f0eedfSdrh  5.2  "INSERT INTO t10 VALUES(1, 3)"
14363f0eedfSdrh                            {1 {foreign key mismatch - "t10" referencing "t9"}}
14463f0eedfSdrh}
14563f0eedfSdrh
14663f0eedfSdrhdo_test without_rowid3-1.1.0 {
14763f0eedfSdrh  execsql [string map {/D/ {}} $FkeySimpleSchema]
14863f0eedfSdrh} {}
14963f0eedfSdrhforeach {tn zSql res} $FkeySimpleTests {
15063f0eedfSdrh  do_test without_rowid3-1.1.$tn.1 { catchsql $zSql } $res
15163f0eedfSdrh  do_test without_rowid3-1.1.$tn.2 { execsql {PRAGMA foreign_key_check(t1)} } {}
15263f0eedfSdrh  do_test without_rowid3-1.1.$tn.3 { execsql {PRAGMA foreign_key_check(t2)} } {}
15363f0eedfSdrh  do_test without_rowid3-1.1.$tn.4 { execsql {PRAGMA foreign_key_check(t3)} } {}
15463f0eedfSdrh  do_test without_rowid3-1.1.$tn.5 { execsql {PRAGMA foreign_key_check(t4)} } {}
15563f0eedfSdrh  do_test without_rowid3-1.1.$tn.6 { execsql {PRAGMA foreign_key_check(t7)} } {}
15663f0eedfSdrh  do_test without_rowid3-1.1.$tn.7 { execsql {PRAGMA foreign_key_check(t8)} } {}
15763f0eedfSdrh}
15863f0eedfSdrhdrop_all_tables
15963f0eedfSdrh
16063f0eedfSdrhdo_test without_rowid3-1.2.0 {
16163f0eedfSdrh  execsql [string map {/D/ {DEFERRABLE INITIALLY DEFERRED}} $FkeySimpleSchema]
16263f0eedfSdrh} {}
16363f0eedfSdrhforeach {tn zSql res} $FkeySimpleTests {
16463f0eedfSdrh  do_test without_rowid3-1.2.$tn { catchsql $zSql } $res
16563f0eedfSdrh  do_test without_rowid3-1.2.$tn.2 { execsql {PRAGMA foreign_key_check(t1)} } {}
16663f0eedfSdrh  do_test without_rowid3-1.2.$tn.3 { execsql {PRAGMA foreign_key_check(t2)} } {}
16763f0eedfSdrh  do_test without_rowid3-1.2.$tn.4 { execsql {PRAGMA foreign_key_check(t3)} } {}
16863f0eedfSdrh  do_test without_rowid3-1.2.$tn.5 { execsql {PRAGMA foreign_key_check(t4)} } {}
16963f0eedfSdrh  do_test without_rowid3-1.2.$tn.6 { execsql {PRAGMA foreign_key_check(t7)} } {}
17063f0eedfSdrh  do_test without_rowid3-1.2.$tn.7 { execsql {PRAGMA foreign_key_check(t8)} } {}
17163f0eedfSdrh}
17263f0eedfSdrhdrop_all_tables
17363f0eedfSdrh
17463f0eedfSdrhdo_test without_rowid3-1.3.0 {
17563f0eedfSdrh  execsql [string map {/D/ {}} $FkeySimpleSchema]
17663f0eedfSdrh  execsql { PRAGMA count_changes = 1 }
17763f0eedfSdrh} {}
17863f0eedfSdrhforeach {tn zSql res} $FkeySimpleTests {
17963f0eedfSdrh  if {$res == "0 {}"} { set res {0 1} }
18063f0eedfSdrh  do_test without_rowid3-1.3.$tn { catchsql $zSql } $res
18163f0eedfSdrh  do_test without_rowid3-1.3.$tn.2 { execsql {PRAGMA foreign_key_check(t1)} } {}
18263f0eedfSdrh  do_test without_rowid3-1.3.$tn.3 { execsql {PRAGMA foreign_key_check(t2)} } {}
18363f0eedfSdrh  do_test without_rowid3-1.3.$tn.4 { execsql {PRAGMA foreign_key_check(t3)} } {}
18463f0eedfSdrh  do_test without_rowid3-1.3.$tn.5 { execsql {PRAGMA foreign_key_check(t4)} } {}
18563f0eedfSdrh  do_test without_rowid3-1.3.$tn.6 { execsql {PRAGMA foreign_key_check(t7)} } {}
18663f0eedfSdrh  do_test without_rowid3-1.3.$tn.7 { execsql {PRAGMA foreign_key_check(t8)} } {}
18763f0eedfSdrh}
18863f0eedfSdrhexecsql { PRAGMA count_changes = 0 }
18963f0eedfSdrhdrop_all_tables
19063f0eedfSdrh
19163f0eedfSdrhdo_test without_rowid3-1.4.0 {
19263f0eedfSdrh  execsql [string map {/D/ {}} $FkeySimpleSchema]
19363f0eedfSdrh  execsql { PRAGMA count_changes = 1 }
19463f0eedfSdrh} {}
19563f0eedfSdrhforeach {tn zSql res} $FkeySimpleTests {
19663f0eedfSdrh  if {$res == "0 {}"} { set res {0 1} }
19763f0eedfSdrh  execsql BEGIN
19863f0eedfSdrh  do_test without_rowid3-1.4.$tn { catchsql $zSql } $res
19963f0eedfSdrh  execsql COMMIT
20063f0eedfSdrh}
20163f0eedfSdrhexecsql { PRAGMA count_changes = 0 }
20263f0eedfSdrhdrop_all_tables
20363f0eedfSdrh
20463f0eedfSdrh# Special test: When the parent key is an IPK, make sure the affinity of
20563f0eedfSdrh# the IPK is not applied to the child key value before it is inserted
20663f0eedfSdrh# into the child table.
20763f0eedfSdrhdo_test without_rowid3-1.5.1 {
20863f0eedfSdrh  execsql {
20963f0eedfSdrh    CREATE TABLE i(i INT PRIMARY KEY) WITHOUT rowid;
21063f0eedfSdrh    CREATE TABLE j(j REFERENCES i);
21163f0eedfSdrh    INSERT INTO i VALUES(35);
21263f0eedfSdrh    INSERT INTO j VALUES('35.0');
21363f0eedfSdrh    SELECT j, typeof(j) FROM j;
21463f0eedfSdrh  }
21563f0eedfSdrh} {35.0 text}
21663f0eedfSdrhdo_test without_rowid3-1.5.2 {
21763f0eedfSdrh  catchsql { DELETE FROM i }
218f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
21963f0eedfSdrh
22063f0eedfSdrh# Same test using a regular primary key with integer affinity.
22163f0eedfSdrhdrop_all_tables
22263f0eedfSdrhdo_test without_rowid3-1.6.1 {
22363f0eedfSdrh  execsql {
22463f0eedfSdrh    CREATE TABLE i(i INT UNIQUE);
22563f0eedfSdrh    CREATE TABLE j(j REFERENCES i(i));
22663f0eedfSdrh    INSERT INTO i VALUES('35.0');
22763f0eedfSdrh    INSERT INTO j VALUES('35.0');
22863f0eedfSdrh    SELECT j, typeof(j) FROM j;
22963f0eedfSdrh    SELECT i, typeof(i) FROM i;
23063f0eedfSdrh  }
23163f0eedfSdrh} {35.0 text 35 integer}
23263f0eedfSdrhdo_test without_rowid3-1.6.2 {
23363f0eedfSdrh  catchsql { DELETE FROM i }
234f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
23563f0eedfSdrh
23663f0eedfSdrh# Use a collation sequence on the parent key.
23763f0eedfSdrhdrop_all_tables
23863f0eedfSdrhdo_test without_rowid3-1.7.1 {
23963f0eedfSdrh  execsql {
24063f0eedfSdrh    CREATE TABLE i(i TEXT COLLATE nocase PRIMARY KEY) WITHOUT rowid;
24163f0eedfSdrh    CREATE TABLE j(j TEXT COLLATE binary REFERENCES i(i));
24263f0eedfSdrh    INSERT INTO i VALUES('SQLite');
24363f0eedfSdrh    INSERT INTO j VALUES('sqlite');
24463f0eedfSdrh  }
24563f0eedfSdrh  catchsql { DELETE FROM i }
246f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
24763f0eedfSdrh
24863f0eedfSdrh# Use the parent key collation even if it is default and the child key
24963f0eedfSdrh# has an explicit value.
25063f0eedfSdrhdrop_all_tables
25163f0eedfSdrhdo_test without_rowid3-1.7.2 {
25263f0eedfSdrh  execsql {
25363f0eedfSdrh    CREATE TABLE i(i TEXT PRIMARY KEY) WITHOUT rowid;  -- Colseq is "BINARY"
25463f0eedfSdrh    CREATE TABLE j(j TEXT COLLATE nocase REFERENCES i(i));
25563f0eedfSdrh    INSERT INTO i VALUES('SQLite');
25663f0eedfSdrh  }
25763f0eedfSdrh  catchsql { INSERT INTO j VALUES('sqlite') }
258f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
25963f0eedfSdrhdo_test without_rowid3-1.7.3 {
26063f0eedfSdrh  execsql {
26163f0eedfSdrh    INSERT INTO i VALUES('sqlite');
26263f0eedfSdrh    INSERT INTO j VALUES('sqlite');
26363f0eedfSdrh    DELETE FROM i WHERE i = 'SQLite';
26463f0eedfSdrh  }
26563f0eedfSdrh  catchsql { DELETE FROM i WHERE i = 'sqlite' }
266f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
26763f0eedfSdrh
26863f0eedfSdrh#-------------------------------------------------------------------------
26963f0eedfSdrh# This section (test cases without_rowid3-2.*) contains tests to check that the
27063f0eedfSdrh# deferred foreign key constraint logic works.
27163f0eedfSdrh#
27263f0eedfSdrhproc without_rowid3-2-test {tn nocommit sql {res {}}} {
27363f0eedfSdrh  if {$res eq "FKV"} {
274f9c8ce3cSdrh    set expected {1 {FOREIGN KEY constraint failed}}
27563f0eedfSdrh  } else {
27663f0eedfSdrh    set expected [list 0 $res]
27763f0eedfSdrh  }
27863f0eedfSdrh  do_test without_rowid3-2.$tn [list catchsql $sql] $expected
27963f0eedfSdrh  if {$nocommit} {
28063f0eedfSdrh    do_test without_rowid3-2.${tn}c {
28163f0eedfSdrh      catchsql COMMIT
282f9c8ce3cSdrh    } {1 {FOREIGN KEY constraint failed}}
28363f0eedfSdrh  }
28463f0eedfSdrh}
28563f0eedfSdrh
28663f0eedfSdrhwithout_rowid3-2-test 1 0 {
28763f0eedfSdrh  CREATE TABLE node(
28863f0eedfSdrh    nodeid PRIMARY KEY,
28963f0eedfSdrh    parent REFERENCES node DEFERRABLE INITIALLY DEFERRED
29063f0eedfSdrh  ) WITHOUT rowid;
29163f0eedfSdrh  CREATE TABLE leaf(
29263f0eedfSdrh    cellid PRIMARY KEY,
29363f0eedfSdrh    parent REFERENCES node DEFERRABLE INITIALLY DEFERRED
29463f0eedfSdrh  ) WITHOUT rowid;
29563f0eedfSdrh}
29663f0eedfSdrh
29763f0eedfSdrhwithout_rowid3-2-test 1  0 "INSERT INTO node VALUES(1, 0)"       FKV
29863f0eedfSdrhwithout_rowid3-2-test 2  0 "BEGIN"
29963f0eedfSdrhwithout_rowid3-2-test 3  1   "INSERT INTO node VALUES(1, 0)"
30063f0eedfSdrhwithout_rowid3-2-test 4  0   "UPDATE node SET parent = NULL"
30163f0eedfSdrhwithout_rowid3-2-test 5  0 "COMMIT"
30263f0eedfSdrhwithout_rowid3-2-test 6  0 "SELECT * FROM node" {1 {}}
30363f0eedfSdrh
30463f0eedfSdrhwithout_rowid3-2-test 7  0 "BEGIN"
30563f0eedfSdrhwithout_rowid3-2-test 8  1   "INSERT INTO leaf VALUES('a', 2)"
30663f0eedfSdrhwithout_rowid3-2-test 9  1   "INSERT INTO node VALUES(2, 0)"
30763f0eedfSdrhwithout_rowid3-2-test 10 0   "UPDATE node SET parent = 1 WHERE nodeid = 2"
30863f0eedfSdrhwithout_rowid3-2-test 11 0 "COMMIT"
30963f0eedfSdrhwithout_rowid3-2-test 12 0 "SELECT * FROM node" {1 {} 2 1}
31063f0eedfSdrhwithout_rowid3-2-test 13 0 "SELECT * FROM leaf" {a 2}
31163f0eedfSdrh
31263f0eedfSdrhwithout_rowid3-2-test 14 0 "BEGIN"
31363f0eedfSdrhwithout_rowid3-2-test 15 1   "DELETE FROM node WHERE nodeid = 2"
31463f0eedfSdrhwithout_rowid3-2-test 16 0   "INSERT INTO node VALUES(2, NULL)"
31563f0eedfSdrhwithout_rowid3-2-test 17 0 "COMMIT"
31663f0eedfSdrhwithout_rowid3-2-test 18 0 "SELECT * FROM node" {1 {} 2 {}}
31763f0eedfSdrhwithout_rowid3-2-test 19 0 "SELECT * FROM leaf" {a 2}
31863f0eedfSdrh
31963f0eedfSdrhwithout_rowid3-2-test 20 0 "BEGIN"
32063f0eedfSdrhwithout_rowid3-2-test 21 0   "INSERT INTO leaf VALUES('b', 1)"
32163f0eedfSdrhwithout_rowid3-2-test 22 0   "SAVEPOINT save"
32263f0eedfSdrhwithout_rowid3-2-test 23 0     "DELETE FROM node WHERE nodeid = 1"
32363f0eedfSdrhwithout_rowid3-2-test 24 0   "ROLLBACK TO save"
32463f0eedfSdrhwithout_rowid3-2-test 25 0 "COMMIT"
32563f0eedfSdrhwithout_rowid3-2-test 26 0 "SELECT * FROM node" {1 {} 2 {}}
32663f0eedfSdrhwithout_rowid3-2-test 27 0 "SELECT * FROM leaf" {a 2 b 1}
32763f0eedfSdrh
32863f0eedfSdrhwithout_rowid3-2-test 28 0 "BEGIN"
32963f0eedfSdrhwithout_rowid3-2-test 29 0   "INSERT INTO leaf VALUES('c', 1)"
33063f0eedfSdrhwithout_rowid3-2-test 30 0   "SAVEPOINT save"
33163f0eedfSdrhwithout_rowid3-2-test 31 0     "DELETE FROM node WHERE nodeid = 1"
33263f0eedfSdrhwithout_rowid3-2-test 32 1   "RELEASE save"
33363f0eedfSdrhwithout_rowid3-2-test 33 1   "DELETE FROM leaf WHERE cellid = 'b'"
33463f0eedfSdrhwithout_rowid3-2-test 34 0   "DELETE FROM leaf WHERE cellid = 'c'"
33563f0eedfSdrhwithout_rowid3-2-test 35 0 "COMMIT"
33663f0eedfSdrhwithout_rowid3-2-test 36 0 "SELECT * FROM node" {2 {}}
33763f0eedfSdrhwithout_rowid3-2-test 37 0 "SELECT * FROM leaf" {a 2}
33863f0eedfSdrh
33963f0eedfSdrhwithout_rowid3-2-test 38 0 "SAVEPOINT outer"
34063f0eedfSdrhwithout_rowid3-2-test 39 1   "INSERT INTO leaf VALUES('d', 3)"
34163f0eedfSdrhwithout_rowid3-2-test 40 1 "RELEASE outer"    FKV
34263f0eedfSdrhwithout_rowid3-2-test 41 1   "INSERT INTO leaf VALUES('e', 3)"
34363f0eedfSdrhwithout_rowid3-2-test 42 0   "INSERT INTO node VALUES(3, 2)"
34463f0eedfSdrhwithout_rowid3-2-test 43 0 "RELEASE outer"
34563f0eedfSdrh
34663f0eedfSdrhwithout_rowid3-2-test 44 0 "SAVEPOINT outer"
34763f0eedfSdrhwithout_rowid3-2-test 45 1   "DELETE FROM node WHERE nodeid=3"
34863f0eedfSdrhwithout_rowid3-2-test 47 0   "INSERT INTO node VALUES(3, 2)"
34963f0eedfSdrhwithout_rowid3-2-test 48 0 "ROLLBACK TO outer"
35063f0eedfSdrhwithout_rowid3-2-test 49 0 "RELEASE outer"
35163f0eedfSdrh
35263f0eedfSdrhwithout_rowid3-2-test 50 0 "SAVEPOINT outer"
35363f0eedfSdrhwithout_rowid3-2-test 51 1   "INSERT INTO leaf VALUES('f', 4)"
35463f0eedfSdrhwithout_rowid3-2-test 52 1   "SAVEPOINT inner"
35563f0eedfSdrhwithout_rowid3-2-test 53 1     "INSERT INTO leaf VALUES('g', 4)"
35663f0eedfSdrhwithout_rowid3-2-test 54 1  "RELEASE outer"   FKV
35763f0eedfSdrhwithout_rowid3-2-test 55 1   "ROLLBACK TO inner"
35863f0eedfSdrhwithout_rowid3-2-test 56 0  "COMMIT"          FKV
35963f0eedfSdrhwithout_rowid3-2-test 57 0   "INSERT INTO node VALUES(4, NULL)"
36063f0eedfSdrhwithout_rowid3-2-test 58 0 "RELEASE outer"
36163f0eedfSdrhwithout_rowid3-2-test 59 0 "SELECT * FROM node" {2 {} 3 2 4 {}}
36263f0eedfSdrhwithout_rowid3-2-test 60 0 "SELECT * FROM leaf" {a 2 d 3 e 3 f 4}
36363f0eedfSdrh
36463f0eedfSdrh# The following set of tests check that if a statement that affects
36563f0eedfSdrh# multiple rows violates some foreign key constraints, then strikes a
36663f0eedfSdrh# constraint that causes the statement-transaction to be rolled back,
36763f0eedfSdrh# the deferred constraint counter is correctly reset to the value it
36863f0eedfSdrh# had before the statement-transaction was opened.
36963f0eedfSdrh#
37063f0eedfSdrhwithout_rowid3-2-test 61 0 "BEGIN"
37163f0eedfSdrhwithout_rowid3-2-test 62 0   "DELETE FROM leaf"
37263f0eedfSdrhwithout_rowid3-2-test 63 0   "DELETE FROM node"
37363f0eedfSdrhwithout_rowid3-2-test 64 1   "INSERT INTO leaf VALUES('a', 1)"
37463f0eedfSdrhwithout_rowid3-2-test 65 1   "INSERT INTO leaf VALUES('b', 2)"
37563f0eedfSdrhwithout_rowid3-2-test 66 1   "INSERT INTO leaf VALUES('c', 1)"
37663f0eedfSdrhdo_test without_rowid3-2-test-67 {
37763f0eedfSdrh  catchsql          "INSERT INTO node SELECT parent, 3 FROM leaf"
378f9c8ce3cSdrh} {1 {UNIQUE constraint failed: node.nodeid}}
37963f0eedfSdrhwithout_rowid3-2-test 68 0 "COMMIT"           FKV
38063f0eedfSdrhwithout_rowid3-2-test 69 1   "INSERT INTO node VALUES(1, NULL)"
38163f0eedfSdrhwithout_rowid3-2-test 70 0   "INSERT INTO node VALUES(2, NULL)"
38263f0eedfSdrhwithout_rowid3-2-test 71 0 "COMMIT"
38363f0eedfSdrh
38463f0eedfSdrhwithout_rowid3-2-test 72 0 "BEGIN"
38563f0eedfSdrhwithout_rowid3-2-test 73 1   "DELETE FROM node"
38663f0eedfSdrhwithout_rowid3-2-test 74 0   "INSERT INTO node(nodeid) SELECT DISTINCT parent FROM leaf"
38763f0eedfSdrhwithout_rowid3-2-test 75 0 "COMMIT"
38863f0eedfSdrh
38963f0eedfSdrh#-------------------------------------------------------------------------
39063f0eedfSdrh# Test cases without_rowid3-3.* test that a program that executes foreign key
39163f0eedfSdrh# actions (CASCADE, SET DEFAULT, SET NULL etc.) or tests FK constraints
39263f0eedfSdrh# opens a statement transaction if required.
39363f0eedfSdrh#
39463f0eedfSdrh# without_rowid3-3.1.*: Test UPDATE statements.
39563f0eedfSdrh# without_rowid3-3.2.*: Test DELETE statements.
39663f0eedfSdrh#
39763f0eedfSdrhdrop_all_tables
39863f0eedfSdrhdo_test without_rowid3-3.1.1 {
39963f0eedfSdrh  execsql {
40063f0eedfSdrh    CREATE TABLE ab(a PRIMARY KEY, b) WITHOUT rowid;
40163f0eedfSdrh    CREATE TABLE cd(
40263f0eedfSdrh      c PRIMARY KEY REFERENCES ab ON UPDATE CASCADE ON DELETE CASCADE,
40363f0eedfSdrh      d
40463f0eedfSdrh    ) WITHOUT rowid;
40563f0eedfSdrh    CREATE TABLE ef(
40663f0eedfSdrh      e REFERENCES cd ON UPDATE CASCADE,
40763f0eedfSdrh      f, CHECK (e!=5)
40863f0eedfSdrh    );
40963f0eedfSdrh  }
41063f0eedfSdrh} {}
41163f0eedfSdrhdo_test without_rowid3-3.1.2 {
41263f0eedfSdrh  execsql {
41363f0eedfSdrh    INSERT INTO ab VALUES(1, 'b');
41463f0eedfSdrh    INSERT INTO cd VALUES(1, 'd');
41563f0eedfSdrh    INSERT INTO ef VALUES(1, 'e');
41663f0eedfSdrh  }
41763f0eedfSdrh} {}
41863f0eedfSdrhdo_test without_rowid3-3.1.3 {
41963f0eedfSdrh  catchsql { UPDATE ab SET a = 5 }
420*92e21ef0Sdrh} {1 {CHECK constraint failed: e!=5}}
42163f0eedfSdrhdo_test without_rowid3-3.1.4 {
42263f0eedfSdrh  execsql { SELECT * FROM ab }
42363f0eedfSdrh} {1 b}
42463f0eedfSdrhdo_test without_rowid3-3.1.4 {
42563f0eedfSdrh  execsql BEGIN;
42663f0eedfSdrh  catchsql { UPDATE ab SET a = 5 }
427*92e21ef0Sdrh} {1 {CHECK constraint failed: e!=5}}
42863f0eedfSdrhdo_test without_rowid3-3.1.5 {
42963f0eedfSdrh  execsql COMMIT;
43063f0eedfSdrh  execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef }
43163f0eedfSdrh} {1 b 1 d 1 e}
43263f0eedfSdrh
43363f0eedfSdrhdo_test without_rowid3-3.2.1 {
43463f0eedfSdrh  execsql BEGIN;
43563f0eedfSdrh  catchsql { DELETE FROM ab }
436f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
43763f0eedfSdrhdo_test without_rowid3-3.2.2 {
43863f0eedfSdrh  execsql COMMIT
43963f0eedfSdrh  execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef }
44063f0eedfSdrh} {1 b 1 d 1 e}
44163f0eedfSdrh
44263f0eedfSdrh#-------------------------------------------------------------------------
44363f0eedfSdrh# Test cases without_rowid3-4.* test that recursive foreign key actions
44463f0eedfSdrh# (i.e. CASCADE) are allowed even if recursive triggers are disabled.
44563f0eedfSdrh#
44663f0eedfSdrhdrop_all_tables
44763f0eedfSdrhdo_test without_rowid3-4.1 {
44863f0eedfSdrh  execsql {
44963f0eedfSdrh    CREATE TABLE t1(
45063f0eedfSdrh      node PRIMARY KEY,
45163f0eedfSdrh      parent REFERENCES t1 ON DELETE CASCADE
45263f0eedfSdrh    ) WITHOUT rowid;
45363f0eedfSdrh    CREATE TABLE t2(node PRIMARY KEY, parent) WITHOUT rowid;
45463f0eedfSdrh    CREATE TRIGGER t2t AFTER DELETE ON t2 BEGIN
45563f0eedfSdrh      DELETE FROM t2 WHERE parent = old.node;
45663f0eedfSdrh    END;
45763f0eedfSdrh    INSERT INTO t1 VALUES(1, NULL);
45863f0eedfSdrh    INSERT INTO t1 VALUES(2, 1);
45963f0eedfSdrh    INSERT INTO t1 VALUES(3, 1);
46063f0eedfSdrh    INSERT INTO t1 VALUES(4, 2);
46163f0eedfSdrh    INSERT INTO t1 VALUES(5, 2);
46263f0eedfSdrh    INSERT INTO t1 VALUES(6, 3);
46363f0eedfSdrh    INSERT INTO t1 VALUES(7, 3);
46463f0eedfSdrh    INSERT INTO t2 SELECT * FROM t1;
46563f0eedfSdrh  }
46663f0eedfSdrh} {}
46763f0eedfSdrhdo_test without_rowid3-4.2 {
46863f0eedfSdrh  execsql { PRAGMA recursive_triggers = off }
46963f0eedfSdrh  execsql {
47063f0eedfSdrh    BEGIN;
47163f0eedfSdrh      DELETE FROM t1 WHERE node = 1;
47263f0eedfSdrh      SELECT node FROM t1;
47363f0eedfSdrh  }
47463f0eedfSdrh} {}
47563f0eedfSdrhdo_test without_rowid3-4.3 {
47663f0eedfSdrh  execsql {
47763f0eedfSdrh      DELETE FROM t2 WHERE node = 1;
47863f0eedfSdrh      SELECT node FROM t2;
47963f0eedfSdrh    ROLLBACK;
48063f0eedfSdrh  }
48163f0eedfSdrh} {4 5 6 7}
48263f0eedfSdrhdo_test without_rowid3-4.4 {
48363f0eedfSdrh  execsql { PRAGMA recursive_triggers = on }
48463f0eedfSdrh  execsql {
48563f0eedfSdrh    BEGIN;
48663f0eedfSdrh      DELETE FROM t1 WHERE node = 1;
48763f0eedfSdrh      SELECT node FROM t1;
48863f0eedfSdrh  }
48963f0eedfSdrh} {}
49063f0eedfSdrhdo_test without_rowid3-4.3 {
49163f0eedfSdrh  execsql {
49263f0eedfSdrh      DELETE FROM t2 WHERE node = 1;
49363f0eedfSdrh      SELECT node FROM t2;
49463f0eedfSdrh    ROLLBACK;
49563f0eedfSdrh  }
49663f0eedfSdrh} {}
49763f0eedfSdrh
49863f0eedfSdrh#-------------------------------------------------------------------------
49963f0eedfSdrh# Test cases without_rowid3-5.* verify that the incremental blob API may not
50063f0eedfSdrh# write to a foreign key column while foreign-keys are enabled.
50163f0eedfSdrh#
50263f0eedfSdrhdrop_all_tables
50363f0eedfSdrhifcapable incrblob {
50463f0eedfSdrh  do_test without_rowid3-5.1 {
50563f0eedfSdrh    execsql {
50663f0eedfSdrh      CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT rowid;
50763f0eedfSdrh      CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1(a)) WITHOUT rowid;
50863f0eedfSdrh      INSERT INTO t1 VALUES('hello', 'world');
50963f0eedfSdrh      INSERT INTO t2 VALUES('key', 'hello');
51063f0eedfSdrh    }
51163f0eedfSdrh  } {}
51263f0eedfSdrh  do_test without_rowid3-5.2 {
51363f0eedfSdrh    set rc [catch { set fd [db incrblob t2 b 1] } msg]
51463f0eedfSdrh    list $rc $msg
51563f0eedfSdrh  } {1 {cannot open table without rowid: t2}}
51663f0eedfSdrh  do_test without_rowid3-5.5 {
51763f0eedfSdrh    execsql { PRAGMA foreign_keys = on }
51863f0eedfSdrh  } {}
51963f0eedfSdrh}
52063f0eedfSdrh
52163f0eedfSdrhdrop_all_tables
52263f0eedfSdrhifcapable vacuum {
52363f0eedfSdrh  do_test without_rowid3-6.1 {
52463f0eedfSdrh    execsql {
52563f0eedfSdrh      CREATE TABLE t1(a REFERENCES t2(c), b);
52663f0eedfSdrh      CREATE TABLE t2(c UNIQUE, b);
52763f0eedfSdrh      INSERT INTO t2 VALUES(1, 2);
52863f0eedfSdrh      INSERT INTO t1 VALUES(1, 2);
52963f0eedfSdrh      VACUUM;
53063f0eedfSdrh    }
53163f0eedfSdrh  } {}
53263f0eedfSdrh}
53363f0eedfSdrh
53463f0eedfSdrh#-------------------------------------------------------------------------
53563f0eedfSdrh# Test that it is possible to use an INT PRIMARY KEY as the child key
53663f0eedfSdrh# of a foreign constraint.
53763f0eedfSdrh#
53863f0eedfSdrhdrop_all_tables
53963f0eedfSdrhdo_test without_rowid3-7.1 {
54063f0eedfSdrh  execsql {
54163f0eedfSdrh    CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT rowid;
54263f0eedfSdrh    CREATE TABLE t2(c INT PRIMARY KEY REFERENCES t1, b) WITHOUT rowid;
54363f0eedfSdrh  }
54463f0eedfSdrh} {}
54563f0eedfSdrhdo_test without_rowid3-7.2 {
54663f0eedfSdrh  catchsql { INSERT INTO t2 VALUES(1, 'A'); }
547f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
54863f0eedfSdrhdo_test without_rowid3-7.3 {
54963f0eedfSdrh  execsql {
55063f0eedfSdrh    INSERT INTO t1 VALUES(1, 2);
55163f0eedfSdrh    INSERT INTO t1 VALUES(2, 3);
55263f0eedfSdrh    INSERT INTO t2 VALUES(1, 'A');
55363f0eedfSdrh  }
55463f0eedfSdrh} {}
55563f0eedfSdrhdo_test without_rowid3-7.4 {
55663f0eedfSdrh  execsql { UPDATE t2 SET c = 2 }
55763f0eedfSdrh} {}
55863f0eedfSdrhdo_test without_rowid3-7.5 {
55963f0eedfSdrh  catchsql { UPDATE t2 SET c = 3 }
560f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
56163f0eedfSdrhdo_test without_rowid3-7.6 {
56263f0eedfSdrh  catchsql { DELETE FROM t1 WHERE a = 2 }
563f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
56463f0eedfSdrhdo_test without_rowid3-7.7 {
56563f0eedfSdrh  execsql { DELETE FROM t1 WHERE a = 1 }
56663f0eedfSdrh} {}
56763f0eedfSdrhdo_test without_rowid3-7.8 {
56863f0eedfSdrh  catchsql { UPDATE t1 SET a = 3 }
569f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
57063f0eedfSdrh
57163f0eedfSdrh#-------------------------------------------------------------------------
57263f0eedfSdrh# Test that it is not possible to enable/disable FK support while a
57363f0eedfSdrh# transaction is open.
57463f0eedfSdrh#
57563f0eedfSdrhdrop_all_tables
57663f0eedfSdrhproc without_rowid3-8-test {tn zSql value} {
57763f0eedfSdrh  do_test without_rowid3-2.8.$tn.1 [list execsql $zSql] {}
57863f0eedfSdrh  do_test without_rowid3-2.8.$tn.2 { execsql "PRAGMA foreign_keys" } $value
57963f0eedfSdrh}
58063f0eedfSdrhwithout_rowid3-8-test  1 { PRAGMA foreign_keys = 0     } 0
58163f0eedfSdrhwithout_rowid3-8-test  2 { PRAGMA foreign_keys = 1     } 1
58263f0eedfSdrhwithout_rowid3-8-test  3 { BEGIN                       } 1
58363f0eedfSdrhwithout_rowid3-8-test  4 { PRAGMA foreign_keys = 0     } 1
58463f0eedfSdrhwithout_rowid3-8-test  5 { COMMIT                      } 1
58563f0eedfSdrhwithout_rowid3-8-test  6 { PRAGMA foreign_keys = 0     } 0
58663f0eedfSdrhwithout_rowid3-8-test  7 { BEGIN                       } 0
58763f0eedfSdrhwithout_rowid3-8-test  8 { PRAGMA foreign_keys = 1     } 0
58863f0eedfSdrhwithout_rowid3-8-test  9 { COMMIT                      } 0
58963f0eedfSdrhwithout_rowid3-8-test 10 { PRAGMA foreign_keys = 1     } 1
59063f0eedfSdrhwithout_rowid3-8-test 11 { PRAGMA foreign_keys = off   } 0
59163f0eedfSdrhwithout_rowid3-8-test 12 { PRAGMA foreign_keys = on    } 1
59263f0eedfSdrhwithout_rowid3-8-test 13 { PRAGMA foreign_keys = no    } 0
59363f0eedfSdrhwithout_rowid3-8-test 14 { PRAGMA foreign_keys = yes   } 1
59463f0eedfSdrhwithout_rowid3-8-test 15 { PRAGMA foreign_keys = false } 0
59563f0eedfSdrhwithout_rowid3-8-test 16 { PRAGMA foreign_keys = true  } 1
59663f0eedfSdrh
59763f0eedfSdrh#-------------------------------------------------------------------------
59863f0eedfSdrh# The following tests, without_rowid3-9.*, test SET DEFAULT actions.
59963f0eedfSdrh#
60063f0eedfSdrhdrop_all_tables
60163f0eedfSdrhdo_test without_rowid3-9.1.1 {
60263f0eedfSdrh  execsql {
60363f0eedfSdrh    CREATE TABLE t1(a INT PRIMARY KEY, b) WITHOUT rowid;
60463f0eedfSdrh    CREATE TABLE t2(
60563f0eedfSdrh      c INT PRIMARY KEY,
60663f0eedfSdrh      d INTEGER DEFAULT 1 REFERENCES t1 ON DELETE SET DEFAULT
60763f0eedfSdrh    ) WITHOUT rowid;
60863f0eedfSdrh    DELETE FROM t1;
60963f0eedfSdrh  }
61063f0eedfSdrh} {}
61163f0eedfSdrhdo_test without_rowid3-9.1.2 {
61263f0eedfSdrh  execsql {
61363f0eedfSdrh    INSERT INTO t1 VALUES(1, 'one');
61463f0eedfSdrh    INSERT INTO t1 VALUES(2, 'two');
61563f0eedfSdrh    INSERT INTO t2 VALUES(1, 2);
61663f0eedfSdrh    SELECT * FROM t2;
61763f0eedfSdrh    DELETE FROM t1 WHERE a = 2;
61863f0eedfSdrh    SELECT * FROM t2;
61963f0eedfSdrh  }
62063f0eedfSdrh} {1 2 1 1}
62163f0eedfSdrhdo_test without_rowid3-9.1.3 {
62263f0eedfSdrh  execsql {
62363f0eedfSdrh    INSERT INTO t1 VALUES(2, 'two');
62463f0eedfSdrh    UPDATE t2 SET d = 2;
62563f0eedfSdrh    DELETE FROM t1 WHERE a = 1;
62663f0eedfSdrh    SELECT * FROM t2;
62763f0eedfSdrh  }
62863f0eedfSdrh} {1 2}
62963f0eedfSdrhdo_test without_rowid3-9.1.4 {
63063f0eedfSdrh  execsql { SELECT * FROM t1 }
63163f0eedfSdrh} {2 two}
63263f0eedfSdrhdo_test without_rowid3-9.1.5 {
63363f0eedfSdrh  catchsql { DELETE FROM t1 }
634f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
63563f0eedfSdrh
63663f0eedfSdrhdo_test without_rowid3-9.2.1 {
63763f0eedfSdrh  execsql {
63863f0eedfSdrh    CREATE TABLE pp(a, b, c, PRIMARY KEY(b, c)) WITHOUT rowid;
63963f0eedfSdrh    CREATE TABLE cc(d DEFAULT 3, e DEFAULT 1, f DEFAULT 2,
64063f0eedfSdrh        FOREIGN KEY(f, d) REFERENCES pp
64163f0eedfSdrh        ON UPDATE SET DEFAULT
64263f0eedfSdrh        ON DELETE SET NULL
64363f0eedfSdrh    );
64463f0eedfSdrh    INSERT INTO pp VALUES(1, 2, 3);
64563f0eedfSdrh    INSERT INTO pp VALUES(4, 5, 6);
64663f0eedfSdrh    INSERT INTO pp VALUES(7, 8, 9);
64763f0eedfSdrh  }
64863f0eedfSdrh} {}
64963f0eedfSdrhdo_test without_rowid3-9.2.2 {
65063f0eedfSdrh  execsql {
65163f0eedfSdrh    INSERT INTO cc VALUES(6, 'A', 5);
65263f0eedfSdrh    INSERT INTO cc VALUES(6, 'B', 5);
65363f0eedfSdrh    INSERT INTO cc VALUES(9, 'A', 8);
65463f0eedfSdrh    INSERT INTO cc VALUES(9, 'B', 8);
65563f0eedfSdrh    UPDATE pp SET b = 1 WHERE a = 7;
65663f0eedfSdrh    SELECT * FROM cc;
65763f0eedfSdrh  }
65863f0eedfSdrh} {6 A 5 6 B 5 3 A 2 3 B 2}
65963f0eedfSdrhdo_test without_rowid3-9.2.3 {
66063f0eedfSdrh  execsql {
66163f0eedfSdrh    DELETE FROM pp WHERE a = 4;
66263f0eedfSdrh    SELECT * FROM cc;
66363f0eedfSdrh  }
66463f0eedfSdrh} {{} A {} {} B {} 3 A 2 3 B 2}
66563f0eedfSdrh
66663f0eedfSdrh#-------------------------------------------------------------------------
66763f0eedfSdrh# The following tests, without_rowid3-10.*, test "foreign key mismatch" and
66863f0eedfSdrh# other errors.
66963f0eedfSdrh#
67063f0eedfSdrhset tn 0
67163f0eedfSdrhforeach zSql [list {
67263f0eedfSdrh  CREATE TABLE p(a PRIMARY KEY, b) WITHOUT rowid;
67363f0eedfSdrh  CREATE TABLE c(x REFERENCES p(c));
67463f0eedfSdrh} {
67563f0eedfSdrh  CREATE TABLE c(x REFERENCES v(y));
67663f0eedfSdrh  CREATE VIEW v AS SELECT x AS y FROM c;
67763f0eedfSdrh} {
67863f0eedfSdrh  CREATE TABLE p(a, b, PRIMARY KEY(a, b)) WITHOUT rowid;
67963f0eedfSdrh  CREATE TABLE c(x REFERENCES p);
68063f0eedfSdrh} {
68163f0eedfSdrh  CREATE TABLE p(a COLLATE binary, b);
68263f0eedfSdrh  CREATE UNIQUE INDEX i ON p(a COLLATE nocase);
68363f0eedfSdrh  CREATE TABLE c(x REFERENCES p(a));
68463f0eedfSdrh}] {
68563f0eedfSdrh  drop_all_tables
68663f0eedfSdrh  do_test without_rowid3-10.1.[incr tn] {
68763f0eedfSdrh    execsql $zSql
68863f0eedfSdrh    catchsql { INSERT INTO c DEFAULT VALUES }
68963f0eedfSdrh  } {/1 {foreign key mismatch - "c" referencing "."}/}
69063f0eedfSdrh}
69163f0eedfSdrh
69263f0eedfSdrh# "rowid" cannot be used as part of a child or parent key definition
69363f0eedfSdrh# unless it happens to be the name of an explicitly declared column.
69463f0eedfSdrh#
69563f0eedfSdrhdo_test without_rowid3-10.2.1 {
69663f0eedfSdrh  drop_all_tables
69763f0eedfSdrh  catchsql {
69863f0eedfSdrh    CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT rowid;
69963f0eedfSdrh    CREATE TABLE t2(c, d, FOREIGN KEY(rowid) REFERENCES t1(a));
70063f0eedfSdrh  }
70163f0eedfSdrh} {1 {unknown column "rowid" in foreign key definition}}
70263f0eedfSdrhdo_test without_rowid3-10.2.2 {
70363f0eedfSdrh  drop_all_tables
70463f0eedfSdrh  catchsql {
70563f0eedfSdrh    CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT rowid;
70663f0eedfSdrh    CREATE TABLE t2(rowid, d, FOREIGN KEY(rowid) REFERENCES t1(a));
70763f0eedfSdrh  }
70863f0eedfSdrh} {0 {}}
70963f0eedfSdrhdo_test without_rowid3-10.2.1 {
71063f0eedfSdrh  drop_all_tables
71163f0eedfSdrh  catchsql {
71263f0eedfSdrh    CREATE TABLE t1(a, b);
71363f0eedfSdrh    CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(rowid));
71463f0eedfSdrh    INSERT INTO t1(rowid, a, b) VALUES(1, 1, 1);
71563f0eedfSdrh    INSERT INTO t2 VALUES(1, 1);
71663f0eedfSdrh  }
71763f0eedfSdrh} {1 {foreign key mismatch - "t2" referencing "t1"}}
71863f0eedfSdrhdo_test without_rowid3-10.2.2 {
71963f0eedfSdrh  drop_all_tables
72063f0eedfSdrh  catchsql {
72163f0eedfSdrh    CREATE TABLE t1(rowid PRIMARY KEY, b) WITHOUT rowid;
72263f0eedfSdrh    CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(rowid));
72363f0eedfSdrh    INSERT INTO t1(rowid, b) VALUES(1, 1);
72463f0eedfSdrh    INSERT INTO t2 VALUES(1, 1);
72563f0eedfSdrh  }
72663f0eedfSdrh} {0 {}}
72763f0eedfSdrh
72863f0eedfSdrh
72963f0eedfSdrh#-------------------------------------------------------------------------
73063f0eedfSdrh# The following tests, without_rowid3-11.*, test CASCADE actions.
73163f0eedfSdrh#
73263f0eedfSdrhdrop_all_tables
73363f0eedfSdrhdo_test without_rowid3-11.1.1 {
73463f0eedfSdrh  execsql {
73563f0eedfSdrh    CREATE TABLE t1(a INT PRIMARY KEY, b) WITHOUT rowid;
73663f0eedfSdrh    CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(a) ON UPDATE CASCADE);
73763f0eedfSdrh
73863f0eedfSdrh    INSERT INTO t1 VALUES(10, 100);
73963f0eedfSdrh    INSERT INTO t2 VALUES(10, 100);
74063f0eedfSdrh    UPDATE t1 SET a = 15;
74163f0eedfSdrh    SELECT * FROM t2;
74263f0eedfSdrh  }
74363f0eedfSdrh} {15 100}
74463f0eedfSdrh
74563f0eedfSdrh#-------------------------------------------------------------------------
74663f0eedfSdrh# The following tests, without_rowid3-12.*, test RESTRICT actions.
74763f0eedfSdrh#
74863f0eedfSdrhdrop_all_tables
74963f0eedfSdrhdo_test without_rowid3-12.1.1 {
75063f0eedfSdrh  execsql {
75163f0eedfSdrh    CREATE TABLE t1(a, b PRIMARY KEY) WITHOUT rowid;
75263f0eedfSdrh    CREATE TABLE t2(
75363f0eedfSdrh      x REFERENCES t1 ON UPDATE RESTRICT DEFERRABLE INITIALLY DEFERRED
75463f0eedfSdrh    );
75563f0eedfSdrh    INSERT INTO t1 VALUES(1, 'one');
75663f0eedfSdrh    INSERT INTO t1 VALUES(2, 'two');
75763f0eedfSdrh    INSERT INTO t1 VALUES(3, 'three');
75863f0eedfSdrh  }
75963f0eedfSdrh} {}
76063f0eedfSdrhdo_test without_rowid3-12.1.2 {
76163f0eedfSdrh  execsql "BEGIN"
76263f0eedfSdrh  execsql "INSERT INTO t2 VALUES('two')"
76363f0eedfSdrh} {}
76463f0eedfSdrhdo_test without_rowid3-12.1.3 {
76563f0eedfSdrh  execsql "UPDATE t1 SET b = 'four' WHERE b = 'one'"
76663f0eedfSdrh} {}
76763f0eedfSdrhdo_test without_rowid3-12.1.4 {
76863f0eedfSdrh  catchsql "UPDATE t1 SET b = 'five' WHERE b = 'two'"
769f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
77063f0eedfSdrhdo_test without_rowid3-12.1.5 {
77163f0eedfSdrh  execsql "DELETE FROM t1 WHERE b = 'two'"
77263f0eedfSdrh} {}
77363f0eedfSdrhdo_test without_rowid3-12.1.6 {
77463f0eedfSdrh  catchsql "COMMIT"
775f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
77663f0eedfSdrhdo_test without_rowid3-12.1.7 {
77763f0eedfSdrh  execsql {
77863f0eedfSdrh    INSERT INTO t1 VALUES(2, 'two');
77963f0eedfSdrh    COMMIT;
78063f0eedfSdrh  }
78163f0eedfSdrh} {}
78263f0eedfSdrh
78363f0eedfSdrhdrop_all_tables
78463f0eedfSdrhdo_test without_rowid3-12.2.1 {
78563f0eedfSdrh  execsql {
78663f0eedfSdrh    CREATE TABLE t1(x COLLATE NOCASE PRIMARY KEY) WITHOUT rowid;
78763f0eedfSdrh    CREATE TRIGGER tt1 AFTER DELETE ON t1
78863f0eedfSdrh      WHEN EXISTS ( SELECT 1 FROM t2 WHERE old.x = y )
78963f0eedfSdrh    BEGIN
79063f0eedfSdrh      INSERT INTO t1 VALUES(old.x);
79163f0eedfSdrh    END;
79263f0eedfSdrh    CREATE TABLE t2(y REFERENCES t1);
79363f0eedfSdrh    INSERT INTO t1 VALUES('A');
79463f0eedfSdrh    INSERT INTO t1 VALUES('B');
79563f0eedfSdrh    INSERT INTO t2 VALUES('a');
79663f0eedfSdrh    INSERT INTO t2 VALUES('b');
79763f0eedfSdrh
79863f0eedfSdrh    SELECT * FROM t1;
79963f0eedfSdrh    SELECT * FROM t2;
80063f0eedfSdrh  }
80163f0eedfSdrh} {A B a b}
80263f0eedfSdrhdo_test without_rowid3-12.2.2 {
80363f0eedfSdrh  execsql { DELETE FROM t1 }
80463f0eedfSdrh  execsql {
80563f0eedfSdrh    SELECT * FROM t1;
80663f0eedfSdrh    SELECT * FROM t2;
80763f0eedfSdrh  }
80863f0eedfSdrh} {A B a b}
80963f0eedfSdrhdo_test without_rowid3-12.2.3 {
81063f0eedfSdrh  execsql {
81163f0eedfSdrh    DROP TABLE t2;
81263f0eedfSdrh    CREATE TABLE t2(y REFERENCES t1 ON DELETE RESTRICT);
81363f0eedfSdrh    INSERT INTO t2 VALUES('a');
81463f0eedfSdrh    INSERT INTO t2 VALUES('b');
81563f0eedfSdrh  }
81663f0eedfSdrh  catchsql { DELETE FROM t1 }
817f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
81863f0eedfSdrhdo_test without_rowid3-12.2.4 {
81963f0eedfSdrh  execsql {
82063f0eedfSdrh    SELECT * FROM t1;
82163f0eedfSdrh    SELECT * FROM t2;
82263f0eedfSdrh  }
82363f0eedfSdrh} {A B a b}
82463f0eedfSdrh
82563f0eedfSdrhdrop_all_tables
82663f0eedfSdrhdo_test without_rowid3-12.3.1 {
82763f0eedfSdrh  execsql {
82863f0eedfSdrh    CREATE TABLE up(
82963f0eedfSdrh      c00, c01, c02, c03, c04, c05, c06, c07, c08, c09,
83063f0eedfSdrh      c10, c11, c12, c13, c14, c15, c16, c17, c18, c19,
83163f0eedfSdrh      c20, c21, c22, c23, c24, c25, c26, c27, c28, c29,
83263f0eedfSdrh      c30, c31, c32, c33, c34, c35, c36, c37, c38, c39,
83363f0eedfSdrh      PRIMARY KEY(c34, c35)
83463f0eedfSdrh    ) WITHOUT rowid;
83563f0eedfSdrh    CREATE TABLE down(
83663f0eedfSdrh      c00, c01, c02, c03, c04, c05, c06, c07, c08, c09,
83763f0eedfSdrh      c10, c11, c12, c13, c14, c15, c16, c17, c18, c19,
83863f0eedfSdrh      c20, c21, c22, c23, c24, c25, c26, c27, c28, c29,
83963f0eedfSdrh      c30, c31, c32, c33, c34, c35, c36, c37, c38, c39,
84063f0eedfSdrh      FOREIGN KEY(c39, c38) REFERENCES up ON UPDATE CASCADE
84163f0eedfSdrh    );
84263f0eedfSdrh  }
84363f0eedfSdrh} {}
84463f0eedfSdrhdo_test without_rowid3-12.3.2 {
84563f0eedfSdrh  execsql {
84663f0eedfSdrh    INSERT INTO up(c34, c35) VALUES('yes', 'no');
84763f0eedfSdrh    INSERT INTO down(c39, c38) VALUES('yes', 'no');
84863f0eedfSdrh    UPDATE up SET c34 = 'possibly';
84963f0eedfSdrh    SELECT c38, c39 FROM down;
85063f0eedfSdrh    DELETE FROM down;
85163f0eedfSdrh  }
85263f0eedfSdrh} {no possibly}
85363f0eedfSdrhdo_test without_rowid3-12.3.3 {
85463f0eedfSdrh  catchsql { INSERT INTO down(c39, c38) VALUES('yes', 'no') }
855f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
85663f0eedfSdrhdo_test without_rowid3-12.3.4 {
85763f0eedfSdrh  execsql {
85863f0eedfSdrh    INSERT INTO up(c34, c35) VALUES('yes', 'no');
85963f0eedfSdrh    INSERT INTO down(c39, c38) VALUES('yes', 'no');
86063f0eedfSdrh  }
86163f0eedfSdrh  catchsql { DELETE FROM up WHERE c34 = 'yes' }
862f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
86363f0eedfSdrhdo_test without_rowid3-12.3.5 {
86463f0eedfSdrh  execsql {
86563f0eedfSdrh    DELETE FROM up WHERE c34 = 'possibly';
86663f0eedfSdrh    SELECT c34, c35 FROM up;
86763f0eedfSdrh    SELECT c39, c38 FROM down;
86863f0eedfSdrh  }
86963f0eedfSdrh} {yes no yes no}
87063f0eedfSdrh
87163f0eedfSdrh#-------------------------------------------------------------------------
87263f0eedfSdrh# The following tests, without_rowid3-13.*, test that FK processing is performed
87363f0eedfSdrh# when rows are REPLACEd.
87463f0eedfSdrh#
87563f0eedfSdrhdrop_all_tables
87663f0eedfSdrhdo_test without_rowid3-13.1.1 {
87763f0eedfSdrh  execsql {
87863f0eedfSdrh    CREATE TABLE pp(a UNIQUE, b, c, PRIMARY KEY(b, c)) WITHOUT rowid;
87963f0eedfSdrh    CREATE TABLE cc(d, e, f UNIQUE, FOREIGN KEY(d, e) REFERENCES pp);
88063f0eedfSdrh    INSERT INTO pp VALUES(1, 2, 3);
88163f0eedfSdrh    INSERT INTO cc VALUES(2, 3, 1);
88263f0eedfSdrh  }
88363f0eedfSdrh} {}
88463f0eedfSdrhforeach {tn stmt} {
88563f0eedfSdrh  1   "REPLACE INTO pp VALUES(1, 4, 5)"
88663f0eedfSdrh} {
88763f0eedfSdrh  do_test without_rowid3-13.1.$tn.1 {
88863f0eedfSdrh    catchsql $stmt
889f9c8ce3cSdrh  } {1 {FOREIGN KEY constraint failed}}
89063f0eedfSdrh  do_test without_rowid3-13.1.$tn.2 {
89163f0eedfSdrh    execsql {
89263f0eedfSdrh      SELECT * FROM pp;
89363f0eedfSdrh      SELECT * FROM cc;
89463f0eedfSdrh    }
89563f0eedfSdrh  } {1 2 3 2 3 1}
89663f0eedfSdrh  do_test without_rowid3-13.1.$tn.3 {
89763f0eedfSdrh    execsql BEGIN;
89863f0eedfSdrh    catchsql $stmt
899f9c8ce3cSdrh  } {1 {FOREIGN KEY constraint failed}}
90063f0eedfSdrh  do_test without_rowid3-13.1.$tn.4 {
90163f0eedfSdrh    execsql {
90263f0eedfSdrh      COMMIT;
90363f0eedfSdrh      SELECT * FROM pp;
90463f0eedfSdrh      SELECT * FROM cc;
90563f0eedfSdrh    }
90663f0eedfSdrh  } {1 2 3 2 3 1}
90763f0eedfSdrh}
90863f0eedfSdrh
90963f0eedfSdrh#-------------------------------------------------------------------------
91063f0eedfSdrh# The following tests, without_rowid3-14.*, test that the "DROP TABLE" and "ALTER
91163f0eedfSdrh# TABLE" commands work as expected wrt foreign key constraints.
91263f0eedfSdrh#
91363f0eedfSdrh# without_rowid3-14.1*: ALTER TABLE ADD COLUMN
91463f0eedfSdrh# without_rowid3-14.2*: ALTER TABLE RENAME TABLE
91563f0eedfSdrh# without_rowid3-14.3*: DROP TABLE
91663f0eedfSdrh#
91763f0eedfSdrhdrop_all_tables
91863f0eedfSdrhifcapable altertable {
91963f0eedfSdrh  do_test without_rowid3-14.1.1 {
92063f0eedfSdrh    # Adding a column with a REFERENCES clause is not supported.
92163f0eedfSdrh    execsql {
92263f0eedfSdrh      CREATE TABLE t1(a PRIMARY KEY) WITHOUT rowid;
92363f0eedfSdrh      CREATE TABLE t2(a, b);
9249e5fdc41Sdrh      INSERT INTO t2(a,b) VALUES(1,2);
92563f0eedfSdrh    }
92663f0eedfSdrh    catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
92763f0eedfSdrh  } {0 {}}
92863f0eedfSdrh  do_test without_rowid3-14.1.2 {
92963f0eedfSdrh    catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
93063f0eedfSdrh  } {0 {}}
93163f0eedfSdrh  do_test without_rowid3-14.1.3 {
93263f0eedfSdrh    catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}
93363f0eedfSdrh  } {0 {}}
93463f0eedfSdrh  do_test without_rowid3-14.1.4 {
93563f0eedfSdrh    catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'}
93663f0eedfSdrh  } {1 {Cannot add a REFERENCES column with non-NULL default value}}
93763f0eedfSdrh  do_test without_rowid3-14.1.5 {
93863f0eedfSdrh    catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 }
93963f0eedfSdrh  } {1 {Cannot add a REFERENCES column with non-NULL default value}}
94063f0eedfSdrh  do_test without_rowid3-14.1.6 {
94163f0eedfSdrh    execsql {
94263f0eedfSdrh      PRAGMA foreign_keys = off;
94363f0eedfSdrh      ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
94463f0eedfSdrh      PRAGMA foreign_keys = on;
945346a70caSdrh      SELECT sql FROM sqlite_schema WHERE name='t2';
94663f0eedfSdrh    }
94763f0eedfSdrh  } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
94863f0eedfSdrh
94963f0eedfSdrh
95063f0eedfSdrh  # Test the sqlite_rename_parent() function directly.
95163f0eedfSdrh  #
95263f0eedfSdrh  proc test_rename_parent {zCreate zOld zNew} {
9535921f2b9Sdan    db eval {SELECT sqlite_rename_table(
9545921f2b9Sdan        'main', 'table', 't1', $zCreate, $zOld, $zNew, 0
9555921f2b9Sdan    )}
95663f0eedfSdrh  }
957171c50ecSdrh  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
95863f0eedfSdrh  do_test without_rowid3-14.2.1.1 {
95963f0eedfSdrh    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
96063f0eedfSdrh  } {{CREATE TABLE t1(a REFERENCES "t3")}}
96163f0eedfSdrh  do_test without_rowid3-14.2.1.2 {
96263f0eedfSdrh    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
96363f0eedfSdrh  } {{CREATE TABLE t1(a REFERENCES t2)}}
96463f0eedfSdrh  do_test without_rowid3-14.2.1.3 {
96563f0eedfSdrh    test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
96663f0eedfSdrh  } {{CREATE TABLE t1(a REFERENCES "t3")}}
967171c50ecSdrh  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
96863f0eedfSdrh
96963f0eedfSdrh  # Test ALTER TABLE RENAME TABLE a bit.
97063f0eedfSdrh  #
97163f0eedfSdrh  do_test without_rowid3-14.2.2.1 {
97263f0eedfSdrh    drop_all_tables
97363f0eedfSdrh    execsql {
97463f0eedfSdrh      CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid;
97563f0eedfSdrh      CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)
97663f0eedfSdrh            WITHOUT rowid;
97763f0eedfSdrh      CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
97863f0eedfSdrh    }
979346a70caSdrh    execsql { SELECT sql FROM sqlite_schema WHERE type = 'table'}
98063f0eedfSdrh  } [list \
98163f0eedfSdrh    {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid}       \
98263f0eedfSdrh    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)
98363f0eedfSdrh            WITHOUT rowid}    \
98463f0eedfSdrh    {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)}  \
98563f0eedfSdrh  ]
98663f0eedfSdrh  do_test without_rowid3-14.2.2.2 {
98763f0eedfSdrh    execsql { ALTER TABLE t1 RENAME TO t4 }
988346a70caSdrh    execsql { SELECT sql FROM sqlite_schema WHERE type = 'table'}
98963f0eedfSdrh  } [list \
99063f0eedfSdrh    {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid}      \
99163f0eedfSdrh    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)
99263f0eedfSdrh            WITHOUT rowid}     \
99363f0eedfSdrh    {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \
99463f0eedfSdrh  ]
99563f0eedfSdrh  do_test without_rowid3-14.2.2.3 {
99663f0eedfSdrh    catchsql { INSERT INTO t3 VALUES(1, 2, 3) }
997f9c8ce3cSdrh  } {1 {FOREIGN KEY constraint failed}}
99863f0eedfSdrh  do_test without_rowid3-14.2.2.4 {
99963f0eedfSdrh    execsql { INSERT INTO t4 VALUES(1, NULL) }
100063f0eedfSdrh  } {}
100163f0eedfSdrh  do_test without_rowid3-14.2.2.5 {
100263f0eedfSdrh    catchsql { UPDATE t4 SET b = 5 }
1003f9c8ce3cSdrh  } {1 {FOREIGN KEY constraint failed}}
100463f0eedfSdrh  do_test without_rowid3-14.2.2.6 {
100563f0eedfSdrh    catchsql { UPDATE t4 SET b = 1 }
100663f0eedfSdrh  } {0 {}}
100763f0eedfSdrh  do_test without_rowid3-14.2.2.7 {
100863f0eedfSdrh    execsql { INSERT INTO t3 VALUES(1, NULL, 1) }
100963f0eedfSdrh  } {}
101063f0eedfSdrh
101163f0eedfSdrh  # Repeat for TEMP tables
101263f0eedfSdrh  #
101363f0eedfSdrh  drop_all_tables
101463f0eedfSdrh  do_test without_rowid3-14.1tmp.1 {
101563f0eedfSdrh    # Adding a column with a REFERENCES clause is not supported.
101663f0eedfSdrh    execsql {
101763f0eedfSdrh      CREATE TEMP TABLE t1(a PRIMARY KEY) WITHOUT rowid;
101863f0eedfSdrh      CREATE TEMP TABLE t2(a, b);
10199e5fdc41Sdrh      INSERT INTO temp.t2(a,b) VALUES(1,2);
102063f0eedfSdrh    }
102163f0eedfSdrh    catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
102263f0eedfSdrh  } {0 {}}
102363f0eedfSdrh  do_test without_rowid3-14.1tmp.2 {
102463f0eedfSdrh    catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
102563f0eedfSdrh  } {0 {}}
102663f0eedfSdrh  do_test without_rowid3-14.1tmp.3 {
102763f0eedfSdrh    catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}
102863f0eedfSdrh  } {0 {}}
102963f0eedfSdrh  do_test without_rowid3-14.1tmp.4 {
103063f0eedfSdrh    catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'}
103163f0eedfSdrh  } {1 {Cannot add a REFERENCES column with non-NULL default value}}
103263f0eedfSdrh  do_test without_rowid3-14.1tmp.5 {
103363f0eedfSdrh    catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 }
103463f0eedfSdrh  } {1 {Cannot add a REFERENCES column with non-NULL default value}}
103563f0eedfSdrh  do_test without_rowid3-14.1tmp.6 {
103663f0eedfSdrh    execsql {
103763f0eedfSdrh      PRAGMA foreign_keys = off;
103863f0eedfSdrh      ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
103963f0eedfSdrh      PRAGMA foreign_keys = on;
1040346a70caSdrh      SELECT sql FROM temp.sqlite_schema WHERE name='t2';
104163f0eedfSdrh    }
104263f0eedfSdrh  } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
104363f0eedfSdrh
1044171c50ecSdrh  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
104563f0eedfSdrh  do_test without_rowid3-14.2tmp.1.1 {
104663f0eedfSdrh    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
104763f0eedfSdrh  } {{CREATE TABLE t1(a REFERENCES "t3")}}
104863f0eedfSdrh  do_test without_rowid3-14.2tmp.1.2 {
104963f0eedfSdrh    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
105063f0eedfSdrh  } {{CREATE TABLE t1(a REFERENCES t2)}}
105163f0eedfSdrh  do_test without_rowid3-14.2tmp.1.3 {
105263f0eedfSdrh    test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
105363f0eedfSdrh  } {{CREATE TABLE t1(a REFERENCES "t3")}}
1054171c50ecSdrh  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
105563f0eedfSdrh
105663f0eedfSdrh  # Test ALTER TABLE RENAME TABLE a bit.
105763f0eedfSdrh  #
105863f0eedfSdrh  do_test without_rowid3-14.2tmp.2.1 {
105963f0eedfSdrh    drop_all_tables
106063f0eedfSdrh    execsql {
106163f0eedfSdrh      CREATE TEMP TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid;
106263f0eedfSdrh      CREATE TEMP TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)
106363f0eedfSdrh            WITHOUT rowid;
106463f0eedfSdrh      CREATE TEMP TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
106563f0eedfSdrh    }
1066346a70caSdrh    execsql { SELECT sql FROM sqlite_temp_schema WHERE type = 'table'}
106763f0eedfSdrh  } [list \
106863f0eedfSdrh    {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid}       \
106963f0eedfSdrh    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)
107063f0eedfSdrh            WITHOUT rowid}    \
107163f0eedfSdrh    {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)}  \
107263f0eedfSdrh  ]
107363f0eedfSdrh  do_test without_rowid3-14.2tmp.2.2 {
107463f0eedfSdrh    execsql { ALTER TABLE t1 RENAME TO t4 }
1075346a70caSdrh    execsql { SELECT sql FROM temp.sqlite_schema WHERE type = 'table'}
107663f0eedfSdrh  } [list \
107763f0eedfSdrh    {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid}      \
107863f0eedfSdrh    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)
107963f0eedfSdrh            WITHOUT rowid}     \
108063f0eedfSdrh    {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \
108163f0eedfSdrh  ]
108263f0eedfSdrh  do_test without_rowid3-14.2tmp.2.3 {
108363f0eedfSdrh    catchsql { INSERT INTO t3 VALUES(1, 2, 3) }
1084f9c8ce3cSdrh  } {1 {FOREIGN KEY constraint failed}}
108563f0eedfSdrh  do_test without_rowid3-14.2tmp.2.4 {
108663f0eedfSdrh    execsql { INSERT INTO t4 VALUES(1, NULL) }
108763f0eedfSdrh  } {}
108863f0eedfSdrh  do_test without_rowid3-14.2tmp.2.5 {
108963f0eedfSdrh    catchsql { UPDATE t4 SET b = 5 }
1090f9c8ce3cSdrh  } {1 {FOREIGN KEY constraint failed}}
109163f0eedfSdrh  do_test without_rowid3-14.2tmp.2.6 {
109263f0eedfSdrh    catchsql { UPDATE t4 SET b = 1 }
109363f0eedfSdrh  } {0 {}}
109463f0eedfSdrh  do_test without_rowid3-14.2tmp.2.7 {
109563f0eedfSdrh    execsql { INSERT INTO t3 VALUES(1, NULL, 1) }
109663f0eedfSdrh  } {}
109763f0eedfSdrh
109863f0eedfSdrh  # Repeat for ATTACH-ed tables
109963f0eedfSdrh  #
110063f0eedfSdrh  drop_all_tables
110163f0eedfSdrh  do_test without_rowid3-14.1aux.1 {
110263f0eedfSdrh    # Adding a column with a REFERENCES clause is not supported.
110363f0eedfSdrh    execsql {
110463f0eedfSdrh      ATTACH ':memory:' AS aux;
110563f0eedfSdrh      CREATE TABLE aux.t1(a PRIMARY KEY) WITHOUT rowid;
110663f0eedfSdrh      CREATE TABLE aux.t2(a, b);
11079e5fdc41Sdrh      INSERT INTO aux.t2(a,b) VALUES(1,2);
110863f0eedfSdrh    }
110963f0eedfSdrh    catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 }
111063f0eedfSdrh  } {0 {}}
111163f0eedfSdrh  do_test without_rowid3-14.1aux.2 {
111263f0eedfSdrh    catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 }
111363f0eedfSdrh  } {0 {}}
111463f0eedfSdrh  do_test without_rowid3-14.1aux.3 {
111563f0eedfSdrh    catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL}
111663f0eedfSdrh  } {0 {}}
111763f0eedfSdrh  do_test without_rowid3-14.1aux.4 {
111863f0eedfSdrh    catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'}
111963f0eedfSdrh  } {1 {Cannot add a REFERENCES column with non-NULL default value}}
112063f0eedfSdrh  do_test without_rowid3-14.1aux.5 {
112163f0eedfSdrh    catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 }
112263f0eedfSdrh  } {1 {Cannot add a REFERENCES column with non-NULL default value}}
112363f0eedfSdrh  do_test without_rowid3-14.1aux.6 {
112463f0eedfSdrh    execsql {
112563f0eedfSdrh      PRAGMA foreign_keys = off;
112663f0eedfSdrh      ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1;
112763f0eedfSdrh      PRAGMA foreign_keys = on;
1128346a70caSdrh      SELECT sql FROM aux.sqlite_schema WHERE name='t2';
112963f0eedfSdrh    }
113063f0eedfSdrh  } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}}
113163f0eedfSdrh
1132171c50ecSdrh  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
113363f0eedfSdrh  do_test without_rowid3-14.2aux.1.1 {
113463f0eedfSdrh    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3
113563f0eedfSdrh  } {{CREATE TABLE t1(a REFERENCES "t3")}}
113663f0eedfSdrh  do_test without_rowid3-14.2aux.1.2 {
113763f0eedfSdrh    test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3
113863f0eedfSdrh  } {{CREATE TABLE t1(a REFERENCES t2)}}
113963f0eedfSdrh  do_test without_rowid3-14.2aux.1.3 {
114063f0eedfSdrh    test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3
114163f0eedfSdrh  } {{CREATE TABLE t1(a REFERENCES "t3")}}
1142171c50ecSdrh  sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db
114363f0eedfSdrh
114463f0eedfSdrh  # Test ALTER TABLE RENAME TABLE a bit.
114563f0eedfSdrh  #
114663f0eedfSdrh  do_test without_rowid3-14.2aux.2.1 {
114763f0eedfSdrh    drop_all_tables
114863f0eedfSdrh    execsql {
114963f0eedfSdrh      CREATE TABLE aux.t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid;
115063f0eedfSdrh      CREATE TABLE aux.t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)
115163f0eedfSdrh            WITHOUT rowid;
115263f0eedfSdrh      CREATE TABLE aux.t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1);
115363f0eedfSdrh    }
1154346a70caSdrh    execsql { SELECT sql FROM aux.sqlite_schema WHERE type = 'table'}
115563f0eedfSdrh  } [list \
115663f0eedfSdrh    {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid}       \
115763f0eedfSdrh    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2)
115863f0eedfSdrh            WITHOUT rowid}    \
115963f0eedfSdrh    {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)}  \
116063f0eedfSdrh  ]
116163f0eedfSdrh  do_test without_rowid3-14.2aux.2.2 {
116263f0eedfSdrh    execsql { ALTER TABLE t1 RENAME TO t4 }
1163346a70caSdrh    execsql { SELECT sql FROM aux.sqlite_schema WHERE type = 'table'}
116463f0eedfSdrh  } [list \
116563f0eedfSdrh    {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid}      \
116663f0eedfSdrh    {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2)
116763f0eedfSdrh            WITHOUT rowid}     \
116863f0eedfSdrh    {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \
116963f0eedfSdrh  ]
117063f0eedfSdrh  do_test without_rowid3-14.2aux.2.3 {
117163f0eedfSdrh    catchsql { INSERT INTO t3 VALUES(1, 2, 3) }
1172f9c8ce3cSdrh  } {1 {FOREIGN KEY constraint failed}}
117363f0eedfSdrh  do_test without_rowid3-14.2aux.2.4 {
117463f0eedfSdrh    execsql { INSERT INTO t4 VALUES(1, NULL) }
117563f0eedfSdrh  } {}
117663f0eedfSdrh  do_test without_rowid3-14.2aux.2.5 {
117763f0eedfSdrh    catchsql { UPDATE t4 SET b = 5 }
1178f9c8ce3cSdrh  } {1 {FOREIGN KEY constraint failed}}
117963f0eedfSdrh  do_test without_rowid3-14.2aux.2.6 {
118063f0eedfSdrh    catchsql { UPDATE t4 SET b = 1 }
118163f0eedfSdrh  } {0 {}}
118263f0eedfSdrh  do_test without_rowid3-14.2aux.2.7 {
118363f0eedfSdrh    execsql { INSERT INTO t3 VALUES(1, NULL, 1) }
118463f0eedfSdrh  } {}
118563f0eedfSdrh}
118663f0eedfSdrh
118763f0eedfSdrhdo_test without_rowid3-2.14.3.1 {
118863f0eedfSdrh  drop_all_tables
118963f0eedfSdrh  execsql {
119063f0eedfSdrh    CREATE TABLE t1(a, b REFERENCES nosuchtable);
119163f0eedfSdrh    DROP TABLE t1;
119263f0eedfSdrh  }
119363f0eedfSdrh} {}
119463f0eedfSdrhdo_test without_rowid3-2.14.3.2 {
119563f0eedfSdrh  execsql {
119663f0eedfSdrh    CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT rowid;
119763f0eedfSdrh    INSERT INTO t1 VALUES('a', 1);
119863f0eedfSdrh    CREATE TABLE t2(x REFERENCES t1);
119963f0eedfSdrh    INSERT INTO t2 VALUES('a');
120063f0eedfSdrh  }
120163f0eedfSdrh} {}
120263f0eedfSdrhdo_test without_rowid3-2.14.3.3 {
120363f0eedfSdrh  catchsql { DROP TABLE t1 }
1204f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
120563f0eedfSdrhdo_test without_rowid3-2.14.3.4 {
120663f0eedfSdrh  execsql {
120763f0eedfSdrh    DELETE FROM t2;
120863f0eedfSdrh    DROP TABLE t1;
120963f0eedfSdrh  }
121063f0eedfSdrh} {}
121163f0eedfSdrhdo_test without_rowid3-2.14.3.4 {
121263f0eedfSdrh  catchsql { INSERT INTO t2 VALUES('x') }
121363f0eedfSdrh} {1 {no such table: main.t1}}
121463f0eedfSdrhdo_test without_rowid3-2.14.3.5 {
121563f0eedfSdrh  execsql {
121663f0eedfSdrh    CREATE TABLE t1(x PRIMARY KEY) WITHOUT rowid;
121763f0eedfSdrh    INSERT INTO t1 VALUES('x');
121863f0eedfSdrh  }
121963f0eedfSdrh  execsql { INSERT INTO t2 VALUES('x') }
122063f0eedfSdrh} {}
122163f0eedfSdrhdo_test without_rowid3-2.14.3.6 {
122263f0eedfSdrh  catchsql { DROP TABLE t1 }
1223f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
122463f0eedfSdrhdo_test without_rowid3-2.14.3.7 {
122563f0eedfSdrh  execsql {
122663f0eedfSdrh    DROP TABLE t2;
122763f0eedfSdrh    DROP TABLE t1;
122863f0eedfSdrh  }
122963f0eedfSdrh} {}
123063f0eedfSdrhdo_test without_rowid3-2.14.3.8 {
123163f0eedfSdrh  execsql {
123263f0eedfSdrh    CREATE TABLE pp(x, y, PRIMARY KEY(x, y)) WITHOUT ROWID;
123363f0eedfSdrh    CREATE TABLE cc(a, b, FOREIGN KEY(a, b) REFERENCES pp(x, z));
123463f0eedfSdrh  }
123563f0eedfSdrh  catchsql { INSERT INTO cc VALUES(1, 2) }
123663f0eedfSdrh} {1 {foreign key mismatch - "cc" referencing "pp"}}
123763f0eedfSdrhdo_test without_rowid3-2.14.3.9 {
123863f0eedfSdrh  execsql { DROP TABLE cc }
123963f0eedfSdrh} {}
124063f0eedfSdrhdo_test without_rowid3-2.14.3.10 {
124163f0eedfSdrh  execsql {
124263f0eedfSdrh    CREATE TABLE cc(a, b,
124363f0eedfSdrh      FOREIGN KEY(a, b) REFERENCES pp DEFERRABLE INITIALLY DEFERRED
124463f0eedfSdrh    );
124563f0eedfSdrh  }
124663f0eedfSdrh  execsql {
124763f0eedfSdrh    INSERT INTO pp VALUES('a', 'b');
124863f0eedfSdrh    INSERT INTO cc VALUES('a', 'b');
124963f0eedfSdrh    BEGIN;
125063f0eedfSdrh      DROP TABLE pp;
125163f0eedfSdrh      CREATE TABLE pp(a, b, c, PRIMARY KEY(b, c)) WITHOUT rowid;
125263f0eedfSdrh      INSERT INTO pp VALUES(1, 'a', 'b');
125363f0eedfSdrh    COMMIT;
125463f0eedfSdrh  }
125563f0eedfSdrh} {}
125663f0eedfSdrhdo_test without_rowid3-2.14.3.11 {
125763f0eedfSdrh  execsql {
125863f0eedfSdrh    BEGIN;
125963f0eedfSdrh      DROP TABLE cc;
126063f0eedfSdrh      DROP TABLE pp;
126163f0eedfSdrh    COMMIT;
126263f0eedfSdrh  }
126363f0eedfSdrh} {}
126463f0eedfSdrhdo_test without_rowid3-2.14.3.12 {
126563f0eedfSdrh  execsql {
126663f0eedfSdrh    CREATE TABLE b1(a, b);
126763f0eedfSdrh    CREATE TABLE b2(a, b REFERENCES b1);
126863f0eedfSdrh    DROP TABLE b1;
126963f0eedfSdrh  }
127063f0eedfSdrh} {}
127163f0eedfSdrhdo_test without_rowid3-2.14.3.13 {
127263f0eedfSdrh  execsql {
127363f0eedfSdrh    CREATE TABLE b3(a, b REFERENCES b2 DEFERRABLE INITIALLY DEFERRED);
127463f0eedfSdrh    DROP TABLE b2;
127563f0eedfSdrh  }
127663f0eedfSdrh} {}
127763f0eedfSdrh
127863f0eedfSdrh# Test that nothing goes wrong when dropping a table that refers to a view.
127963f0eedfSdrh# Or dropping a view that an existing FK (incorrectly) refers to. Or either
128063f0eedfSdrh# of the above scenarios with a virtual table.
128163f0eedfSdrhdrop_all_tables
128263f0eedfSdrhdo_test without_rowid3-2.14.4.1 {
128363f0eedfSdrh  execsql {
128463f0eedfSdrh    CREATE TABLE t1(x REFERENCES v);
128563f0eedfSdrh    CREATE VIEW v AS SELECT * FROM t1;
128663f0eedfSdrh  }
128763f0eedfSdrh} {}
128863f0eedfSdrhdo_test without_rowid3-2.14.4.2 {
128963f0eedfSdrh  execsql {
129063f0eedfSdrh    DROP VIEW v;
129163f0eedfSdrh  }
129263f0eedfSdrh} {}
129363f0eedfSdrhifcapable vtab {
129463f0eedfSdrh  register_echo_module db
129563f0eedfSdrh  do_test without_rowid3-2.14.4.3 {
129663f0eedfSdrh    execsql { CREATE VIRTUAL TABLE v USING echo(t1) }
129763f0eedfSdrh  } {}
129863f0eedfSdrh  do_test without_rowid3-2.14.4.2 {
129963f0eedfSdrh    execsql {
130063f0eedfSdrh      DROP TABLE v;
130163f0eedfSdrh    }
130263f0eedfSdrh  } {}
130363f0eedfSdrh}
130463f0eedfSdrh
130563f0eedfSdrh#-------------------------------------------------------------------------
130663f0eedfSdrh# The following tests, without_rowid3-15.*, test that unnecessary FK related scans
130763f0eedfSdrh# and lookups are avoided when the constraint counters are zero.
130863f0eedfSdrh#
130963f0eedfSdrhdrop_all_tables
131063f0eedfSdrhproc execsqlS {zSql} {
131163f0eedfSdrh  set ::sqlite_search_count 0
131263f0eedfSdrh  set ::sqlite_found_count 0
131363f0eedfSdrh  set res [uplevel [list execsql $zSql]]
131463f0eedfSdrh  concat [expr $::sqlite_found_count + $::sqlite_search_count] $res
131563f0eedfSdrh}
131663f0eedfSdrhdo_test without_rowid3-15.1.1 {
131763f0eedfSdrh  execsql {
131863f0eedfSdrh    CREATE TABLE pp(a PRIMARY KEY, b) WITHOUT rowid;
131963f0eedfSdrh    CREATE TABLE cc(x, y REFERENCES pp DEFERRABLE INITIALLY DEFERRED);
132063f0eedfSdrh    INSERT INTO pp VALUES(1, 'one');
132163f0eedfSdrh    INSERT INTO pp VALUES(2, 'two');
132263f0eedfSdrh    INSERT INTO cc VALUES('neung', 1);
132363f0eedfSdrh    INSERT INTO cc VALUES('song', 2);
132463f0eedfSdrh  }
132563f0eedfSdrh} {}
132663f0eedfSdrhdo_test without_rowid3-15.1.2 {
132763f0eedfSdrh  execsqlS { INSERT INTO pp VALUES(3, 'three') }
132863f0eedfSdrh} {0}
132963f0eedfSdrhdo_test without_rowid3-15.1.3 {
133063f0eedfSdrh  execsql {
133163f0eedfSdrh    BEGIN;
133263f0eedfSdrh      INSERT INTO cc VALUES('see', 4);    -- Violates deferred constraint
133363f0eedfSdrh  }
133463f0eedfSdrh  execsqlS { INSERT INTO pp VALUES(5, 'five') }
133563f0eedfSdrh} {2}
133663f0eedfSdrhdo_test without_rowid3-15.1.4 {
133763f0eedfSdrh  execsql { DELETE FROM cc WHERE x = 'see' }
133863f0eedfSdrh  execsqlS { INSERT INTO pp VALUES(6, 'six') }
133963f0eedfSdrh} {0}
134063f0eedfSdrhdo_test without_rowid3-15.1.5 {
134163f0eedfSdrh  execsql COMMIT
134263f0eedfSdrh} {}
134363f0eedfSdrhdo_test without_rowid3-15.1.6 {
134463f0eedfSdrh  execsql BEGIN
134563f0eedfSdrh  execsqlS {
134663f0eedfSdrh    DELETE FROM cc WHERE x = 'neung';
134763f0eedfSdrh    ROLLBACK;
134863f0eedfSdrh  }
134963f0eedfSdrh} {1}
135063f0eedfSdrhdo_test without_rowid3-15.1.7 {
135163f0eedfSdrh  execsql {
135263f0eedfSdrh    BEGIN;
135363f0eedfSdrh    DELETE FROM pp WHERE a = 2;
135463f0eedfSdrh  }
135563f0eedfSdrh  execsqlS {
135663f0eedfSdrh    DELETE FROM cc WHERE x = 'neung';
135763f0eedfSdrh    ROLLBACK;
135863f0eedfSdrh  }
135963f0eedfSdrh} {2}
136063f0eedfSdrh
136163f0eedfSdrh#-------------------------------------------------------------------------
136263f0eedfSdrh# This next block of tests, without_rowid3-16.*, test that rows that refer to
136363f0eedfSdrh# themselves may be inserted and deleted.
136463f0eedfSdrh#
136563f0eedfSdrhforeach {tn zSchema} {
136663f0eedfSdrh  1 { CREATE TABLE self(a INTEGER PRIMARY KEY, b REFERENCES self(a))
136763f0eedfSdrh             WITHOUT rowid }
136863f0eedfSdrh  2 { CREATE TABLE self(a PRIMARY KEY, b REFERENCES self(a)) WITHOUT rowid }
136963f0eedfSdrh  3 { CREATE TABLE self(a UNIQUE, b INT PRIMARY KEY REFERENCES self(a))
137063f0eedfSdrh             WITHOUT rowid }
137163f0eedfSdrh} {
137263f0eedfSdrh  drop_all_tables
137363f0eedfSdrh  do_test without_rowid3-16.1.$tn.1 {
137463f0eedfSdrh    execsql $zSchema
137563f0eedfSdrh    execsql { INSERT INTO self VALUES(13, 13) }
137663f0eedfSdrh  } {}
137763f0eedfSdrh  do_test without_rowid3-16.1.$tn.2 {
137863f0eedfSdrh    execsql { UPDATE self SET a = 14, b = 14 }
137963f0eedfSdrh  } {}
138063f0eedfSdrh
138163f0eedfSdrh  do_test without_rowid3-16.1.$tn.3 {
138263f0eedfSdrh    catchsql { UPDATE self SET b = 15 }
1383f9c8ce3cSdrh  } {1 {FOREIGN KEY constraint failed}}
138463f0eedfSdrh
138563f0eedfSdrh  do_test without_rowid3-16.1.$tn.4 {
138663f0eedfSdrh    catchsql { UPDATE self SET a = 15 }
1387f9c8ce3cSdrh  } {1 {FOREIGN KEY constraint failed}}
138863f0eedfSdrh
138963f0eedfSdrh  do_test without_rowid3-16.1.$tn.5 {
139063f0eedfSdrh    catchsql { UPDATE self SET a = 15, b = 16 }
1391f9c8ce3cSdrh  } {1 {FOREIGN KEY constraint failed}}
139263f0eedfSdrh
139363f0eedfSdrh  do_test without_rowid3-16.1.$tn.6 {
139463f0eedfSdrh    catchsql { UPDATE self SET a = 17, b = 17 }
139563f0eedfSdrh  } {0 {}}
139663f0eedfSdrh
139763f0eedfSdrh  do_test without_rowid3-16.1.$tn.7 {
139863f0eedfSdrh    execsql { DELETE FROM self }
139963f0eedfSdrh  } {}
140063f0eedfSdrh  do_test without_rowid3-16.1.$tn.8 {
140163f0eedfSdrh    catchsql { INSERT INTO self VALUES(20, 21) }
1402f9c8ce3cSdrh  } {1 {FOREIGN KEY constraint failed}}
140363f0eedfSdrh}
140463f0eedfSdrh
14056546af14Sdrh# Additional tests cases using multi-column self-referential
14066546af14Sdrh# FOREIGN KEY constraints.
14076546af14Sdrh#
14086546af14Sdrhdrop_all_tables
14096546af14Sdrhdo_execsql_test without_rowid3-16.4.1.1 {
14106546af14Sdrh  PRAGMA foreign_keys=ON;
14116546af14Sdrh  CREATE TABLE t1(a,b,c,d,e,f,
14126546af14Sdrh     UNIQUE (a,b),
14136546af14Sdrh     PRIMARY KEY (e,c),
14146546af14Sdrh     FOREIGN KEY (d,f) REFERENCES t1(e,c)
14156546af14Sdrh  ) WITHOUT rowid;
14166546af14Sdrh  INSERT INTO t1 VALUES(1,2,3,5,5,3);
14176546af14Sdrh  INSERT INTO t1 VALUES(2,3,4,6,6,4);
14186546af14Sdrh  INSERT INTO t1 VALUES('x','y',1.5,'fizzle','fizzle',1.5);
14196546af14Sdrh  SELECT *, '|' FROM t1 ORDER BY a, b;
14206546af14Sdrh} {1 2 3 5 5 3 | 2 3 4 6 6 4 | x y 1.5 fizzle fizzle 1.5 |}
14216546af14Sdrh
14226546af14Sdrhdo_execsql_test without_rowid3-16.4.1.2 {
14236546af14Sdrh  UPDATE t1 SET c=99, f=99 WHERE a=1;
14246546af14Sdrh  SELECT *, '|' FROM t1 ORDER BY a, b;
14256546af14Sdrh} {1 2 99 5 5 99 | 2 3 4 6 6 4 | x y 1.5 fizzle fizzle 1.5 |}
14266546af14Sdrh
14276546af14Sdrhdo_execsql_test without_rowid3-16.4.1.3 {
14286546af14Sdrh  UPDATE t1 SET e=876, d=876 WHERE a=2;
14296546af14Sdrh  SELECT *, '|' FROM t1 ORDER BY a, b;
14306546af14Sdrh} {1 2 99 5 5 99 | 2 3 4 876 876 4 | x y 1.5 fizzle fizzle 1.5 |}
14316546af14Sdrh
14326546af14Sdrhdo_test without_rowid3-16.4.1.4 {
14336546af14Sdrh  catchsql {
14346546af14Sdrh    UPDATE t1 SET c=11, e=22 WHERE a=1;
14356546af14Sdrh  }
1436f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
14376546af14Sdrh
14386546af14Sdrhdo_test without_rowid3-16.4.1.5 {
14396546af14Sdrh  catchsql {
14406546af14Sdrh    UPDATE t1 SET d=11, f=22 WHERE a=1;
14416546af14Sdrh  }
1442f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
14436546af14Sdrh
14446546af14Sdrhdo_execsql_test without_rowid3-16.4.1.6 {
14456546af14Sdrh  DELETE FROM t1 WHERE a=1;
14466546af14Sdrh  SELECT *, '|' FROM t1 ORDER BY a, b;
14476546af14Sdrh} {2 3 4 876 876 4 | x y 1.5 fizzle fizzle 1.5 |}
14486546af14Sdrh
14496546af14Sdrhdo_execsql_test without_rowid3-16.4.2.1 {
14506546af14Sdrh  DROP TABLE t1;
14516546af14Sdrh  CREATE TABLE t1(a,b,c,d,e,f,
14526546af14Sdrh     PRIMARY KEY (a,b),
14536546af14Sdrh     UNIQUE (e,c),
14546546af14Sdrh     FOREIGN KEY (d,f) REFERENCES t1(e,c)
14556546af14Sdrh  ) WITHOUT rowid;
14566546af14Sdrh  INSERT INTO t1 VALUES(1,2,3,5,5,3);
14576546af14Sdrh  INSERT INTO t1 VALUES(2,3,4,6,6,4);
14586546af14Sdrh  INSERT INTO t1 VALUES('x','y',1.5,'fizzle','fizzle',1.5);
14596546af14Sdrh  SELECT *, '|' FROM t1 ORDER BY a, b;
14606546af14Sdrh} {1 2 3 5 5 3 | 2 3 4 6 6 4 | x y 1.5 fizzle fizzle 1.5 |}
14616546af14Sdrh
14626546af14Sdrhdo_execsql_test without_rowid3-16.4.2.2 {
14636546af14Sdrh  UPDATE t1 SET c=99, f=99 WHERE a=1;
14646546af14Sdrh  SELECT *, '|' FROM t1 ORDER BY a, b;
14656546af14Sdrh} {1 2 99 5 5 99 | 2 3 4 6 6 4 | x y 1.5 fizzle fizzle 1.5 |}
14666546af14Sdrh
14676546af14Sdrhdo_execsql_test without_rowid3-16.4.2.3 {
14686546af14Sdrh  UPDATE t1 SET e=876, d=876 WHERE a=2;
14696546af14Sdrh  SELECT *, '|' FROM t1 ORDER BY a, b;
14706546af14Sdrh} {1 2 99 5 5 99 | 2 3 4 876 876 4 | x y 1.5 fizzle fizzle 1.5 |}
14716546af14Sdrh
14726546af14Sdrhdo_test without_rowid3-16.4.2.4 {
14736546af14Sdrh  catchsql {
14746546af14Sdrh    UPDATE t1 SET c=11, e=22 WHERE a=1;
14756546af14Sdrh  }
1476f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
14776546af14Sdrh
14786546af14Sdrhdo_test without_rowid3-16.4.2.5 {
14796546af14Sdrh  catchsql {
14806546af14Sdrh    UPDATE t1 SET d=11, f=22 WHERE a=1;
14816546af14Sdrh  }
1482f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
14836546af14Sdrh
14846546af14Sdrhdo_execsql_test without_rowid3-16.4.2.6 {
14856546af14Sdrh  DELETE FROM t1 WHERE a=1;
14866546af14Sdrh  SELECT *, '|' FROM t1 ORDER BY a, b;
14876546af14Sdrh} {2 3 4 876 876 4 | x y 1.5 fizzle fizzle 1.5 |}
14886546af14Sdrh
14896546af14Sdrh
149063f0eedfSdrh#-------------------------------------------------------------------------
149163f0eedfSdrh# This next block of tests, without_rowid3-17.*, tests that if "PRAGMA count_changes"
149263f0eedfSdrh# is turned on statements that violate immediate FK constraints return
149363f0eedfSdrh# SQLITE_CONSTRAINT immediately, not after returning a number of rows.
149463f0eedfSdrh# Whereas statements that violate deferred FK constraints return the number
149563f0eedfSdrh# of rows before failing.
149663f0eedfSdrh#
149763f0eedfSdrh# Also test that rows modified by FK actions are not counted in either the
149863f0eedfSdrh# returned row count or the values returned by sqlite3_changes(). Like
149963f0eedfSdrh# trigger related changes, they are included in sqlite3_total_changes() though.
150063f0eedfSdrh#
150163f0eedfSdrhdrop_all_tables
150263f0eedfSdrhdo_test without_rowid3-17.1.1 {
150363f0eedfSdrh  execsql { PRAGMA count_changes = 1 }
150463f0eedfSdrh  execsql {
150563f0eedfSdrh    CREATE TABLE one(a, b, c, UNIQUE(b, c));
150663f0eedfSdrh    CREATE TABLE two(d, e, f, FOREIGN KEY(e, f) REFERENCES one(b, c));
150763f0eedfSdrh    INSERT INTO one VALUES(1, 2, 3);
150863f0eedfSdrh  }
150963f0eedfSdrh} {1}
151063f0eedfSdrhdo_test without_rowid3-17.1.2 {
151163f0eedfSdrh  set STMT [sqlite3_prepare_v2 db "INSERT INTO two VALUES(4, 5, 6)" -1 dummy]
151263f0eedfSdrh  sqlite3_step $STMT
151363f0eedfSdrh} {SQLITE_CONSTRAINT}
151463f0eedfSdrhverify_ex_errcode without_rowid3-17.1.2b SQLITE_CONSTRAINT_FOREIGNKEY
151563f0eedfSdrhifcapable autoreset {
151663f0eedfSdrh  do_test without_rowid3-17.1.3 {
151763f0eedfSdrh    sqlite3_step $STMT
151863f0eedfSdrh  } {SQLITE_CONSTRAINT}
151963f0eedfSdrh  verify_ex_errcode without_rowid3-17.1.3b SQLITE_CONSTRAINT_FOREIGNKEY
152063f0eedfSdrh} else {
152163f0eedfSdrh  do_test without_rowid3-17.1.3 {
152263f0eedfSdrh    sqlite3_step $STMT
152363f0eedfSdrh  } {SQLITE_MISUSE}
152463f0eedfSdrh}
152563f0eedfSdrhdo_test without_rowid3-17.1.4 {
152663f0eedfSdrh  sqlite3_finalize $STMT
152763f0eedfSdrh} {SQLITE_CONSTRAINT}
152863f0eedfSdrhverify_ex_errcode without_rowid3-17.1.4b SQLITE_CONSTRAINT_FOREIGNKEY
152963f0eedfSdrhdo_test without_rowid3-17.1.5 {
153063f0eedfSdrh  execsql {
153163f0eedfSdrh    INSERT INTO one VALUES(2, 3, 4);
153263f0eedfSdrh    INSERT INTO one VALUES(3, 4, 5);
153363f0eedfSdrh    INSERT INTO two VALUES(1, 2, 3);
153463f0eedfSdrh    INSERT INTO two VALUES(2, 3, 4);
153563f0eedfSdrh    INSERT INTO two VALUES(3, 4, 5);
153663f0eedfSdrh  }
153763f0eedfSdrh} {1 1 1 1 1}
153863f0eedfSdrhdo_test without_rowid3-17.1.6 {
153963f0eedfSdrh  catchsql {
154063f0eedfSdrh    BEGIN;
154163f0eedfSdrh      INSERT INTO one VALUES(0, 0, 0);
154263f0eedfSdrh      UPDATE two SET e=e+1, f=f+1;
154363f0eedfSdrh  }
1544f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
154563f0eedfSdrhdo_test without_rowid3-17.1.7 {
154663f0eedfSdrh  execsql { SELECT * FROM one }
154763f0eedfSdrh} {1 2 3 2 3 4 3 4 5 0 0 0}
154863f0eedfSdrhdo_test without_rowid3-17.1.8 {
154963f0eedfSdrh  execsql { SELECT * FROM two }
155063f0eedfSdrh} {1 2 3 2 3 4 3 4 5}
155163f0eedfSdrhdo_test without_rowid3-17.1.9 {
155263f0eedfSdrh  execsql COMMIT
155363f0eedfSdrh} {}
155463f0eedfSdrhdo_test without_rowid3-17.1.10 {
155563f0eedfSdrh  execsql {
155663f0eedfSdrh    CREATE TABLE three(
155763f0eedfSdrh      g, h, i,
155863f0eedfSdrh      FOREIGN KEY(h, i) REFERENCES one(b, c) DEFERRABLE INITIALLY DEFERRED
155963f0eedfSdrh    );
156063f0eedfSdrh  }
156163f0eedfSdrh} {}
156263f0eedfSdrhdo_test without_rowid3-17.1.11 {
156363f0eedfSdrh  set STMT [sqlite3_prepare_v2 db "INSERT INTO three VALUES(7, 8, 9)" -1 dummy]
156463f0eedfSdrh  sqlite3_step $STMT
156563f0eedfSdrh} {SQLITE_ROW}
156663f0eedfSdrhdo_test without_rowid3-17.1.12 {
156763f0eedfSdrh  sqlite3_column_text $STMT 0
156863f0eedfSdrh} {1}
156963f0eedfSdrhdo_test without_rowid3-17.1.13 {
157063f0eedfSdrh  sqlite3_step $STMT
157163f0eedfSdrh} {SQLITE_CONSTRAINT}
157263f0eedfSdrhverify_ex_errcode without_rowid3-17.1.13b SQLITE_CONSTRAINT_FOREIGNKEY
157363f0eedfSdrhdo_test without_rowid3-17.1.14 {
157463f0eedfSdrh  sqlite3_finalize $STMT
157563f0eedfSdrh} {SQLITE_CONSTRAINT}
157663f0eedfSdrhverify_ex_errcode without_rowid3-17.1.14b SQLITE_CONSTRAINT_FOREIGNKEY
157763f0eedfSdrh
157863f0eedfSdrhdrop_all_tables
157963f0eedfSdrhdo_test without_rowid3-17.2.1 {
158063f0eedfSdrh  execsql {
158163f0eedfSdrh    CREATE TABLE high("a'b!" PRIMARY KEY, b) WITHOUT rowid;
158263f0eedfSdrh    CREATE TABLE low(
158363f0eedfSdrh      c,
158463f0eedfSdrh      "d&6" REFERENCES high ON UPDATE CASCADE ON DELETE CASCADE
158563f0eedfSdrh    );
158663f0eedfSdrh  }
158763f0eedfSdrh} {}
158863f0eedfSdrhdo_test without_rowid3-17.2.2 {
158963f0eedfSdrh  execsql {
159063f0eedfSdrh    INSERT INTO high VALUES('a', 'b');
159163f0eedfSdrh    INSERT INTO low VALUES('b', 'a');
159263f0eedfSdrh  }
159363f0eedfSdrh  db changes
159463f0eedfSdrh} {1}
159563f0eedfSdrhset nTotal [db total_changes]
159663f0eedfSdrhdo_test without_rowid3-17.2.3 {
159763f0eedfSdrh  execsql { UPDATE high SET "a'b!" = 'c' }
159863f0eedfSdrh} {1}
159963f0eedfSdrhdo_test without_rowid3-17.2.4 {
160063f0eedfSdrh  db changes
160163f0eedfSdrh} {1}
160263f0eedfSdrhdo_test without_rowid3-17.2.5 {
160363f0eedfSdrh  expr [db total_changes] - $nTotal
160463f0eedfSdrh} {2}
160563f0eedfSdrhdo_test without_rowid3-17.2.6 {
160663f0eedfSdrh  execsql { SELECT * FROM high ; SELECT * FROM low }
160763f0eedfSdrh} {c b b c}
160863f0eedfSdrhdo_test without_rowid3-17.2.7 {
160963f0eedfSdrh  execsql { DELETE FROM high }
161063f0eedfSdrh} {1}
161163f0eedfSdrhdo_test without_rowid3-17.2.8 {
161263f0eedfSdrh  db changes
161363f0eedfSdrh} {1}
161463f0eedfSdrhdo_test without_rowid3-17.2.9 {
161563f0eedfSdrh  expr [db total_changes] - $nTotal
161663f0eedfSdrh} {4}
161763f0eedfSdrhdo_test without_rowid3-17.2.10 {
161863f0eedfSdrh  execsql { SELECT * FROM high ; SELECT * FROM low }
161963f0eedfSdrh} {}
162063f0eedfSdrhexecsql { PRAGMA count_changes = 0 }
162163f0eedfSdrh
162263f0eedfSdrh#-------------------------------------------------------------------------
162363f0eedfSdrh# Test that the authorization callback works.
162463f0eedfSdrh#
162563f0eedfSdrh
162663f0eedfSdrhifcapable auth {
162763f0eedfSdrh  do_test without_rowid3-18.1 {
162863f0eedfSdrh    execsql {
162963f0eedfSdrh      CREATE TABLE long(a, b PRIMARY KEY, c) WITHOUT rowid;
163063f0eedfSdrh      CREATE TABLE short(d, e, f REFERENCES long);
163163f0eedfSdrh      CREATE TABLE mid(g, h, i REFERENCES long DEFERRABLE INITIALLY DEFERRED);
163263f0eedfSdrh    }
163363f0eedfSdrh  } {}
163463f0eedfSdrh
163532c6a48bSdrh  proc auth {args} {eval lappend ::authargs [lrange $args 0 4]; return SQLITE_OK}
163663f0eedfSdrh  db auth auth
163763f0eedfSdrh
163863f0eedfSdrh  # An insert on the parent table must read the child key of any deferred
163963f0eedfSdrh  # foreign key constraints. But not the child key of immediate constraints.
164063f0eedfSdrh  set authargs {}
164163f0eedfSdrh  do_test without_rowid3-18.2 {
164263f0eedfSdrh    execsql { INSERT INTO long VALUES(1, 2, 3) }
164363f0eedfSdrh    set authargs
164463f0eedfSdrh  } {SQLITE_INSERT long {} main {} SQLITE_READ mid i main {}}
164563f0eedfSdrh
164663f0eedfSdrh  # An insert on the child table of an immediate constraint must read the
164763f0eedfSdrh  # parent key columns (to see if it is a violation or not).
164863f0eedfSdrh  set authargs {}
164963f0eedfSdrh  do_test without_rowid3-18.3 {
165063f0eedfSdrh    execsql { INSERT INTO short VALUES(1, 3, 2) }
165163f0eedfSdrh    set authargs
165263f0eedfSdrh  } {SQLITE_INSERT short {} main {} SQLITE_READ long b main {}}
165363f0eedfSdrh
165463f0eedfSdrh  # As must an insert on the child table of a deferred constraint.
165563f0eedfSdrh  set authargs {}
165663f0eedfSdrh  do_test without_rowid3-18.4 {
165763f0eedfSdrh    execsql { INSERT INTO mid VALUES(1, 3, 2) }
165863f0eedfSdrh    set authargs
165963f0eedfSdrh  } {SQLITE_INSERT mid {} main {} SQLITE_READ long b main {}}
166063f0eedfSdrh
166163f0eedfSdrh  do_test without_rowid3-18.5 {
166263f0eedfSdrh    execsql {
166363f0eedfSdrh      CREATE TABLE nought(a, b PRIMARY KEY, c) WITHOUT rowid;
166463f0eedfSdrh      CREATE TABLE cross(d, e, f,
166563f0eedfSdrh        FOREIGN KEY(e) REFERENCES nought(b) ON UPDATE CASCADE
166663f0eedfSdrh      );
166763f0eedfSdrh    }
166863f0eedfSdrh    execsql { INSERT INTO nought VALUES(2, 1, 2) }
166963f0eedfSdrh    execsql { INSERT INTO cross VALUES(0, 1, 0) }
167063f0eedfSdrh    set authargs [list]
167163f0eedfSdrh    execsql { UPDATE nought SET b = 5 }
167263f0eedfSdrh    set authargs
167363f0eedfSdrh  } {SQLITE_UPDATE nought b main {} SQLITE_READ cross e main {} SQLITE_READ cross e main {} SQLITE_READ nought b main {} SQLITE_READ nought b main {} SQLITE_READ nought b main {} SQLITE_UPDATE cross e main {} SQLITE_READ nought b main {} SQLITE_READ cross e main {} SQLITE_READ nought b main {} SQLITE_READ nought b main {}}
167463f0eedfSdrh
167563f0eedfSdrh  do_test without_rowid3-18.6 {
167663f0eedfSdrh    execsql {SELECT * FROM cross}
167763f0eedfSdrh  } {0 5 0}
167863f0eedfSdrh
167963f0eedfSdrh  do_test without_rowid3-18.7 {
168063f0eedfSdrh    execsql {
168163f0eedfSdrh      CREATE TABLE one(a INT PRIMARY KEY, b) WITHOUT rowid;
168263f0eedfSdrh      CREATE TABLE two(b, c REFERENCES one);
168363f0eedfSdrh      INSERT INTO one VALUES(101, 102);
168463f0eedfSdrh    }
168563f0eedfSdrh    set authargs [list]
168663f0eedfSdrh    execsql { INSERT INTO two VALUES(100, 101); }
168763f0eedfSdrh    set authargs
168863f0eedfSdrh  } {SQLITE_INSERT two {} main {} SQLITE_READ one a main {}}
168963f0eedfSdrh
169063f0eedfSdrh  # Return SQLITE_IGNORE to requests to read from the parent table. This
169163f0eedfSdrh  # causes inserts of non-NULL keys into the child table to fail.
169263f0eedfSdrh  #
169363f0eedfSdrh  rename auth {}
169463f0eedfSdrh  proc auth {args} {
169563f0eedfSdrh    if {[lindex $args 1] == "long"} {return SQLITE_IGNORE}
169663f0eedfSdrh    return SQLITE_OK
169763f0eedfSdrh  }
169863f0eedfSdrh  do_test without_rowid3-18.8 {
169963f0eedfSdrh    catchsql { INSERT INTO short VALUES(1, 3, 2) }
1700f9c8ce3cSdrh  } {1 {FOREIGN KEY constraint failed}}
170163f0eedfSdrh  do_test without_rowid3-18.9 {
170263f0eedfSdrh    execsql { INSERT INTO short VALUES(1, 3, NULL) }
170363f0eedfSdrh  } {}
170463f0eedfSdrh  do_test without_rowid3-18.10 {
170563f0eedfSdrh    execsql { SELECT * FROM short }
170663f0eedfSdrh  } {1 3 2 1 3 {}}
170763f0eedfSdrh  do_test without_rowid3-18.11 {
170863f0eedfSdrh    catchsql { UPDATE short SET f = 2 WHERE f IS NULL }
1709f9c8ce3cSdrh  } {1 {FOREIGN KEY constraint failed}}
171063f0eedfSdrh
171163f0eedfSdrh  db auth {}
171263f0eedfSdrh  unset authargs
171363f0eedfSdrh}
171463f0eedfSdrh
171563f0eedfSdrh
171663f0eedfSdrhdo_test without_rowid3-19.1 {
171763f0eedfSdrh  execsql {
171863f0eedfSdrh    CREATE TABLE main(id INT PRIMARY KEY) WITHOUT rowid;
171963f0eedfSdrh    CREATE TABLE sub(id INT REFERENCES main(id));
172063f0eedfSdrh    INSERT INTO main VALUES(1);
172163f0eedfSdrh    INSERT INTO main VALUES(2);
172263f0eedfSdrh    INSERT INTO sub VALUES(2);
172363f0eedfSdrh  }
172463f0eedfSdrh} {}
172563f0eedfSdrhdo_test without_rowid3-19.2 {
172663f0eedfSdrh  set S [sqlite3_prepare_v2 db "DELETE FROM main WHERE id = ?" -1 dummy]
172763f0eedfSdrh  sqlite3_bind_int $S 1 2
172863f0eedfSdrh  sqlite3_step $S
172963f0eedfSdrh} {SQLITE_CONSTRAINT}
173063f0eedfSdrhverify_ex_errcode without_rowid3-19.2b SQLITE_CONSTRAINT_FOREIGNKEY
173163f0eedfSdrhdo_test without_rowid3-19.3 {
173263f0eedfSdrh  sqlite3_reset $S
173363f0eedfSdrh} {SQLITE_CONSTRAINT}
173463f0eedfSdrhverify_ex_errcode without_rowid3-19.3b SQLITE_CONSTRAINT_FOREIGNKEY
173563f0eedfSdrhdo_test without_rowid3-19.4 {
173663f0eedfSdrh  sqlite3_bind_int $S 1 1
173763f0eedfSdrh  sqlite3_step $S
173863f0eedfSdrh} {SQLITE_DONE}
173963f0eedfSdrhdo_test without_rowid3-19.4 {
174063f0eedfSdrh  sqlite3_finalize $S
174163f0eedfSdrh} {SQLITE_OK}
174263f0eedfSdrh
174363f0eedfSdrhdrop_all_tables
174463f0eedfSdrhdo_test without_rowid3-20.1 {
174563f0eedfSdrh  execsql {
174663f0eedfSdrh    CREATE TABLE pp(a PRIMARY KEY, b) WITHOUT rowid;
174763f0eedfSdrh    CREATE TABLE cc(c PRIMARY KEY, d REFERENCES pp) WITHOUT rowid;
174863f0eedfSdrh  }
174963f0eedfSdrh} {}
175063f0eedfSdrh
175163f0eedfSdrhforeach {tn insert} {
175263f0eedfSdrh  1 "INSERT"
175363f0eedfSdrh  2 "INSERT OR IGNORE"
175463f0eedfSdrh  3 "INSERT OR ABORT"
175563f0eedfSdrh  4 "INSERT OR ROLLBACK"
175663f0eedfSdrh  5 "INSERT OR REPLACE"
175763f0eedfSdrh  6 "INSERT OR FAIL"
175863f0eedfSdrh} {
175963f0eedfSdrh  do_test without_rowid3-20.2.$tn.1 {
176063f0eedfSdrh    catchsql "$insert INTO cc VALUES(1, 2)"
1761f9c8ce3cSdrh  } {1 {FOREIGN KEY constraint failed}}
176263f0eedfSdrh  do_test without_rowid3-20.2.$tn.2 {
176363f0eedfSdrh    execsql { SELECT * FROM cc }
176463f0eedfSdrh  } {}
176563f0eedfSdrh  do_test without_rowid3-20.2.$tn.3 {
176663f0eedfSdrh    execsql {
176763f0eedfSdrh      BEGIN;
176863f0eedfSdrh        INSERT INTO pp VALUES(2, 'two');
176963f0eedfSdrh        INSERT INTO cc VALUES(1, 2);
177063f0eedfSdrh    }
177163f0eedfSdrh    catchsql "$insert INTO cc VALUES(3, 4)"
1772f9c8ce3cSdrh  } {1 {FOREIGN KEY constraint failed}}
177363f0eedfSdrh  do_test without_rowid3-20.2.$tn.4 {
177463f0eedfSdrh    execsql { COMMIT ; SELECT * FROM cc }
177563f0eedfSdrh  } {1 2}
177663f0eedfSdrh  do_test without_rowid3-20.2.$tn.5 {
177763f0eedfSdrh    execsql { DELETE FROM cc ; DELETE FROM pp }
177863f0eedfSdrh  } {}
177963f0eedfSdrh}
178063f0eedfSdrh
178163f0eedfSdrhforeach {tn update} {
178263f0eedfSdrh  1 "UPDATE"
178363f0eedfSdrh  2 "UPDATE OR IGNORE"
178463f0eedfSdrh  3 "UPDATE OR ABORT"
178563f0eedfSdrh  4 "UPDATE OR ROLLBACK"
178663f0eedfSdrh  5 "UPDATE OR REPLACE"
178763f0eedfSdrh  6 "UPDATE OR FAIL"
178863f0eedfSdrh} {
178963f0eedfSdrh  do_test without_rowid3-20.3.$tn.1 {
179063f0eedfSdrh    execsql {
179163f0eedfSdrh      INSERT INTO pp VALUES(2, 'two');
179263f0eedfSdrh      INSERT INTO cc VALUES(1, 2);
179363f0eedfSdrh    }
179463f0eedfSdrh  } {}
179563f0eedfSdrh  do_test without_rowid3-20.3.$tn.2 {
179663f0eedfSdrh    catchsql "$update pp SET a = 1"
1797f9c8ce3cSdrh  } {1 {FOREIGN KEY constraint failed}}
179863f0eedfSdrh  do_test without_rowid3-20.3.$tn.3 {
179963f0eedfSdrh    execsql { SELECT * FROM pp }
180063f0eedfSdrh  } {2 two}
180163f0eedfSdrh  do_test without_rowid3-20.3.$tn.4 {
180263f0eedfSdrh    catchsql "$update cc SET d = 1"
1803f9c8ce3cSdrh  } {1 {FOREIGN KEY constraint failed}}
180463f0eedfSdrh  do_test without_rowid3-20.3.$tn.5 {
180563f0eedfSdrh    execsql { SELECT * FROM cc }
180663f0eedfSdrh  } {1 2}
180763f0eedfSdrh  do_test without_rowid3-20.3.$tn.6 {
180863f0eedfSdrh    execsql {
180963f0eedfSdrh      BEGIN;
181063f0eedfSdrh        INSERT INTO pp VALUES(3, 'three');
181163f0eedfSdrh    }
181263f0eedfSdrh    catchsql "$update pp SET a = 1 WHERE a = 2"
1813f9c8ce3cSdrh  } {1 {FOREIGN KEY constraint failed}}
181463f0eedfSdrh  do_test without_rowid3-20.3.$tn.7 {
181563f0eedfSdrh    execsql { COMMIT ; SELECT * FROM pp }
181663f0eedfSdrh  } {2 two 3 three}
181763f0eedfSdrh  do_test without_rowid3-20.3.$tn.8 {
181863f0eedfSdrh    execsql {
181963f0eedfSdrh      BEGIN;
182063f0eedfSdrh        INSERT INTO cc VALUES(2, 2);
182163f0eedfSdrh    }
182263f0eedfSdrh    catchsql "$update cc SET d = 1 WHERE c = 1"
1823f9c8ce3cSdrh  } {1 {FOREIGN KEY constraint failed}}
182463f0eedfSdrh  do_test without_rowid3-20.3.$tn.9 {
182563f0eedfSdrh    execsql { COMMIT ; SELECT * FROM cc }
182663f0eedfSdrh  } {1 2 2 2}
182763f0eedfSdrh  do_test without_rowid3-20.3.$tn.10 {
182863f0eedfSdrh    execsql { DELETE FROM cc ; DELETE FROM pp }
182963f0eedfSdrh  } {}
183063f0eedfSdrh}
183163f0eedfSdrh
183263f0eedfSdrh#-------------------------------------------------------------------------
183363f0eedfSdrh# The following block of tests, those prefixed with "without_rowid3-genfkey.",
183463f0eedfSdrh# are the same tests that were used to test the ".genfkey" command provided
183563f0eedfSdrh# by the shell tool. So these tests show that the built-in foreign key
183663f0eedfSdrh# implementation is more or less compatible with the triggers generated
183763f0eedfSdrh# by genfkey.
183863f0eedfSdrh#
183963f0eedfSdrhdrop_all_tables
184063f0eedfSdrhdo_test without_rowid3-genfkey.1.1 {
184163f0eedfSdrh  execsql {
184263f0eedfSdrh    CREATE TABLE t1(a INT PRIMARY KEY, b, c, UNIQUE(b, c)) WITHOUT rowid;
184363f0eedfSdrh    CREATE TABLE t2(e REFERENCES t1, f);
184463f0eedfSdrh    CREATE TABLE t3(g, h, i, FOREIGN KEY (h, i) REFERENCES t1(b, c));
184563f0eedfSdrh  }
184663f0eedfSdrh} {}
184763f0eedfSdrhdo_test without_rowid3-genfkey.1.2 {
184863f0eedfSdrh  catchsql { INSERT INTO t2 VALUES(1, 2) }
1849f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
185063f0eedfSdrhdo_test without_rowid3-genfkey.1.3 {
185163f0eedfSdrh  execsql {
185263f0eedfSdrh    INSERT INTO t1 VALUES(1, 2, 3);
185363f0eedfSdrh    INSERT INTO t2 VALUES(1, 2);
185463f0eedfSdrh  }
185563f0eedfSdrh} {}
185663f0eedfSdrhdo_test without_rowid3-genfkey.1.4 {
185763f0eedfSdrh  execsql { INSERT INTO t2 VALUES(NULL, 3) }
185863f0eedfSdrh} {}
185963f0eedfSdrhdo_test without_rowid3-genfkey.1.5 {
186063f0eedfSdrh  catchsql { UPDATE t2 SET e = 5 WHERE e IS NULL }
1861f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
186263f0eedfSdrhdo_test without_rowid3-genfkey.1.6 {
186363f0eedfSdrh  execsql { UPDATE t2 SET e = 1 WHERE e IS NULL }
186463f0eedfSdrh} {}
186563f0eedfSdrhdo_test without_rowid3-genfkey.1.7 {
186663f0eedfSdrh  execsql { UPDATE t2 SET e = NULL WHERE f = 3 }
186763f0eedfSdrh} {}
186863f0eedfSdrhdo_test without_rowid3-genfkey.1.8 {
186963f0eedfSdrh  catchsql { UPDATE t1 SET a = 10 }
1870f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
187163f0eedfSdrhdo_test without_rowid3-genfkey.1.9 {
187263f0eedfSdrh  catchsql { UPDATE t1 SET a = NULL }
1873f9c8ce3cSdrh} {1 {NOT NULL constraint failed: t1.a}}
187463f0eedfSdrhdo_test without_rowid3-genfkey.1.10 {
187563f0eedfSdrh  catchsql { DELETE FROM t1 }
1876f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
187763f0eedfSdrhdo_test without_rowid3-genfkey.1.11 {
187863f0eedfSdrh  execsql { UPDATE t2 SET e = NULL }
187963f0eedfSdrh} {}
188063f0eedfSdrhdo_test without_rowid3-genfkey.1.12 {
188163f0eedfSdrh  execsql {
188263f0eedfSdrh    UPDATE t1 SET a = 10;
188363f0eedfSdrh    DELETE FROM t1;
188463f0eedfSdrh    DELETE FROM t2;
188563f0eedfSdrh  }
188663f0eedfSdrh} {}
188763f0eedfSdrhdo_test without_rowid3-genfkey.1.13 {
188863f0eedfSdrh  execsql {
188963f0eedfSdrh    INSERT INTO t3 VALUES(1, NULL, NULL);
189063f0eedfSdrh    INSERT INTO t3 VALUES(1, 2, NULL);
189163f0eedfSdrh    INSERT INTO t3 VALUES(1, NULL, 3);
189263f0eedfSdrh  }
189363f0eedfSdrh} {}
189463f0eedfSdrhdo_test without_rowid3-genfkey.1.14 {
189563f0eedfSdrh  catchsql { INSERT INTO t3 VALUES(3, 1, 4) }
1896f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
189763f0eedfSdrhdo_test without_rowid3-genfkey.1.15 {
189863f0eedfSdrh  execsql {
189963f0eedfSdrh    INSERT INTO t1 VALUES(1, 1, 4);
190063f0eedfSdrh    INSERT INTO t3 VALUES(3, 1, 4);
190163f0eedfSdrh  }
190263f0eedfSdrh} {}
190363f0eedfSdrhdo_test without_rowid3-genfkey.1.16 {
190463f0eedfSdrh  catchsql { DELETE FROM t1 }
1905f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
190663f0eedfSdrhdo_test without_rowid3-genfkey.1.17 {
190763f0eedfSdrh  catchsql { UPDATE t1 SET b = 10}
1908f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
190963f0eedfSdrhdo_test without_rowid3-genfkey.1.18 {
191063f0eedfSdrh  execsql { UPDATE t1 SET a = 10}
191163f0eedfSdrh} {}
191263f0eedfSdrhdo_test without_rowid3-genfkey.1.19 {
191363f0eedfSdrh  catchsql { UPDATE t3 SET h = 'hello' WHERE i = 3}
1914f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
191563f0eedfSdrh
191663f0eedfSdrhdrop_all_tables
191763f0eedfSdrhdo_test without_rowid3-genfkey.2.1 {
191863f0eedfSdrh  execsql {
191963f0eedfSdrh    CREATE TABLE t1(a INT PRIMARY KEY, b, c, UNIQUE(b, c)) WITHOUT rowid;
192063f0eedfSdrh    CREATE TABLE t2(e REFERENCES t1 ON UPDATE CASCADE ON DELETE CASCADE, f);
192163f0eedfSdrh    CREATE TABLE t3(g, h, i,
192263f0eedfSdrh        FOREIGN KEY (h, i)
192363f0eedfSdrh        REFERENCES t1(b, c) ON UPDATE CASCADE ON DELETE CASCADE
192463f0eedfSdrh    );
192563f0eedfSdrh  }
192663f0eedfSdrh} {}
192763f0eedfSdrhdo_test without_rowid3-genfkey.2.2 {
192863f0eedfSdrh  execsql {
192963f0eedfSdrh    INSERT INTO t1 VALUES(1, 2, 3);
193063f0eedfSdrh    INSERT INTO t1 VALUES(4, 5, 6);
193163f0eedfSdrh    INSERT INTO t2 VALUES(1, 'one');
193263f0eedfSdrh    INSERT INTO t2 VALUES(4, 'four');
193363f0eedfSdrh  }
193463f0eedfSdrh} {}
193563f0eedfSdrhdo_test without_rowid3-genfkey.2.3 {
193663f0eedfSdrh  execsql {
193763f0eedfSdrh    UPDATE t1 SET a = 2 WHERE a = 1;
193863f0eedfSdrh    SELECT * FROM t2;
193963f0eedfSdrh  }
194063f0eedfSdrh} {2 one 4 four}
194163f0eedfSdrhdo_test without_rowid3-genfkey.2.4 {
194263f0eedfSdrh  execsql {
194363f0eedfSdrh    DELETE FROM t1 WHERE a = 4;
194463f0eedfSdrh    SELECT * FROM t2;
194563f0eedfSdrh  }
194663f0eedfSdrh} {2 one}
194763f0eedfSdrh
194863f0eedfSdrhdo_test without_rowid3-genfkey.2.5 {
194963f0eedfSdrh  execsql {
195063f0eedfSdrh    INSERT INTO t3 VALUES('hello', 2, 3);
195163f0eedfSdrh    UPDATE t1 SET c = 2;
195263f0eedfSdrh    SELECT * FROM t3;
195363f0eedfSdrh  }
195463f0eedfSdrh} {hello 2 2}
195563f0eedfSdrhdo_test without_rowid3-genfkey.2.6 {
195663f0eedfSdrh  execsql {
195763f0eedfSdrh    DELETE FROM t1;
195863f0eedfSdrh    SELECT * FROM t3;
195963f0eedfSdrh  }
196063f0eedfSdrh} {}
196163f0eedfSdrh
196263f0eedfSdrhdrop_all_tables
196363f0eedfSdrhdo_test without_rowid3-genfkey.3.1 {
196463f0eedfSdrh  execsql {
196563f0eedfSdrh    CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, UNIQUE(c, b)) WITHOUT rowid;
196663f0eedfSdrh    CREATE TABLE t2(e REFERENCES t1 ON UPDATE SET NULL ON DELETE SET NULL, f);
196763f0eedfSdrh    CREATE TABLE t3(g, h, i,
196863f0eedfSdrh        FOREIGN KEY (h, i)
196963f0eedfSdrh        REFERENCES t1(b, c) ON UPDATE SET NULL ON DELETE SET NULL
197063f0eedfSdrh    );
197163f0eedfSdrh  }
197263f0eedfSdrh} {}
197363f0eedfSdrhdo_test without_rowid3-genfkey.3.2 {
197463f0eedfSdrh  execsql {
197563f0eedfSdrh    INSERT INTO t1 VALUES(1, 2, 3);
197663f0eedfSdrh    INSERT INTO t1 VALUES(4, 5, 6);
197763f0eedfSdrh    INSERT INTO t2 VALUES(1, 'one');
197863f0eedfSdrh    INSERT INTO t2 VALUES(4, 'four');
197963f0eedfSdrh  }
198063f0eedfSdrh} {}
198163f0eedfSdrhdo_test without_rowid3-genfkey.3.3 {
198263f0eedfSdrh  execsql {
198363f0eedfSdrh    UPDATE t1 SET a = 2 WHERE a = 1;
198463f0eedfSdrh    SELECT * FROM t2;
198563f0eedfSdrh  }
198663f0eedfSdrh} {{} one 4 four}
198763f0eedfSdrhdo_test without_rowid3-genfkey.3.4 {
198863f0eedfSdrh  execsql {
198963f0eedfSdrh    DELETE FROM t1 WHERE a = 4;
199063f0eedfSdrh    SELECT * FROM t2;
199163f0eedfSdrh  }
199263f0eedfSdrh} {{} one {} four}
199363f0eedfSdrhdo_test without_rowid3-genfkey.3.5 {
199463f0eedfSdrh  execsql {
199563f0eedfSdrh    INSERT INTO t3 VALUES('hello', 2, 3);
199663f0eedfSdrh    UPDATE t1 SET c = 2;
199763f0eedfSdrh    SELECT * FROM t3;
199863f0eedfSdrh  }
199963f0eedfSdrh} {hello {} {}}
200063f0eedfSdrhdo_test without_rowid3-genfkey.3.6 {
200163f0eedfSdrh  execsql {
200263f0eedfSdrh    UPDATE t3 SET h = 2, i = 2;
200363f0eedfSdrh    DELETE FROM t1;
200463f0eedfSdrh    SELECT * FROM t3;
200563f0eedfSdrh  }
200663f0eedfSdrh} {hello {} {}}
200763f0eedfSdrh
200863f0eedfSdrh#-------------------------------------------------------------------------
200963f0eedfSdrh# Verify that ticket dd08e5a988d00decc4a543daa8dbbfab9c577ad8 has been
201063f0eedfSdrh# fixed.
201163f0eedfSdrh#
201263f0eedfSdrhdo_test without_rowid3-dd08e5.1.1 {
201363f0eedfSdrh  execsql {
201463f0eedfSdrh    PRAGMA foreign_keys=ON;
201563f0eedfSdrh    CREATE TABLE tdd08(a INTEGER PRIMARY KEY, b) WITHOUT rowid;
201663f0eedfSdrh    CREATE UNIQUE INDEX idd08 ON tdd08(a,b);
201763f0eedfSdrh    INSERT INTO tdd08 VALUES(200,300);
201863f0eedfSdrh
201963f0eedfSdrh    CREATE TABLE tdd08_b(w,x,y, FOREIGN KEY(x,y) REFERENCES tdd08(a,b));
202063f0eedfSdrh    INSERT INTO tdd08_b VALUES(100,200,300);
202163f0eedfSdrh  }
202263f0eedfSdrh} {}
202363f0eedfSdrhdo_test without_rowid3-dd08e5.1.2 {
202463f0eedfSdrh  catchsql {
202563f0eedfSdrh    DELETE FROM tdd08;
202663f0eedfSdrh  }
2027f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
202863f0eedfSdrhdo_test without_rowid3-dd08e5.1.3 {
202963f0eedfSdrh  execsql {
203063f0eedfSdrh    SELECT * FROM tdd08;
203163f0eedfSdrh  }
203263f0eedfSdrh} {200 300}
203363f0eedfSdrhdo_test without_rowid3-dd08e5.1.4 {
203463f0eedfSdrh  catchsql {
203563f0eedfSdrh    INSERT INTO tdd08_b VALUES(400,500,300);
203663f0eedfSdrh  }
2037f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
203863f0eedfSdrhdo_test without_rowid3-dd08e5.1.5 {
203963f0eedfSdrh  catchsql {
204063f0eedfSdrh    UPDATE tdd08_b SET x=x+1;
204163f0eedfSdrh  }
2042f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
204363f0eedfSdrhdo_test without_rowid3-dd08e5.1.6 {
204463f0eedfSdrh  catchsql {
204563f0eedfSdrh    UPDATE tdd08 SET a=a+1;
204663f0eedfSdrh  }
2047f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
204863f0eedfSdrh
204963f0eedfSdrh#-------------------------------------------------------------------------
205063f0eedfSdrh# Verify that ticket ce7c133ea6cc9ccdc1a60d80441f80b6180f5eba
205163f0eedfSdrh# fixed.
205263f0eedfSdrh#
205363f0eedfSdrhdo_test without_rowid3-ce7c13.1.1 {
205463f0eedfSdrh  execsql {
205563f0eedfSdrh    CREATE TABLE tce71(a INTEGER PRIMARY KEY, b) WITHOUT rowid;
205663f0eedfSdrh    CREATE UNIQUE INDEX ice71 ON tce71(a,b);
205763f0eedfSdrh    INSERT INTO tce71 VALUES(100,200);
205863f0eedfSdrh    CREATE TABLE tce72(w, x, y, FOREIGN KEY(x,y) REFERENCES tce71(a,b));
205963f0eedfSdrh    INSERT INTO tce72 VALUES(300,100,200);
206063f0eedfSdrh    UPDATE tce71 set b = 200 where a = 100;
206163f0eedfSdrh    SELECT * FROM tce71, tce72;
206263f0eedfSdrh  }
206363f0eedfSdrh} {100 200 300 100 200}
206463f0eedfSdrhdo_test without_rowid3-ce7c13.1.2 {
206563f0eedfSdrh  catchsql {
206663f0eedfSdrh    UPDATE tce71 set b = 201 where a = 100;
206763f0eedfSdrh  }
2068f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
206963f0eedfSdrhdo_test without_rowid3-ce7c13.1.3 {
207063f0eedfSdrh  catchsql {
207163f0eedfSdrh    UPDATE tce71 set a = 101 where a = 100;
207263f0eedfSdrh  }
2073f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
207463f0eedfSdrhdo_test without_rowid3-ce7c13.1.4 {
207563f0eedfSdrh  execsql {
207663f0eedfSdrh    CREATE TABLE tce73(a INTEGER PRIMARY KEY, b, UNIQUE(a,b)) WITHOUT rowid;
207763f0eedfSdrh    INSERT INTO tce73 VALUES(100,200);
207863f0eedfSdrh    CREATE TABLE tce74(w, x, y, FOREIGN KEY(x,y) REFERENCES tce73(a,b));
207963f0eedfSdrh    INSERT INTO tce74 VALUES(300,100,200);
208063f0eedfSdrh    UPDATE tce73 set b = 200 where a = 100;
208163f0eedfSdrh    SELECT * FROM tce73, tce74;
208263f0eedfSdrh  }
208363f0eedfSdrh} {100 200 300 100 200}
208463f0eedfSdrhdo_test without_rowid3-ce7c13.1.5 {
208563f0eedfSdrh  catchsql {
208663f0eedfSdrh    UPDATE tce73 set b = 201 where a = 100;
208763f0eedfSdrh  }
2088f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
208963f0eedfSdrhdo_test without_rowid3-ce7c13.1.6 {
209063f0eedfSdrh  catchsql {
209163f0eedfSdrh    UPDATE tce73 set a = 101 where a = 100;
209263f0eedfSdrh  }
2093f9c8ce3cSdrh} {1 {FOREIGN KEY constraint failed}}
209463f0eedfSdrh
209541b9ca25Sdrh# Confirm that changes() works on WITHOUT ROWID tables that use the
209641b9ca25Sdrh# xfer optimization.
209741b9ca25Sdrh#
209841b9ca25Sdrhdb close
209941b9ca25Sdrhsqlite3 db :memory:
210041b9ca25Sdrhdo_execsql_test without_rowid3-30.1 {
210141b9ca25Sdrh  CREATE TABLE t1(a,b,PRIMARY KEY(a,b)) WITHOUT ROWID;
210241b9ca25Sdrh  CREATE TABLE t2(a,b,PRIMARY KEY(a,b)) WITHOUT ROWID;
210341b9ca25Sdrh  INSERT INTO t1 VALUES(1,2),(3,4),(5,6);
210441b9ca25Sdrh  SELECT changes();
210541b9ca25Sdrh} {3}
210641b9ca25Sdrhdo_execsql_test without_rowid3-30.2 {
210741b9ca25Sdrh  INSERT INTO t2 SELECT * FROM t1;
210841b9ca25Sdrh  SELECT changes();
210941b9ca25Sdrh} {3}
211041b9ca25Sdrh
211163f0eedfSdrhfinish_test
2112