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