gitlab.com/CoiaPrant/sqlite3@v1.19.1/testdata/tcl/without_rowid3.test (about) 1 # 2013-11-02 2 # 3 # The author disclaims copyright to this source code. In place of 4 # a legal notice, here is a blessing: 5 # 6 # May you do good and not evil. 7 # May you find forgiveness for yourself and forgive others. 8 # May you share freely, never taking more than you give. 9 # 10 #*********************************************************************** 11 # This file implements regression tests for SQLite library. 12 # 13 # This file implements tests for foreign keys on WITHOUT ROWID 14 # tables. 15 # 16 17 set testdir [file dirname $argv0] 18 source $testdir/tester.tcl 19 20 ifcapable {!foreignkey||!trigger} { 21 finish_test 22 return 23 } 24 25 #------------------------------------------------------------------------- 26 # Test structure: 27 # 28 # without_rowid3-1.*: Simple tests to check that immediate and deferred foreign key 29 # constraints work when not inside a transaction. 30 # 31 # without_rowid3-2.*: Tests to verify that deferred foreign keys work inside 32 # explicit transactions (i.e that processing really is deferred). 33 # 34 # without_rowid3-3.*: Tests that a statement transaction is rolled back if an 35 # immediate foreign key constraint is violated. 36 # 37 # without_rowid3-4.*: Test that FK actions may recurse even when recursive triggers 38 # are disabled. 39 # 40 # without_rowid3-5.*: Check that if foreign-keys are enabled, it is not possible 41 # to write to an FK column using the incremental blob API. 42 # 43 # without_rowid3-6.*: Test that FK processing is automatically disabled when 44 # running VACUUM. 45 # 46 # without_rowid3-7.*: Test using an IPK as the key in the child (referencing) table. 47 # 48 # without_rowid3-8.*: Test that enabling/disabling foreign key support while a 49 # transaction is active is not possible. 50 # 51 # without_rowid3-9.*: Test SET DEFAULT actions. 52 # 53 # without_rowid3-10.*: Test errors. 54 # 55 # without_rowid3-11.*: Test CASCADE actions. 56 # 57 # without_rowid3-12.*: Test RESTRICT actions. 58 # 59 # without_rowid3-13.*: Test that FK processing is performed when a row is REPLACED by 60 # an UPDATE or INSERT statement. 61 # 62 # without_rowid3-14.*: Test the ALTER TABLE and DROP TABLE commands. 63 # 64 # without_rowid3-15.*: Test that if there are no (known) outstanding foreign key 65 # constraint violations in the database, inserting into a parent 66 # table or deleting from a child table does not cause SQLite 67 # to check if this has repaired an outstanding violation. 68 # 69 # without_rowid3-16.*: Test that rows that refer to themselves may be inserted, 70 # updated and deleted. 71 # 72 # without_rowid3-17.*: Test that the "count_changes" pragma does not interfere with 73 # FK constraint processing. 74 # 75 # without_rowid3-18.*: Test that the authorization callback is invoked when processing 76 # FK constraints. 77 # 78 # without_rowid3-20.*: Test that ON CONFLICT clauses specified as part of statements 79 # do not affect the operation of FK constraints. 80 # 81 # without_rowid3-genfkey.*: Tests that were used with the shell tool .genfkey 82 # command. Recycled to test the built-in implementation. 83 # 84 # without_rowid3-dd08e5.*: Tests to verify that ticket dd08e5a988d00decc4a543daa8d 85 # has been fixed. 86 # 87 88 89 execsql { PRAGMA foreign_keys = on } 90 91 set FkeySimpleSchema { 92 PRAGMA foreign_keys = on; 93 CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT rowid; 94 CREATE TABLE t2(c REFERENCES t1(a) /D/ , d); 95 96 CREATE TABLE t3(a PRIMARY KEY, b) WITHOUT rowid; 97 CREATE TABLE t4(c REFERENCES t3 /D/, d); 98 99 CREATE TABLE t7(a, b INT PRIMARY KEY) WITHOUT rowid; 100 CREATE TABLE t8(c REFERENCES t7 /D/, d); 101 102 CREATE TABLE t9(a REFERENCES nosuchtable, b); 103 CREATE TABLE t10(a REFERENCES t9(c) /D/, b); 104 } 105 106 107 set FkeySimpleTests { 108 1.1 "INSERT INTO t2 VALUES(1, 3)" {1 {FOREIGN KEY constraint failed}} 109 1.2 "INSERT INTO t1 VALUES(1, 2)" {0 {}} 110 1.3 "INSERT INTO t2 VALUES(1, 3)" {0 {}} 111 1.4 "INSERT INTO t2 VALUES(2, 4)" {1 {FOREIGN KEY constraint failed}} 112 1.5 "INSERT INTO t2 VALUES(NULL, 4)" {0 {}} 113 1.6 "UPDATE t2 SET c=2 WHERE d=4" {1 {FOREIGN KEY constraint failed}} 114 1.7 "UPDATE t2 SET c=1 WHERE d=4" {0 {}} 115 1.9 "UPDATE t2 SET c=1 WHERE d=4" {0 {}} 116 1.10 "UPDATE t2 SET c=NULL WHERE d=4" {0 {}} 117 1.11 "DELETE FROM t1 WHERE a=1" {1 {FOREIGN KEY constraint failed}} 118 1.12 "UPDATE t1 SET a = 2" {1 {FOREIGN KEY constraint failed}} 119 1.13 "UPDATE t1 SET a = 1" {0 {}} 120 121 2.1 "INSERT INTO t4 VALUES(1, 3)" {1 {FOREIGN KEY constraint failed}} 122 2.2 "INSERT INTO t3 VALUES(1, 2)" {0 {}} 123 2.3 "INSERT INTO t4 VALUES(1, 3)" {0 {}} 124 125 4.1 "INSERT INTO t8 VALUES(1, 3)" {1 {FOREIGN KEY constraint failed}} 126 4.2 "INSERT INTO t7 VALUES(2, 1)" {0 {}} 127 4.3 "INSERT INTO t8 VALUES(1, 3)" {0 {}} 128 4.4 "INSERT INTO t8 VALUES(2, 4)" {1 {FOREIGN KEY constraint failed}} 129 4.5 "INSERT INTO t8 VALUES(NULL, 4)" {0 {}} 130 4.6 "UPDATE t8 SET c=2 WHERE d=4" {1 {FOREIGN KEY constraint failed}} 131 4.7 "UPDATE t8 SET c=1 WHERE d=4" {0 {}} 132 4.9 "UPDATE t8 SET c=1 WHERE d=4" {0 {}} 133 4.10 "UPDATE t8 SET c=NULL WHERE d=4" {0 {}} 134 4.11 "DELETE FROM t7 WHERE b=1" {1 {FOREIGN KEY constraint failed}} 135 4.12 "UPDATE t7 SET b = 2" {1 {FOREIGN KEY constraint failed}} 136 4.13 "UPDATE t7 SET b = 1" {0 {}} 137 4.14 "INSERT INTO t8 VALUES('a', 'b')" {1 {FOREIGN KEY constraint failed}} 138 4.15 "UPDATE t7 SET b = 5" {1 {FOREIGN KEY constraint failed}} 139 4.17 "UPDATE t7 SET a = 10" {0 {}} 140 141 5.1 "INSERT INTO t9 VALUES(1, 3)" {1 {no such table: main.nosuchtable}} 142 5.2 "INSERT INTO t10 VALUES(1, 3)" 143 {1 {foreign key mismatch - "t10" referencing "t9"}} 144 } 145 146 do_test without_rowid3-1.1.0 { 147 execsql [string map {/D/ {}} $FkeySimpleSchema] 148 } {} 149 foreach {tn zSql res} $FkeySimpleTests { 150 do_test without_rowid3-1.1.$tn.1 { catchsql $zSql } $res 151 do_test without_rowid3-1.1.$tn.2 { execsql {PRAGMA foreign_key_check(t1)} } {} 152 do_test without_rowid3-1.1.$tn.3 { execsql {PRAGMA foreign_key_check(t2)} } {} 153 do_test without_rowid3-1.1.$tn.4 { execsql {PRAGMA foreign_key_check(t3)} } {} 154 do_test without_rowid3-1.1.$tn.5 { execsql {PRAGMA foreign_key_check(t4)} } {} 155 do_test without_rowid3-1.1.$tn.6 { execsql {PRAGMA foreign_key_check(t7)} } {} 156 do_test without_rowid3-1.1.$tn.7 { execsql {PRAGMA foreign_key_check(t8)} } {} 157 } 158 drop_all_tables 159 160 do_test without_rowid3-1.2.0 { 161 execsql [string map {/D/ {DEFERRABLE INITIALLY DEFERRED}} $FkeySimpleSchema] 162 } {} 163 foreach {tn zSql res} $FkeySimpleTests { 164 do_test without_rowid3-1.2.$tn { catchsql $zSql } $res 165 do_test without_rowid3-1.2.$tn.2 { execsql {PRAGMA foreign_key_check(t1)} } {} 166 do_test without_rowid3-1.2.$tn.3 { execsql {PRAGMA foreign_key_check(t2)} } {} 167 do_test without_rowid3-1.2.$tn.4 { execsql {PRAGMA foreign_key_check(t3)} } {} 168 do_test without_rowid3-1.2.$tn.5 { execsql {PRAGMA foreign_key_check(t4)} } {} 169 do_test without_rowid3-1.2.$tn.6 { execsql {PRAGMA foreign_key_check(t7)} } {} 170 do_test without_rowid3-1.2.$tn.7 { execsql {PRAGMA foreign_key_check(t8)} } {} 171 } 172 drop_all_tables 173 174 do_test without_rowid3-1.3.0 { 175 execsql [string map {/D/ {}} $FkeySimpleSchema] 176 execsql { PRAGMA count_changes = 1 } 177 } {} 178 foreach {tn zSql res} $FkeySimpleTests { 179 if {$res == "0 {}"} { set res {0 1} } 180 do_test without_rowid3-1.3.$tn { catchsql $zSql } $res 181 do_test without_rowid3-1.3.$tn.2 { execsql {PRAGMA foreign_key_check(t1)} } {} 182 do_test without_rowid3-1.3.$tn.3 { execsql {PRAGMA foreign_key_check(t2)} } {} 183 do_test without_rowid3-1.3.$tn.4 { execsql {PRAGMA foreign_key_check(t3)} } {} 184 do_test without_rowid3-1.3.$tn.5 { execsql {PRAGMA foreign_key_check(t4)} } {} 185 do_test without_rowid3-1.3.$tn.6 { execsql {PRAGMA foreign_key_check(t7)} } {} 186 do_test without_rowid3-1.3.$tn.7 { execsql {PRAGMA foreign_key_check(t8)} } {} 187 } 188 execsql { PRAGMA count_changes = 0 } 189 drop_all_tables 190 191 do_test without_rowid3-1.4.0 { 192 execsql [string map {/D/ {}} $FkeySimpleSchema] 193 execsql { PRAGMA count_changes = 1 } 194 } {} 195 foreach {tn zSql res} $FkeySimpleTests { 196 if {$res == "0 {}"} { set res {0 1} } 197 execsql BEGIN 198 do_test without_rowid3-1.4.$tn { catchsql $zSql } $res 199 execsql COMMIT 200 } 201 execsql { PRAGMA count_changes = 0 } 202 drop_all_tables 203 204 # Special test: When the parent key is an IPK, make sure the affinity of 205 # the IPK is not applied to the child key value before it is inserted 206 # into the child table. 207 do_test without_rowid3-1.5.1 { 208 execsql { 209 CREATE TABLE i(i INT PRIMARY KEY) WITHOUT rowid; 210 CREATE TABLE j(j REFERENCES i); 211 INSERT INTO i VALUES(35); 212 INSERT INTO j VALUES('35.0'); 213 SELECT j, typeof(j) FROM j; 214 } 215 } {35.0 text} 216 do_test without_rowid3-1.5.2 { 217 catchsql { DELETE FROM i } 218 } {1 {FOREIGN KEY constraint failed}} 219 220 # Same test using a regular primary key with integer affinity. 221 drop_all_tables 222 do_test without_rowid3-1.6.1 { 223 execsql { 224 CREATE TABLE i(i INT UNIQUE); 225 CREATE TABLE j(j REFERENCES i(i)); 226 INSERT INTO i VALUES('35.0'); 227 INSERT INTO j VALUES('35.0'); 228 SELECT j, typeof(j) FROM j; 229 SELECT i, typeof(i) FROM i; 230 } 231 } {35.0 text 35 integer} 232 do_test without_rowid3-1.6.2 { 233 catchsql { DELETE FROM i } 234 } {1 {FOREIGN KEY constraint failed}} 235 236 # Use a collation sequence on the parent key. 237 drop_all_tables 238 do_test without_rowid3-1.7.1 { 239 execsql { 240 CREATE TABLE i(i TEXT COLLATE nocase PRIMARY KEY) WITHOUT rowid; 241 CREATE TABLE j(j TEXT COLLATE binary REFERENCES i(i)); 242 INSERT INTO i VALUES('SQLite'); 243 INSERT INTO j VALUES('sqlite'); 244 } 245 catchsql { DELETE FROM i } 246 } {1 {FOREIGN KEY constraint failed}} 247 248 # Use the parent key collation even if it is default and the child key 249 # has an explicit value. 250 drop_all_tables 251 do_test without_rowid3-1.7.2 { 252 execsql { 253 CREATE TABLE i(i TEXT PRIMARY KEY) WITHOUT rowid; -- Colseq is "BINARY" 254 CREATE TABLE j(j TEXT COLLATE nocase REFERENCES i(i)); 255 INSERT INTO i VALUES('SQLite'); 256 } 257 catchsql { INSERT INTO j VALUES('sqlite') } 258 } {1 {FOREIGN KEY constraint failed}} 259 do_test without_rowid3-1.7.3 { 260 execsql { 261 INSERT INTO i VALUES('sqlite'); 262 INSERT INTO j VALUES('sqlite'); 263 DELETE FROM i WHERE i = 'SQLite'; 264 } 265 catchsql { DELETE FROM i WHERE i = 'sqlite' } 266 } {1 {FOREIGN KEY constraint failed}} 267 268 #------------------------------------------------------------------------- 269 # This section (test cases without_rowid3-2.*) contains tests to check that the 270 # deferred foreign key constraint logic works. 271 # 272 proc without_rowid3-2-test {tn nocommit sql {res {}}} { 273 if {$res eq "FKV"} { 274 set expected {1 {FOREIGN KEY constraint failed}} 275 } else { 276 set expected [list 0 $res] 277 } 278 do_test without_rowid3-2.$tn [list catchsql $sql] $expected 279 if {$nocommit} { 280 do_test without_rowid3-2.${tn}c { 281 catchsql COMMIT 282 } {1 {FOREIGN KEY constraint failed}} 283 } 284 } 285 286 without_rowid3-2-test 1 0 { 287 CREATE TABLE node( 288 nodeid PRIMARY KEY, 289 parent REFERENCES node DEFERRABLE INITIALLY DEFERRED 290 ) WITHOUT rowid; 291 CREATE TABLE leaf( 292 cellid PRIMARY KEY, 293 parent REFERENCES node DEFERRABLE INITIALLY DEFERRED 294 ) WITHOUT rowid; 295 } 296 297 without_rowid3-2-test 1 0 "INSERT INTO node VALUES(1, 0)" FKV 298 without_rowid3-2-test 2 0 "BEGIN" 299 without_rowid3-2-test 3 1 "INSERT INTO node VALUES(1, 0)" 300 without_rowid3-2-test 4 0 "UPDATE node SET parent = NULL" 301 without_rowid3-2-test 5 0 "COMMIT" 302 without_rowid3-2-test 6 0 "SELECT * FROM node" {1 {}} 303 304 without_rowid3-2-test 7 0 "BEGIN" 305 without_rowid3-2-test 8 1 "INSERT INTO leaf VALUES('a', 2)" 306 without_rowid3-2-test 9 1 "INSERT INTO node VALUES(2, 0)" 307 without_rowid3-2-test 10 0 "UPDATE node SET parent = 1 WHERE nodeid = 2" 308 without_rowid3-2-test 11 0 "COMMIT" 309 without_rowid3-2-test 12 0 "SELECT * FROM node" {1 {} 2 1} 310 without_rowid3-2-test 13 0 "SELECT * FROM leaf" {a 2} 311 312 without_rowid3-2-test 14 0 "BEGIN" 313 without_rowid3-2-test 15 1 "DELETE FROM node WHERE nodeid = 2" 314 without_rowid3-2-test 16 0 "INSERT INTO node VALUES(2, NULL)" 315 without_rowid3-2-test 17 0 "COMMIT" 316 without_rowid3-2-test 18 0 "SELECT * FROM node" {1 {} 2 {}} 317 without_rowid3-2-test 19 0 "SELECT * FROM leaf" {a 2} 318 319 without_rowid3-2-test 20 0 "BEGIN" 320 without_rowid3-2-test 21 0 "INSERT INTO leaf VALUES('b', 1)" 321 without_rowid3-2-test 22 0 "SAVEPOINT save" 322 without_rowid3-2-test 23 0 "DELETE FROM node WHERE nodeid = 1" 323 without_rowid3-2-test 24 0 "ROLLBACK TO save" 324 without_rowid3-2-test 25 0 "COMMIT" 325 without_rowid3-2-test 26 0 "SELECT * FROM node" {1 {} 2 {}} 326 without_rowid3-2-test 27 0 "SELECT * FROM leaf" {a 2 b 1} 327 328 without_rowid3-2-test 28 0 "BEGIN" 329 without_rowid3-2-test 29 0 "INSERT INTO leaf VALUES('c', 1)" 330 without_rowid3-2-test 30 0 "SAVEPOINT save" 331 without_rowid3-2-test 31 0 "DELETE FROM node WHERE nodeid = 1" 332 without_rowid3-2-test 32 1 "RELEASE save" 333 without_rowid3-2-test 33 1 "DELETE FROM leaf WHERE cellid = 'b'" 334 without_rowid3-2-test 34 0 "DELETE FROM leaf WHERE cellid = 'c'" 335 without_rowid3-2-test 35 0 "COMMIT" 336 without_rowid3-2-test 36 0 "SELECT * FROM node" {2 {}} 337 without_rowid3-2-test 37 0 "SELECT * FROM leaf" {a 2} 338 339 without_rowid3-2-test 38 0 "SAVEPOINT outer" 340 without_rowid3-2-test 39 1 "INSERT INTO leaf VALUES('d', 3)" 341 without_rowid3-2-test 40 1 "RELEASE outer" FKV 342 without_rowid3-2-test 41 1 "INSERT INTO leaf VALUES('e', 3)" 343 without_rowid3-2-test 42 0 "INSERT INTO node VALUES(3, 2)" 344 without_rowid3-2-test 43 0 "RELEASE outer" 345 346 without_rowid3-2-test 44 0 "SAVEPOINT outer" 347 without_rowid3-2-test 45 1 "DELETE FROM node WHERE nodeid=3" 348 without_rowid3-2-test 47 0 "INSERT INTO node VALUES(3, 2)" 349 without_rowid3-2-test 48 0 "ROLLBACK TO outer" 350 without_rowid3-2-test 49 0 "RELEASE outer" 351 352 without_rowid3-2-test 50 0 "SAVEPOINT outer" 353 without_rowid3-2-test 51 1 "INSERT INTO leaf VALUES('f', 4)" 354 without_rowid3-2-test 52 1 "SAVEPOINT inner" 355 without_rowid3-2-test 53 1 "INSERT INTO leaf VALUES('g', 4)" 356 without_rowid3-2-test 54 1 "RELEASE outer" FKV 357 without_rowid3-2-test 55 1 "ROLLBACK TO inner" 358 without_rowid3-2-test 56 0 "COMMIT" FKV 359 without_rowid3-2-test 57 0 "INSERT INTO node VALUES(4, NULL)" 360 without_rowid3-2-test 58 0 "RELEASE outer" 361 without_rowid3-2-test 59 0 "SELECT * FROM node" {2 {} 3 2 4 {}} 362 without_rowid3-2-test 60 0 "SELECT * FROM leaf" {a 2 d 3 e 3 f 4} 363 364 # The following set of tests check that if a statement that affects 365 # multiple rows violates some foreign key constraints, then strikes a 366 # constraint that causes the statement-transaction to be rolled back, 367 # the deferred constraint counter is correctly reset to the value it 368 # had before the statement-transaction was opened. 369 # 370 without_rowid3-2-test 61 0 "BEGIN" 371 without_rowid3-2-test 62 0 "DELETE FROM leaf" 372 without_rowid3-2-test 63 0 "DELETE FROM node" 373 without_rowid3-2-test 64 1 "INSERT INTO leaf VALUES('a', 1)" 374 without_rowid3-2-test 65 1 "INSERT INTO leaf VALUES('b', 2)" 375 without_rowid3-2-test 66 1 "INSERT INTO leaf VALUES('c', 1)" 376 do_test without_rowid3-2-test-67 { 377 catchsql "INSERT INTO node SELECT parent, 3 FROM leaf" 378 } {1 {UNIQUE constraint failed: node.nodeid}} 379 without_rowid3-2-test 68 0 "COMMIT" FKV 380 without_rowid3-2-test 69 1 "INSERT INTO node VALUES(1, NULL)" 381 without_rowid3-2-test 70 0 "INSERT INTO node VALUES(2, NULL)" 382 without_rowid3-2-test 71 0 "COMMIT" 383 384 without_rowid3-2-test 72 0 "BEGIN" 385 without_rowid3-2-test 73 1 "DELETE FROM node" 386 without_rowid3-2-test 74 0 "INSERT INTO node(nodeid) SELECT DISTINCT parent FROM leaf" 387 without_rowid3-2-test 75 0 "COMMIT" 388 389 #------------------------------------------------------------------------- 390 # Test cases without_rowid3-3.* test that a program that executes foreign key 391 # actions (CASCADE, SET DEFAULT, SET NULL etc.) or tests FK constraints 392 # opens a statement transaction if required. 393 # 394 # without_rowid3-3.1.*: Test UPDATE statements. 395 # without_rowid3-3.2.*: Test DELETE statements. 396 # 397 drop_all_tables 398 do_test without_rowid3-3.1.1 { 399 execsql { 400 CREATE TABLE ab(a PRIMARY KEY, b) WITHOUT rowid; 401 CREATE TABLE cd( 402 c PRIMARY KEY REFERENCES ab ON UPDATE CASCADE ON DELETE CASCADE, 403 d 404 ) WITHOUT rowid; 405 CREATE TABLE ef( 406 e REFERENCES cd ON UPDATE CASCADE, 407 f, CHECK (e!=5) 408 ); 409 } 410 } {} 411 do_test without_rowid3-3.1.2 { 412 execsql { 413 INSERT INTO ab VALUES(1, 'b'); 414 INSERT INTO cd VALUES(1, 'd'); 415 INSERT INTO ef VALUES(1, 'e'); 416 } 417 } {} 418 do_test without_rowid3-3.1.3 { 419 catchsql { UPDATE ab SET a = 5 } 420 } {1 {CHECK constraint failed: e!=5}} 421 do_test without_rowid3-3.1.4 { 422 execsql { SELECT * FROM ab } 423 } {1 b} 424 do_test without_rowid3-3.1.4 { 425 execsql BEGIN; 426 catchsql { UPDATE ab SET a = 5 } 427 } {1 {CHECK constraint failed: e!=5}} 428 do_test without_rowid3-3.1.5 { 429 execsql COMMIT; 430 execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef } 431 } {1 b 1 d 1 e} 432 433 do_test without_rowid3-3.2.1 { 434 execsql BEGIN; 435 catchsql { DELETE FROM ab } 436 } {1 {FOREIGN KEY constraint failed}} 437 do_test without_rowid3-3.2.2 { 438 execsql COMMIT 439 execsql { SELECT * FROM ab; SELECT * FROM cd; SELECT * FROM ef } 440 } {1 b 1 d 1 e} 441 442 #------------------------------------------------------------------------- 443 # Test cases without_rowid3-4.* test that recursive foreign key actions 444 # (i.e. CASCADE) are allowed even if recursive triggers are disabled. 445 # 446 drop_all_tables 447 do_test without_rowid3-4.1 { 448 execsql { 449 CREATE TABLE t1( 450 node PRIMARY KEY, 451 parent REFERENCES t1 ON DELETE CASCADE 452 ) WITHOUT rowid; 453 CREATE TABLE t2(node PRIMARY KEY, parent) WITHOUT rowid; 454 CREATE TRIGGER t2t AFTER DELETE ON t2 BEGIN 455 DELETE FROM t2 WHERE parent = old.node; 456 END; 457 INSERT INTO t1 VALUES(1, NULL); 458 INSERT INTO t1 VALUES(2, 1); 459 INSERT INTO t1 VALUES(3, 1); 460 INSERT INTO t1 VALUES(4, 2); 461 INSERT INTO t1 VALUES(5, 2); 462 INSERT INTO t1 VALUES(6, 3); 463 INSERT INTO t1 VALUES(7, 3); 464 INSERT INTO t2 SELECT * FROM t1; 465 } 466 } {} 467 do_test without_rowid3-4.2 { 468 execsql { PRAGMA recursive_triggers = off } 469 execsql { 470 BEGIN; 471 DELETE FROM t1 WHERE node = 1; 472 SELECT node FROM t1; 473 } 474 } {} 475 do_test without_rowid3-4.3 { 476 execsql { 477 DELETE FROM t2 WHERE node = 1; 478 SELECT node FROM t2; 479 ROLLBACK; 480 } 481 } {4 5 6 7} 482 do_test without_rowid3-4.4 { 483 execsql { PRAGMA recursive_triggers = on } 484 execsql { 485 BEGIN; 486 DELETE FROM t1 WHERE node = 1; 487 SELECT node FROM t1; 488 } 489 } {} 490 do_test without_rowid3-4.3 { 491 execsql { 492 DELETE FROM t2 WHERE node = 1; 493 SELECT node FROM t2; 494 ROLLBACK; 495 } 496 } {} 497 498 #------------------------------------------------------------------------- 499 # Test cases without_rowid3-5.* verify that the incremental blob API may not 500 # write to a foreign key column while foreign-keys are enabled. 501 # 502 drop_all_tables 503 ifcapable incrblob { 504 do_test without_rowid3-5.1 { 505 execsql { 506 CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT rowid; 507 CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1(a)) WITHOUT rowid; 508 INSERT INTO t1 VALUES('hello', 'world'); 509 INSERT INTO t2 VALUES('key', 'hello'); 510 } 511 } {} 512 do_test without_rowid3-5.2 { 513 set rc [catch { set fd [db incrblob t2 b 1] } msg] 514 list $rc $msg 515 } {1 {cannot open table without rowid: t2}} 516 do_test without_rowid3-5.5 { 517 execsql { PRAGMA foreign_keys = on } 518 } {} 519 } 520 521 drop_all_tables 522 ifcapable vacuum { 523 do_test without_rowid3-6.1 { 524 execsql { 525 CREATE TABLE t1(a REFERENCES t2(c), b); 526 CREATE TABLE t2(c UNIQUE, b); 527 INSERT INTO t2 VALUES(1, 2); 528 INSERT INTO t1 VALUES(1, 2); 529 VACUUM; 530 } 531 } {} 532 } 533 534 #------------------------------------------------------------------------- 535 # Test that it is possible to use an INT PRIMARY KEY as the child key 536 # of a foreign constraint. 537 # 538 drop_all_tables 539 do_test without_rowid3-7.1 { 540 execsql { 541 CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT rowid; 542 CREATE TABLE t2(c INT PRIMARY KEY REFERENCES t1, b) WITHOUT rowid; 543 } 544 } {} 545 do_test without_rowid3-7.2 { 546 catchsql { INSERT INTO t2 VALUES(1, 'A'); } 547 } {1 {FOREIGN KEY constraint failed}} 548 do_test without_rowid3-7.3 { 549 execsql { 550 INSERT INTO t1 VALUES(1, 2); 551 INSERT INTO t1 VALUES(2, 3); 552 INSERT INTO t2 VALUES(1, 'A'); 553 } 554 } {} 555 do_test without_rowid3-7.4 { 556 execsql { UPDATE t2 SET c = 2 } 557 } {} 558 do_test without_rowid3-7.5 { 559 catchsql { UPDATE t2 SET c = 3 } 560 } {1 {FOREIGN KEY constraint failed}} 561 do_test without_rowid3-7.6 { 562 catchsql { DELETE FROM t1 WHERE a = 2 } 563 } {1 {FOREIGN KEY constraint failed}} 564 do_test without_rowid3-7.7 { 565 execsql { DELETE FROM t1 WHERE a = 1 } 566 } {} 567 do_test without_rowid3-7.8 { 568 catchsql { UPDATE t1 SET a = 3 } 569 } {1 {FOREIGN KEY constraint failed}} 570 571 #------------------------------------------------------------------------- 572 # Test that it is not possible to enable/disable FK support while a 573 # transaction is open. 574 # 575 drop_all_tables 576 proc without_rowid3-8-test {tn zSql value} { 577 do_test without_rowid3-2.8.$tn.1 [list execsql $zSql] {} 578 do_test without_rowid3-2.8.$tn.2 { execsql "PRAGMA foreign_keys" } $value 579 } 580 without_rowid3-8-test 1 { PRAGMA foreign_keys = 0 } 0 581 without_rowid3-8-test 2 { PRAGMA foreign_keys = 1 } 1 582 without_rowid3-8-test 3 { BEGIN } 1 583 without_rowid3-8-test 4 { PRAGMA foreign_keys = 0 } 1 584 without_rowid3-8-test 5 { COMMIT } 1 585 without_rowid3-8-test 6 { PRAGMA foreign_keys = 0 } 0 586 without_rowid3-8-test 7 { BEGIN } 0 587 without_rowid3-8-test 8 { PRAGMA foreign_keys = 1 } 0 588 without_rowid3-8-test 9 { COMMIT } 0 589 without_rowid3-8-test 10 { PRAGMA foreign_keys = 1 } 1 590 without_rowid3-8-test 11 { PRAGMA foreign_keys = off } 0 591 without_rowid3-8-test 12 { PRAGMA foreign_keys = on } 1 592 without_rowid3-8-test 13 { PRAGMA foreign_keys = no } 0 593 without_rowid3-8-test 14 { PRAGMA foreign_keys = yes } 1 594 without_rowid3-8-test 15 { PRAGMA foreign_keys = false } 0 595 without_rowid3-8-test 16 { PRAGMA foreign_keys = true } 1 596 597 #------------------------------------------------------------------------- 598 # The following tests, without_rowid3-9.*, test SET DEFAULT actions. 599 # 600 drop_all_tables 601 do_test without_rowid3-9.1.1 { 602 execsql { 603 CREATE TABLE t1(a INT PRIMARY KEY, b) WITHOUT rowid; 604 CREATE TABLE t2( 605 c INT PRIMARY KEY, 606 d INTEGER DEFAULT 1 REFERENCES t1 ON DELETE SET DEFAULT 607 ) WITHOUT rowid; 608 DELETE FROM t1; 609 } 610 } {} 611 do_test without_rowid3-9.1.2 { 612 execsql { 613 INSERT INTO t1 VALUES(1, 'one'); 614 INSERT INTO t1 VALUES(2, 'two'); 615 INSERT INTO t2 VALUES(1, 2); 616 SELECT * FROM t2; 617 DELETE FROM t1 WHERE a = 2; 618 SELECT * FROM t2; 619 } 620 } {1 2 1 1} 621 do_test without_rowid3-9.1.3 { 622 execsql { 623 INSERT INTO t1 VALUES(2, 'two'); 624 UPDATE t2 SET d = 2; 625 DELETE FROM t1 WHERE a = 1; 626 SELECT * FROM t2; 627 } 628 } {1 2} 629 do_test without_rowid3-9.1.4 { 630 execsql { SELECT * FROM t1 } 631 } {2 two} 632 do_test without_rowid3-9.1.5 { 633 catchsql { DELETE FROM t1 } 634 } {1 {FOREIGN KEY constraint failed}} 635 636 do_test without_rowid3-9.2.1 { 637 execsql { 638 CREATE TABLE pp(a, b, c, PRIMARY KEY(b, c)) WITHOUT rowid; 639 CREATE TABLE cc(d DEFAULT 3, e DEFAULT 1, f DEFAULT 2, 640 FOREIGN KEY(f, d) REFERENCES pp 641 ON UPDATE SET DEFAULT 642 ON DELETE SET NULL 643 ); 644 INSERT INTO pp VALUES(1, 2, 3); 645 INSERT INTO pp VALUES(4, 5, 6); 646 INSERT INTO pp VALUES(7, 8, 9); 647 } 648 } {} 649 do_test without_rowid3-9.2.2 { 650 execsql { 651 INSERT INTO cc VALUES(6, 'A', 5); 652 INSERT INTO cc VALUES(6, 'B', 5); 653 INSERT INTO cc VALUES(9, 'A', 8); 654 INSERT INTO cc VALUES(9, 'B', 8); 655 UPDATE pp SET b = 1 WHERE a = 7; 656 SELECT * FROM cc; 657 } 658 } {6 A 5 6 B 5 3 A 2 3 B 2} 659 do_test without_rowid3-9.2.3 { 660 execsql { 661 DELETE FROM pp WHERE a = 4; 662 SELECT * FROM cc; 663 } 664 } {{} A {} {} B {} 3 A 2 3 B 2} 665 666 #------------------------------------------------------------------------- 667 # The following tests, without_rowid3-10.*, test "foreign key mismatch" and 668 # other errors. 669 # 670 set tn 0 671 foreach zSql [list { 672 CREATE TABLE p(a PRIMARY KEY, b) WITHOUT rowid; 673 CREATE TABLE c(x REFERENCES p(c)); 674 } { 675 CREATE TABLE c(x REFERENCES v(y)); 676 CREATE VIEW v AS SELECT x AS y FROM c; 677 } { 678 CREATE TABLE p(a, b, PRIMARY KEY(a, b)) WITHOUT rowid; 679 CREATE TABLE c(x REFERENCES p); 680 } { 681 CREATE TABLE p(a COLLATE binary, b); 682 CREATE UNIQUE INDEX i ON p(a COLLATE nocase); 683 CREATE TABLE c(x REFERENCES p(a)); 684 }] { 685 drop_all_tables 686 do_test without_rowid3-10.1.[incr tn] { 687 execsql $zSql 688 catchsql { INSERT INTO c DEFAULT VALUES } 689 } {/1 {foreign key mismatch - "c" referencing "."}/} 690 } 691 692 # "rowid" cannot be used as part of a child or parent key definition 693 # unless it happens to be the name of an explicitly declared column. 694 # 695 do_test without_rowid3-10.2.1 { 696 drop_all_tables 697 catchsql { 698 CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT rowid; 699 CREATE TABLE t2(c, d, FOREIGN KEY(rowid) REFERENCES t1(a)); 700 } 701 } {1 {unknown column "rowid" in foreign key definition}} 702 do_test without_rowid3-10.2.2 { 703 drop_all_tables 704 catchsql { 705 CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT rowid; 706 CREATE TABLE t2(rowid, d, FOREIGN KEY(rowid) REFERENCES t1(a)); 707 } 708 } {0 {}} 709 do_test without_rowid3-10.2.1 { 710 drop_all_tables 711 catchsql { 712 CREATE TABLE t1(a, b); 713 CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(rowid)); 714 INSERT INTO t1(rowid, a, b) VALUES(1, 1, 1); 715 INSERT INTO t2 VALUES(1, 1); 716 } 717 } {1 {foreign key mismatch - "t2" referencing "t1"}} 718 do_test without_rowid3-10.2.2 { 719 drop_all_tables 720 catchsql { 721 CREATE TABLE t1(rowid PRIMARY KEY, b) WITHOUT rowid; 722 CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(rowid)); 723 INSERT INTO t1(rowid, b) VALUES(1, 1); 724 INSERT INTO t2 VALUES(1, 1); 725 } 726 } {0 {}} 727 728 729 #------------------------------------------------------------------------- 730 # The following tests, without_rowid3-11.*, test CASCADE actions. 731 # 732 drop_all_tables 733 do_test without_rowid3-11.1.1 { 734 execsql { 735 CREATE TABLE t1(a INT PRIMARY KEY, b) WITHOUT rowid; 736 CREATE TABLE t2(c, d, FOREIGN KEY(c) REFERENCES t1(a) ON UPDATE CASCADE); 737 738 INSERT INTO t1 VALUES(10, 100); 739 INSERT INTO t2 VALUES(10, 100); 740 UPDATE t1 SET a = 15; 741 SELECT * FROM t2; 742 } 743 } {15 100} 744 745 #------------------------------------------------------------------------- 746 # The following tests, without_rowid3-12.*, test RESTRICT actions. 747 # 748 drop_all_tables 749 do_test without_rowid3-12.1.1 { 750 execsql { 751 CREATE TABLE t1(a, b PRIMARY KEY) WITHOUT rowid; 752 CREATE TABLE t2( 753 x REFERENCES t1 ON UPDATE RESTRICT DEFERRABLE INITIALLY DEFERRED 754 ); 755 INSERT INTO t1 VALUES(1, 'one'); 756 INSERT INTO t1 VALUES(2, 'two'); 757 INSERT INTO t1 VALUES(3, 'three'); 758 } 759 } {} 760 do_test without_rowid3-12.1.2 { 761 execsql "BEGIN" 762 execsql "INSERT INTO t2 VALUES('two')" 763 } {} 764 do_test without_rowid3-12.1.3 { 765 execsql "UPDATE t1 SET b = 'four' WHERE b = 'one'" 766 } {} 767 do_test without_rowid3-12.1.4 { 768 catchsql "UPDATE t1 SET b = 'five' WHERE b = 'two'" 769 } {1 {FOREIGN KEY constraint failed}} 770 do_test without_rowid3-12.1.5 { 771 execsql "DELETE FROM t1 WHERE b = 'two'" 772 } {} 773 do_test without_rowid3-12.1.6 { 774 catchsql "COMMIT" 775 } {1 {FOREIGN KEY constraint failed}} 776 do_test without_rowid3-12.1.7 { 777 execsql { 778 INSERT INTO t1 VALUES(2, 'two'); 779 COMMIT; 780 } 781 } {} 782 783 drop_all_tables 784 do_test without_rowid3-12.2.1 { 785 execsql { 786 CREATE TABLE t1(x COLLATE NOCASE PRIMARY KEY) WITHOUT rowid; 787 CREATE TRIGGER tt1 AFTER DELETE ON t1 788 WHEN EXISTS ( SELECT 1 FROM t2 WHERE old.x = y ) 789 BEGIN 790 INSERT INTO t1 VALUES(old.x); 791 END; 792 CREATE TABLE t2(y REFERENCES t1); 793 INSERT INTO t1 VALUES('A'); 794 INSERT INTO t1 VALUES('B'); 795 INSERT INTO t2 VALUES('a'); 796 INSERT INTO t2 VALUES('b'); 797 798 SELECT * FROM t1; 799 SELECT * FROM t2; 800 } 801 } {A B a b} 802 do_test without_rowid3-12.2.2 { 803 execsql { DELETE FROM t1 } 804 execsql { 805 SELECT * FROM t1; 806 SELECT * FROM t2; 807 } 808 } {A B a b} 809 do_test without_rowid3-12.2.3 { 810 execsql { 811 DROP TABLE t2; 812 CREATE TABLE t2(y REFERENCES t1 ON DELETE RESTRICT); 813 INSERT INTO t2 VALUES('a'); 814 INSERT INTO t2 VALUES('b'); 815 } 816 catchsql { DELETE FROM t1 } 817 } {1 {FOREIGN KEY constraint failed}} 818 do_test without_rowid3-12.2.4 { 819 execsql { 820 SELECT * FROM t1; 821 SELECT * FROM t2; 822 } 823 } {A B a b} 824 825 drop_all_tables 826 do_test without_rowid3-12.3.1 { 827 execsql { 828 CREATE TABLE up( 829 c00, c01, c02, c03, c04, c05, c06, c07, c08, c09, 830 c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, 831 c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, 832 c30, c31, c32, c33, c34, c35, c36, c37, c38, c39, 833 PRIMARY KEY(c34, c35) 834 ) WITHOUT rowid; 835 CREATE TABLE down( 836 c00, c01, c02, c03, c04, c05, c06, c07, c08, c09, 837 c10, c11, c12, c13, c14, c15, c16, c17, c18, c19, 838 c20, c21, c22, c23, c24, c25, c26, c27, c28, c29, 839 c30, c31, c32, c33, c34, c35, c36, c37, c38, c39, 840 FOREIGN KEY(c39, c38) REFERENCES up ON UPDATE CASCADE 841 ); 842 } 843 } {} 844 do_test without_rowid3-12.3.2 { 845 execsql { 846 INSERT INTO up(c34, c35) VALUES('yes', 'no'); 847 INSERT INTO down(c39, c38) VALUES('yes', 'no'); 848 UPDATE up SET c34 = 'possibly'; 849 SELECT c38, c39 FROM down; 850 DELETE FROM down; 851 } 852 } {no possibly} 853 do_test without_rowid3-12.3.3 { 854 catchsql { INSERT INTO down(c39, c38) VALUES('yes', 'no') } 855 } {1 {FOREIGN KEY constraint failed}} 856 do_test without_rowid3-12.3.4 { 857 execsql { 858 INSERT INTO up(c34, c35) VALUES('yes', 'no'); 859 INSERT INTO down(c39, c38) VALUES('yes', 'no'); 860 } 861 catchsql { DELETE FROM up WHERE c34 = 'yes' } 862 } {1 {FOREIGN KEY constraint failed}} 863 do_test without_rowid3-12.3.5 { 864 execsql { 865 DELETE FROM up WHERE c34 = 'possibly'; 866 SELECT c34, c35 FROM up; 867 SELECT c39, c38 FROM down; 868 } 869 } {yes no yes no} 870 871 #------------------------------------------------------------------------- 872 # The following tests, without_rowid3-13.*, test that FK processing is performed 873 # when rows are REPLACEd. 874 # 875 drop_all_tables 876 do_test without_rowid3-13.1.1 { 877 execsql { 878 CREATE TABLE pp(a UNIQUE, b, c, PRIMARY KEY(b, c)) WITHOUT rowid; 879 CREATE TABLE cc(d, e, f UNIQUE, FOREIGN KEY(d, e) REFERENCES pp); 880 INSERT INTO pp VALUES(1, 2, 3); 881 INSERT INTO cc VALUES(2, 3, 1); 882 } 883 } {} 884 foreach {tn stmt} { 885 1 "REPLACE INTO pp VALUES(1, 4, 5)" 886 } { 887 do_test without_rowid3-13.1.$tn.1 { 888 catchsql $stmt 889 } {1 {FOREIGN KEY constraint failed}} 890 do_test without_rowid3-13.1.$tn.2 { 891 execsql { 892 SELECT * FROM pp; 893 SELECT * FROM cc; 894 } 895 } {1 2 3 2 3 1} 896 do_test without_rowid3-13.1.$tn.3 { 897 execsql BEGIN; 898 catchsql $stmt 899 } {1 {FOREIGN KEY constraint failed}} 900 do_test without_rowid3-13.1.$tn.4 { 901 execsql { 902 COMMIT; 903 SELECT * FROM pp; 904 SELECT * FROM cc; 905 } 906 } {1 2 3 2 3 1} 907 } 908 909 #------------------------------------------------------------------------- 910 # The following tests, without_rowid3-14.*, test that the "DROP TABLE" and "ALTER 911 # TABLE" commands work as expected wrt foreign key constraints. 912 # 913 # without_rowid3-14.1*: ALTER TABLE ADD COLUMN 914 # without_rowid3-14.2*: ALTER TABLE RENAME TABLE 915 # without_rowid3-14.3*: DROP TABLE 916 # 917 drop_all_tables 918 ifcapable altertable { 919 do_test without_rowid3-14.1.1 { 920 # Adding a column with a REFERENCES clause is not supported. 921 execsql { 922 CREATE TABLE t1(a PRIMARY KEY) WITHOUT rowid; 923 CREATE TABLE t2(a, b); 924 INSERT INTO t2(a,b) VALUES(1,2); 925 } 926 catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 } 927 } {0 {}} 928 do_test without_rowid3-14.1.2 { 929 catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 } 930 } {0 {}} 931 do_test without_rowid3-14.1.3 { 932 catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL} 933 } {0 {}} 934 do_test without_rowid3-14.1.4 { 935 catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'} 936 } {1 {Cannot add a REFERENCES column with non-NULL default value}} 937 do_test without_rowid3-14.1.5 { 938 catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 } 939 } {1 {Cannot add a REFERENCES column with non-NULL default value}} 940 do_test without_rowid3-14.1.6 { 941 execsql { 942 PRAGMA foreign_keys = off; 943 ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1; 944 PRAGMA foreign_keys = on; 945 SELECT sql FROM sqlite_schema WHERE name='t2'; 946 } 947 } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}} 948 949 950 # Test the sqlite_rename_parent() function directly. 951 # 952 proc test_rename_parent {zCreate zOld zNew} { 953 db eval {SELECT sqlite_rename_table( 954 'main', 'table', 't1', $zCreate, $zOld, $zNew, 0 955 )} 956 } 957 sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db 958 do_test without_rowid3-14.2.1.1 { 959 test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3 960 } {{CREATE TABLE t1(a REFERENCES "t3")}} 961 do_test without_rowid3-14.2.1.2 { 962 test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3 963 } {{CREATE TABLE t1(a REFERENCES t2)}} 964 do_test without_rowid3-14.2.1.3 { 965 test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3 966 } {{CREATE TABLE t1(a REFERENCES "t3")}} 967 sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db 968 969 # Test ALTER TABLE RENAME TABLE a bit. 970 # 971 do_test without_rowid3-14.2.2.1 { 972 drop_all_tables 973 execsql { 974 CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid; 975 CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2) 976 WITHOUT rowid; 977 CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1); 978 } 979 execsql { SELECT sql FROM sqlite_schema WHERE type = 'table'} 980 } [list \ 981 {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid} \ 982 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2) 983 WITHOUT rowid} \ 984 {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)} \ 985 ] 986 do_test without_rowid3-14.2.2.2 { 987 execsql { ALTER TABLE t1 RENAME TO t4 } 988 execsql { SELECT sql FROM sqlite_schema WHERE type = 'table'} 989 } [list \ 990 {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid} \ 991 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2) 992 WITHOUT rowid} \ 993 {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \ 994 ] 995 do_test without_rowid3-14.2.2.3 { 996 catchsql { INSERT INTO t3 VALUES(1, 2, 3) } 997 } {1 {FOREIGN KEY constraint failed}} 998 do_test without_rowid3-14.2.2.4 { 999 execsql { INSERT INTO t4 VALUES(1, NULL) } 1000 } {} 1001 do_test without_rowid3-14.2.2.5 { 1002 catchsql { UPDATE t4 SET b = 5 } 1003 } {1 {FOREIGN KEY constraint failed}} 1004 do_test without_rowid3-14.2.2.6 { 1005 catchsql { UPDATE t4 SET b = 1 } 1006 } {0 {}} 1007 do_test without_rowid3-14.2.2.7 { 1008 execsql { INSERT INTO t3 VALUES(1, NULL, 1) } 1009 } {} 1010 1011 # Repeat for TEMP tables 1012 # 1013 drop_all_tables 1014 do_test without_rowid3-14.1tmp.1 { 1015 # Adding a column with a REFERENCES clause is not supported. 1016 execsql { 1017 CREATE TEMP TABLE t1(a PRIMARY KEY) WITHOUT rowid; 1018 CREATE TEMP TABLE t2(a, b); 1019 INSERT INTO temp.t2(a,b) VALUES(1,2); 1020 } 1021 catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 } 1022 } {0 {}} 1023 do_test without_rowid3-14.1tmp.2 { 1024 catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 } 1025 } {0 {}} 1026 do_test without_rowid3-14.1tmp.3 { 1027 catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL} 1028 } {0 {}} 1029 do_test without_rowid3-14.1tmp.4 { 1030 catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'} 1031 } {1 {Cannot add a REFERENCES column with non-NULL default value}} 1032 do_test without_rowid3-14.1tmp.5 { 1033 catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 } 1034 } {1 {Cannot add a REFERENCES column with non-NULL default value}} 1035 do_test without_rowid3-14.1tmp.6 { 1036 execsql { 1037 PRAGMA foreign_keys = off; 1038 ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1; 1039 PRAGMA foreign_keys = on; 1040 SELECT sql FROM temp.sqlite_schema WHERE name='t2'; 1041 } 1042 } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}} 1043 1044 sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db 1045 do_test without_rowid3-14.2tmp.1.1 { 1046 test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3 1047 } {{CREATE TABLE t1(a REFERENCES "t3")}} 1048 do_test without_rowid3-14.2tmp.1.2 { 1049 test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3 1050 } {{CREATE TABLE t1(a REFERENCES t2)}} 1051 do_test without_rowid3-14.2tmp.1.3 { 1052 test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3 1053 } {{CREATE TABLE t1(a REFERENCES "t3")}} 1054 sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db 1055 1056 # Test ALTER TABLE RENAME TABLE a bit. 1057 # 1058 do_test without_rowid3-14.2tmp.2.1 { 1059 drop_all_tables 1060 execsql { 1061 CREATE TEMP TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid; 1062 CREATE TEMP TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2) 1063 WITHOUT rowid; 1064 CREATE TEMP TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1); 1065 } 1066 execsql { SELECT sql FROM sqlite_temp_schema WHERE type = 'table'} 1067 } [list \ 1068 {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid} \ 1069 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2) 1070 WITHOUT rowid} \ 1071 {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)} \ 1072 ] 1073 do_test without_rowid3-14.2tmp.2.2 { 1074 execsql { ALTER TABLE t1 RENAME TO t4 } 1075 execsql { SELECT sql FROM temp.sqlite_schema WHERE type = 'table'} 1076 } [list \ 1077 {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid} \ 1078 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2) 1079 WITHOUT rowid} \ 1080 {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \ 1081 ] 1082 do_test without_rowid3-14.2tmp.2.3 { 1083 catchsql { INSERT INTO t3 VALUES(1, 2, 3) } 1084 } {1 {FOREIGN KEY constraint failed}} 1085 do_test without_rowid3-14.2tmp.2.4 { 1086 execsql { INSERT INTO t4 VALUES(1, NULL) } 1087 } {} 1088 do_test without_rowid3-14.2tmp.2.5 { 1089 catchsql { UPDATE t4 SET b = 5 } 1090 } {1 {FOREIGN KEY constraint failed}} 1091 do_test without_rowid3-14.2tmp.2.6 { 1092 catchsql { UPDATE t4 SET b = 1 } 1093 } {0 {}} 1094 do_test without_rowid3-14.2tmp.2.7 { 1095 execsql { INSERT INTO t3 VALUES(1, NULL, 1) } 1096 } {} 1097 1098 # Repeat for ATTACH-ed tables 1099 # 1100 drop_all_tables 1101 do_test without_rowid3-14.1aux.1 { 1102 # Adding a column with a REFERENCES clause is not supported. 1103 execsql { 1104 ATTACH ':memory:' AS aux; 1105 CREATE TABLE aux.t1(a PRIMARY KEY) WITHOUT rowid; 1106 CREATE TABLE aux.t2(a, b); 1107 INSERT INTO aux.t2(a,b) VALUES(1,2); 1108 } 1109 catchsql { ALTER TABLE t2 ADD COLUMN c REFERENCES t1 } 1110 } {0 {}} 1111 do_test without_rowid3-14.1aux.2 { 1112 catchsql { ALTER TABLE t2 ADD COLUMN d DEFAULT NULL REFERENCES t1 } 1113 } {0 {}} 1114 do_test without_rowid3-14.1aux.3 { 1115 catchsql { ALTER TABLE t2 ADD COLUMN e REFERENCES t1 DEFAULT NULL} 1116 } {0 {}} 1117 do_test without_rowid3-14.1aux.4 { 1118 catchsql { ALTER TABLE t2 ADD COLUMN f REFERENCES t1 DEFAULT 'text'} 1119 } {1 {Cannot add a REFERENCES column with non-NULL default value}} 1120 do_test without_rowid3-14.1aux.5 { 1121 catchsql { ALTER TABLE t2 ADD COLUMN g DEFAULT CURRENT_TIME REFERENCES t1 } 1122 } {1 {Cannot add a REFERENCES column with non-NULL default value}} 1123 do_test without_rowid3-14.1aux.6 { 1124 execsql { 1125 PRAGMA foreign_keys = off; 1126 ALTER TABLE t2 ADD COLUMN h DEFAULT 'text' REFERENCES t1; 1127 PRAGMA foreign_keys = on; 1128 SELECT sql FROM aux.sqlite_schema WHERE name='t2'; 1129 } 1130 } {{CREATE TABLE t2(a, b, c REFERENCES t1, d DEFAULT NULL REFERENCES t1, e REFERENCES t1 DEFAULT NULL, h DEFAULT 'text' REFERENCES t1)}} 1131 1132 sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db 1133 do_test without_rowid3-14.2aux.1.1 { 1134 test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t2 t3 1135 } {{CREATE TABLE t1(a REFERENCES "t3")}} 1136 do_test without_rowid3-14.2aux.1.2 { 1137 test_rename_parent {CREATE TABLE t1(a REFERENCES t2)} t4 t3 1138 } {{CREATE TABLE t1(a REFERENCES t2)}} 1139 do_test without_rowid3-14.2aux.1.3 { 1140 test_rename_parent {CREATE TABLE t1(a REFERENCES "t2")} t2 t3 1141 } {{CREATE TABLE t1(a REFERENCES "t3")}} 1142 sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db 1143 1144 # Test ALTER TABLE RENAME TABLE a bit. 1145 # 1146 do_test without_rowid3-14.2aux.2.1 { 1147 drop_all_tables 1148 execsql { 1149 CREATE TABLE aux.t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid; 1150 CREATE TABLE aux.t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2) 1151 WITHOUT rowid; 1152 CREATE TABLE aux.t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1); 1153 } 1154 execsql { SELECT sql FROM aux.sqlite_schema WHERE type = 'table'} 1155 } [list \ 1156 {CREATE TABLE t1(a PRIMARY KEY, b REFERENCES t1) WITHOUT rowid} \ 1157 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES t1, c REFERENCES t2) 1158 WITHOUT rowid} \ 1159 {CREATE TABLE t3(a REFERENCES t1, b REFERENCES t2, c REFERENCES t1)} \ 1160 ] 1161 do_test without_rowid3-14.2aux.2.2 { 1162 execsql { ALTER TABLE t1 RENAME TO t4 } 1163 execsql { SELECT sql FROM aux.sqlite_schema WHERE type = 'table'} 1164 } [list \ 1165 {CREATE TABLE "t4"(a PRIMARY KEY, b REFERENCES "t4") WITHOUT rowid} \ 1166 {CREATE TABLE t2(a PRIMARY KEY, b REFERENCES "t4", c REFERENCES t2) 1167 WITHOUT rowid} \ 1168 {CREATE TABLE t3(a REFERENCES "t4", b REFERENCES t2, c REFERENCES "t4")} \ 1169 ] 1170 do_test without_rowid3-14.2aux.2.3 { 1171 catchsql { INSERT INTO t3 VALUES(1, 2, 3) } 1172 } {1 {FOREIGN KEY constraint failed}} 1173 do_test without_rowid3-14.2aux.2.4 { 1174 execsql { INSERT INTO t4 VALUES(1, NULL) } 1175 } {} 1176 do_test without_rowid3-14.2aux.2.5 { 1177 catchsql { UPDATE t4 SET b = 5 } 1178 } {1 {FOREIGN KEY constraint failed}} 1179 do_test without_rowid3-14.2aux.2.6 { 1180 catchsql { UPDATE t4 SET b = 1 } 1181 } {0 {}} 1182 do_test without_rowid3-14.2aux.2.7 { 1183 execsql { INSERT INTO t3 VALUES(1, NULL, 1) } 1184 } {} 1185 } 1186 1187 do_test without_rowid3-2.14.3.1 { 1188 drop_all_tables 1189 execsql { 1190 CREATE TABLE t1(a, b REFERENCES nosuchtable); 1191 DROP TABLE t1; 1192 } 1193 } {} 1194 do_test without_rowid3-2.14.3.2 { 1195 execsql { 1196 CREATE TABLE t1(a PRIMARY KEY, b) WITHOUT rowid; 1197 INSERT INTO t1 VALUES('a', 1); 1198 CREATE TABLE t2(x REFERENCES t1); 1199 INSERT INTO t2 VALUES('a'); 1200 } 1201 } {} 1202 do_test without_rowid3-2.14.3.3 { 1203 catchsql { DROP TABLE t1 } 1204 } {1 {FOREIGN KEY constraint failed}} 1205 do_test without_rowid3-2.14.3.4 { 1206 execsql { 1207 DELETE FROM t2; 1208 DROP TABLE t1; 1209 } 1210 } {} 1211 do_test without_rowid3-2.14.3.4 { 1212 catchsql { INSERT INTO t2 VALUES('x') } 1213 } {1 {no such table: main.t1}} 1214 do_test without_rowid3-2.14.3.5 { 1215 execsql { 1216 CREATE TABLE t1(x PRIMARY KEY) WITHOUT rowid; 1217 INSERT INTO t1 VALUES('x'); 1218 } 1219 execsql { INSERT INTO t2 VALUES('x') } 1220 } {} 1221 do_test without_rowid3-2.14.3.6 { 1222 catchsql { DROP TABLE t1 } 1223 } {1 {FOREIGN KEY constraint failed}} 1224 do_test without_rowid3-2.14.3.7 { 1225 execsql { 1226 DROP TABLE t2; 1227 DROP TABLE t1; 1228 } 1229 } {} 1230 do_test without_rowid3-2.14.3.8 { 1231 execsql { 1232 CREATE TABLE pp(x, y, PRIMARY KEY(x, y)) WITHOUT ROWID; 1233 CREATE TABLE cc(a, b, FOREIGN KEY(a, b) REFERENCES pp(x, z)); 1234 } 1235 catchsql { INSERT INTO cc VALUES(1, 2) } 1236 } {1 {foreign key mismatch - "cc" referencing "pp"}} 1237 do_test without_rowid3-2.14.3.9 { 1238 execsql { DROP TABLE cc } 1239 } {} 1240 do_test without_rowid3-2.14.3.10 { 1241 execsql { 1242 CREATE TABLE cc(a, b, 1243 FOREIGN KEY(a, b) REFERENCES pp DEFERRABLE INITIALLY DEFERRED 1244 ); 1245 } 1246 execsql { 1247 INSERT INTO pp VALUES('a', 'b'); 1248 INSERT INTO cc VALUES('a', 'b'); 1249 BEGIN; 1250 DROP TABLE pp; 1251 CREATE TABLE pp(a, b, c, PRIMARY KEY(b, c)) WITHOUT rowid; 1252 INSERT INTO pp VALUES(1, 'a', 'b'); 1253 COMMIT; 1254 } 1255 } {} 1256 do_test without_rowid3-2.14.3.11 { 1257 execsql { 1258 BEGIN; 1259 DROP TABLE cc; 1260 DROP TABLE pp; 1261 COMMIT; 1262 } 1263 } {} 1264 do_test without_rowid3-2.14.3.12 { 1265 execsql { 1266 CREATE TABLE b1(a, b); 1267 CREATE TABLE b2(a, b REFERENCES b1); 1268 DROP TABLE b1; 1269 } 1270 } {} 1271 do_test without_rowid3-2.14.3.13 { 1272 execsql { 1273 CREATE TABLE b3(a, b REFERENCES b2 DEFERRABLE INITIALLY DEFERRED); 1274 DROP TABLE b2; 1275 } 1276 } {} 1277 1278 # Test that nothing goes wrong when dropping a table that refers to a view. 1279 # Or dropping a view that an existing FK (incorrectly) refers to. Or either 1280 # of the above scenarios with a virtual table. 1281 drop_all_tables 1282 do_test without_rowid3-2.14.4.1 { 1283 execsql { 1284 CREATE TABLE t1(x REFERENCES v); 1285 CREATE VIEW v AS SELECT * FROM t1; 1286 } 1287 } {} 1288 do_test without_rowid3-2.14.4.2 { 1289 execsql { 1290 DROP VIEW v; 1291 } 1292 } {} 1293 ifcapable vtab { 1294 register_echo_module db 1295 do_test without_rowid3-2.14.4.3 { 1296 execsql { CREATE VIRTUAL TABLE v USING echo(t1) } 1297 } {} 1298 do_test without_rowid3-2.14.4.2 { 1299 execsql { 1300 DROP TABLE v; 1301 } 1302 } {} 1303 } 1304 1305 #------------------------------------------------------------------------- 1306 # The following tests, without_rowid3-15.*, test that unnecessary FK related scans 1307 # and lookups are avoided when the constraint counters are zero. 1308 # 1309 drop_all_tables 1310 proc execsqlS {zSql} { 1311 set ::sqlite_search_count 0 1312 set ::sqlite_found_count 0 1313 set res [uplevel [list execsql $zSql]] 1314 concat [expr $::sqlite_found_count + $::sqlite_search_count] $res 1315 } 1316 do_test without_rowid3-15.1.1 { 1317 execsql { 1318 CREATE TABLE pp(a PRIMARY KEY, b) WITHOUT rowid; 1319 CREATE TABLE cc(x, y REFERENCES pp DEFERRABLE INITIALLY DEFERRED); 1320 INSERT INTO pp VALUES(1, 'one'); 1321 INSERT INTO pp VALUES(2, 'two'); 1322 INSERT INTO cc VALUES('neung', 1); 1323 INSERT INTO cc VALUES('song', 2); 1324 } 1325 } {} 1326 do_test without_rowid3-15.1.2 { 1327 execsqlS { INSERT INTO pp VALUES(3, 'three') } 1328 } {0} 1329 do_test without_rowid3-15.1.3 { 1330 execsql { 1331 BEGIN; 1332 INSERT INTO cc VALUES('see', 4); -- Violates deferred constraint 1333 } 1334 execsqlS { INSERT INTO pp VALUES(5, 'five') } 1335 } {2} 1336 do_test without_rowid3-15.1.4 { 1337 execsql { DELETE FROM cc WHERE x = 'see' } 1338 execsqlS { INSERT INTO pp VALUES(6, 'six') } 1339 } {0} 1340 do_test without_rowid3-15.1.5 { 1341 execsql COMMIT 1342 } {} 1343 do_test without_rowid3-15.1.6 { 1344 execsql BEGIN 1345 execsqlS { 1346 DELETE FROM cc WHERE x = 'neung'; 1347 ROLLBACK; 1348 } 1349 } {1} 1350 do_test without_rowid3-15.1.7 { 1351 execsql { 1352 BEGIN; 1353 DELETE FROM pp WHERE a = 2; 1354 } 1355 execsqlS { 1356 DELETE FROM cc WHERE x = 'neung'; 1357 ROLLBACK; 1358 } 1359 } {2} 1360 1361 #------------------------------------------------------------------------- 1362 # This next block of tests, without_rowid3-16.*, test that rows that refer to 1363 # themselves may be inserted and deleted. 1364 # 1365 foreach {tn zSchema} { 1366 1 { CREATE TABLE self(a INTEGER PRIMARY KEY, b REFERENCES self(a)) 1367 WITHOUT rowid } 1368 2 { CREATE TABLE self(a PRIMARY KEY, b REFERENCES self(a)) WITHOUT rowid } 1369 3 { CREATE TABLE self(a UNIQUE, b INT PRIMARY KEY REFERENCES self(a)) 1370 WITHOUT rowid } 1371 } { 1372 drop_all_tables 1373 do_test without_rowid3-16.1.$tn.1 { 1374 execsql $zSchema 1375 execsql { INSERT INTO self VALUES(13, 13) } 1376 } {} 1377 do_test without_rowid3-16.1.$tn.2 { 1378 execsql { UPDATE self SET a = 14, b = 14 } 1379 } {} 1380 1381 do_test without_rowid3-16.1.$tn.3 { 1382 catchsql { UPDATE self SET b = 15 } 1383 } {1 {FOREIGN KEY constraint failed}} 1384 1385 do_test without_rowid3-16.1.$tn.4 { 1386 catchsql { UPDATE self SET a = 15 } 1387 } {1 {FOREIGN KEY constraint failed}} 1388 1389 do_test without_rowid3-16.1.$tn.5 { 1390 catchsql { UPDATE self SET a = 15, b = 16 } 1391 } {1 {FOREIGN KEY constraint failed}} 1392 1393 do_test without_rowid3-16.1.$tn.6 { 1394 catchsql { UPDATE self SET a = 17, b = 17 } 1395 } {0 {}} 1396 1397 do_test without_rowid3-16.1.$tn.7 { 1398 execsql { DELETE FROM self } 1399 } {} 1400 do_test without_rowid3-16.1.$tn.8 { 1401 catchsql { INSERT INTO self VALUES(20, 21) } 1402 } {1 {FOREIGN KEY constraint failed}} 1403 } 1404 1405 # Additional tests cases using multi-column self-referential 1406 # FOREIGN KEY constraints. 1407 # 1408 drop_all_tables 1409 do_execsql_test without_rowid3-16.4.1.1 { 1410 PRAGMA foreign_keys=ON; 1411 CREATE TABLE t1(a,b,c,d,e,f, 1412 UNIQUE (a,b), 1413 PRIMARY KEY (e,c), 1414 FOREIGN KEY (d,f) REFERENCES t1(e,c) 1415 ) WITHOUT rowid; 1416 INSERT INTO t1 VALUES(1,2,3,5,5,3); 1417 INSERT INTO t1 VALUES(2,3,4,6,6,4); 1418 INSERT INTO t1 VALUES('x','y',1.5,'fizzle','fizzle',1.5); 1419 SELECT *, '|' FROM t1 ORDER BY a, b; 1420 } {1 2 3 5 5 3 | 2 3 4 6 6 4 | x y 1.5 fizzle fizzle 1.5 |} 1421 1422 do_execsql_test without_rowid3-16.4.1.2 { 1423 UPDATE t1 SET c=99, f=99 WHERE a=1; 1424 SELECT *, '|' FROM t1 ORDER BY a, b; 1425 } {1 2 99 5 5 99 | 2 3 4 6 6 4 | x y 1.5 fizzle fizzle 1.5 |} 1426 1427 do_execsql_test without_rowid3-16.4.1.3 { 1428 UPDATE t1 SET e=876, d=876 WHERE a=2; 1429 SELECT *, '|' FROM t1 ORDER BY a, b; 1430 } {1 2 99 5 5 99 | 2 3 4 876 876 4 | x y 1.5 fizzle fizzle 1.5 |} 1431 1432 do_test without_rowid3-16.4.1.4 { 1433 catchsql { 1434 UPDATE t1 SET c=11, e=22 WHERE a=1; 1435 } 1436 } {1 {FOREIGN KEY constraint failed}} 1437 1438 do_test without_rowid3-16.4.1.5 { 1439 catchsql { 1440 UPDATE t1 SET d=11, f=22 WHERE a=1; 1441 } 1442 } {1 {FOREIGN KEY constraint failed}} 1443 1444 do_execsql_test without_rowid3-16.4.1.6 { 1445 DELETE FROM t1 WHERE a=1; 1446 SELECT *, '|' FROM t1 ORDER BY a, b; 1447 } {2 3 4 876 876 4 | x y 1.5 fizzle fizzle 1.5 |} 1448 1449 do_execsql_test without_rowid3-16.4.2.1 { 1450 DROP TABLE t1; 1451 CREATE TABLE t1(a,b,c,d,e,f, 1452 PRIMARY KEY (a,b), 1453 UNIQUE (e,c), 1454 FOREIGN KEY (d,f) REFERENCES t1(e,c) 1455 ) WITHOUT rowid; 1456 INSERT INTO t1 VALUES(1,2,3,5,5,3); 1457 INSERT INTO t1 VALUES(2,3,4,6,6,4); 1458 INSERT INTO t1 VALUES('x','y',1.5,'fizzle','fizzle',1.5); 1459 SELECT *, '|' FROM t1 ORDER BY a, b; 1460 } {1 2 3 5 5 3 | 2 3 4 6 6 4 | x y 1.5 fizzle fizzle 1.5 |} 1461 1462 do_execsql_test without_rowid3-16.4.2.2 { 1463 UPDATE t1 SET c=99, f=99 WHERE a=1; 1464 SELECT *, '|' FROM t1 ORDER BY a, b; 1465 } {1 2 99 5 5 99 | 2 3 4 6 6 4 | x y 1.5 fizzle fizzle 1.5 |} 1466 1467 do_execsql_test without_rowid3-16.4.2.3 { 1468 UPDATE t1 SET e=876, d=876 WHERE a=2; 1469 SELECT *, '|' FROM t1 ORDER BY a, b; 1470 } {1 2 99 5 5 99 | 2 3 4 876 876 4 | x y 1.5 fizzle fizzle 1.5 |} 1471 1472 do_test without_rowid3-16.4.2.4 { 1473 catchsql { 1474 UPDATE t1 SET c=11, e=22 WHERE a=1; 1475 } 1476 } {1 {FOREIGN KEY constraint failed}} 1477 1478 do_test without_rowid3-16.4.2.5 { 1479 catchsql { 1480 UPDATE t1 SET d=11, f=22 WHERE a=1; 1481 } 1482 } {1 {FOREIGN KEY constraint failed}} 1483 1484 do_execsql_test without_rowid3-16.4.2.6 { 1485 DELETE FROM t1 WHERE a=1; 1486 SELECT *, '|' FROM t1 ORDER BY a, b; 1487 } {2 3 4 876 876 4 | x y 1.5 fizzle fizzle 1.5 |} 1488 1489 1490 #------------------------------------------------------------------------- 1491 # This next block of tests, without_rowid3-17.*, tests that if "PRAGMA count_changes" 1492 # is turned on statements that violate immediate FK constraints return 1493 # SQLITE_CONSTRAINT immediately, not after returning a number of rows. 1494 # Whereas statements that violate deferred FK constraints return the number 1495 # of rows before failing. 1496 # 1497 # Also test that rows modified by FK actions are not counted in either the 1498 # returned row count or the values returned by sqlite3_changes(). Like 1499 # trigger related changes, they are included in sqlite3_total_changes() though. 1500 # 1501 drop_all_tables 1502 do_test without_rowid3-17.1.1 { 1503 execsql { PRAGMA count_changes = 1 } 1504 execsql { 1505 CREATE TABLE one(a, b, c, UNIQUE(b, c)); 1506 CREATE TABLE two(d, e, f, FOREIGN KEY(e, f) REFERENCES one(b, c)); 1507 INSERT INTO one VALUES(1, 2, 3); 1508 } 1509 } {1} 1510 do_test without_rowid3-17.1.2 { 1511 set STMT [sqlite3_prepare_v2 db "INSERT INTO two VALUES(4, 5, 6)" -1 dummy] 1512 sqlite3_step $STMT 1513 } {SQLITE_CONSTRAINT} 1514 verify_ex_errcode without_rowid3-17.1.2b SQLITE_CONSTRAINT_FOREIGNKEY 1515 ifcapable autoreset { 1516 do_test without_rowid3-17.1.3 { 1517 sqlite3_step $STMT 1518 } {SQLITE_CONSTRAINT} 1519 verify_ex_errcode without_rowid3-17.1.3b SQLITE_CONSTRAINT_FOREIGNKEY 1520 } else { 1521 do_test without_rowid3-17.1.3 { 1522 sqlite3_step $STMT 1523 } {SQLITE_MISUSE} 1524 } 1525 do_test without_rowid3-17.1.4 { 1526 sqlite3_finalize $STMT 1527 } {SQLITE_CONSTRAINT} 1528 verify_ex_errcode without_rowid3-17.1.4b SQLITE_CONSTRAINT_FOREIGNKEY 1529 do_test without_rowid3-17.1.5 { 1530 execsql { 1531 INSERT INTO one VALUES(2, 3, 4); 1532 INSERT INTO one VALUES(3, 4, 5); 1533 INSERT INTO two VALUES(1, 2, 3); 1534 INSERT INTO two VALUES(2, 3, 4); 1535 INSERT INTO two VALUES(3, 4, 5); 1536 } 1537 } {1 1 1 1 1} 1538 do_test without_rowid3-17.1.6 { 1539 catchsql { 1540 BEGIN; 1541 INSERT INTO one VALUES(0, 0, 0); 1542 UPDATE two SET e=e+1, f=f+1; 1543 } 1544 } {1 {FOREIGN KEY constraint failed}} 1545 do_test without_rowid3-17.1.7 { 1546 execsql { SELECT * FROM one } 1547 } {1 2 3 2 3 4 3 4 5 0 0 0} 1548 do_test without_rowid3-17.1.8 { 1549 execsql { SELECT * FROM two } 1550 } {1 2 3 2 3 4 3 4 5} 1551 do_test without_rowid3-17.1.9 { 1552 execsql COMMIT 1553 } {} 1554 do_test without_rowid3-17.1.10 { 1555 execsql { 1556 CREATE TABLE three( 1557 g, h, i, 1558 FOREIGN KEY(h, i) REFERENCES one(b, c) DEFERRABLE INITIALLY DEFERRED 1559 ); 1560 } 1561 } {} 1562 do_test without_rowid3-17.1.11 { 1563 set STMT [sqlite3_prepare_v2 db "INSERT INTO three VALUES(7, 8, 9)" -1 dummy] 1564 sqlite3_step $STMT 1565 } {SQLITE_ROW} 1566 do_test without_rowid3-17.1.12 { 1567 sqlite3_column_text $STMT 0 1568 } {1} 1569 do_test without_rowid3-17.1.13 { 1570 sqlite3_step $STMT 1571 } {SQLITE_CONSTRAINT} 1572 verify_ex_errcode without_rowid3-17.1.13b SQLITE_CONSTRAINT_FOREIGNKEY 1573 do_test without_rowid3-17.1.14 { 1574 sqlite3_finalize $STMT 1575 } {SQLITE_CONSTRAINT} 1576 verify_ex_errcode without_rowid3-17.1.14b SQLITE_CONSTRAINT_FOREIGNKEY 1577 1578 drop_all_tables 1579 do_test without_rowid3-17.2.1 { 1580 execsql { 1581 CREATE TABLE high("a'b!" PRIMARY KEY, b) WITHOUT rowid; 1582 CREATE TABLE low( 1583 c, 1584 "d&6" REFERENCES high ON UPDATE CASCADE ON DELETE CASCADE 1585 ); 1586 } 1587 } {} 1588 do_test without_rowid3-17.2.2 { 1589 execsql { 1590 INSERT INTO high VALUES('a', 'b'); 1591 INSERT INTO low VALUES('b', 'a'); 1592 } 1593 db changes 1594 } {1} 1595 set nTotal [db total_changes] 1596 do_test without_rowid3-17.2.3 { 1597 execsql { UPDATE high SET "a'b!" = 'c' } 1598 } {1} 1599 do_test without_rowid3-17.2.4 { 1600 db changes 1601 } {1} 1602 do_test without_rowid3-17.2.5 { 1603 expr [db total_changes] - $nTotal 1604 } {2} 1605 do_test without_rowid3-17.2.6 { 1606 execsql { SELECT * FROM high ; SELECT * FROM low } 1607 } {c b b c} 1608 do_test without_rowid3-17.2.7 { 1609 execsql { DELETE FROM high } 1610 } {1} 1611 do_test without_rowid3-17.2.8 { 1612 db changes 1613 } {1} 1614 do_test without_rowid3-17.2.9 { 1615 expr [db total_changes] - $nTotal 1616 } {4} 1617 do_test without_rowid3-17.2.10 { 1618 execsql { SELECT * FROM high ; SELECT * FROM low } 1619 } {} 1620 execsql { PRAGMA count_changes = 0 } 1621 1622 #------------------------------------------------------------------------- 1623 # Test that the authorization callback works. 1624 # 1625 1626 ifcapable auth { 1627 do_test without_rowid3-18.1 { 1628 execsql { 1629 CREATE TABLE long(a, b PRIMARY KEY, c) WITHOUT rowid; 1630 CREATE TABLE short(d, e, f REFERENCES long); 1631 CREATE TABLE mid(g, h, i REFERENCES long DEFERRABLE INITIALLY DEFERRED); 1632 } 1633 } {} 1634 1635 proc auth {args} {eval lappend ::authargs [lrange $args 0 4]; return SQLITE_OK} 1636 db auth auth 1637 1638 # An insert on the parent table must read the child key of any deferred 1639 # foreign key constraints. But not the child key of immediate constraints. 1640 set authargs {} 1641 do_test without_rowid3-18.2 { 1642 execsql { INSERT INTO long VALUES(1, 2, 3) } 1643 set authargs 1644 } {SQLITE_INSERT long {} main {} SQLITE_READ mid i main {}} 1645 1646 # An insert on the child table of an immediate constraint must read the 1647 # parent key columns (to see if it is a violation or not). 1648 set authargs {} 1649 do_test without_rowid3-18.3 { 1650 execsql { INSERT INTO short VALUES(1, 3, 2) } 1651 set authargs 1652 } {SQLITE_INSERT short {} main {} SQLITE_READ long b main {}} 1653 1654 # As must an insert on the child table of a deferred constraint. 1655 set authargs {} 1656 do_test without_rowid3-18.4 { 1657 execsql { INSERT INTO mid VALUES(1, 3, 2) } 1658 set authargs 1659 } {SQLITE_INSERT mid {} main {} SQLITE_READ long b main {}} 1660 1661 do_test without_rowid3-18.5 { 1662 execsql { 1663 CREATE TABLE nought(a, b PRIMARY KEY, c) WITHOUT rowid; 1664 CREATE TABLE cross(d, e, f, 1665 FOREIGN KEY(e) REFERENCES nought(b) ON UPDATE CASCADE 1666 ); 1667 } 1668 execsql { INSERT INTO nought VALUES(2, 1, 2) } 1669 execsql { INSERT INTO cross VALUES(0, 1, 0) } 1670 set authargs [list] 1671 execsql { UPDATE nought SET b = 5 } 1672 set authargs 1673 } {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 {}} 1674 1675 do_test without_rowid3-18.6 { 1676 execsql {SELECT * FROM cross} 1677 } {0 5 0} 1678 1679 do_test without_rowid3-18.7 { 1680 execsql { 1681 CREATE TABLE one(a INT PRIMARY KEY, b) WITHOUT rowid; 1682 CREATE TABLE two(b, c REFERENCES one); 1683 INSERT INTO one VALUES(101, 102); 1684 } 1685 set authargs [list] 1686 execsql { INSERT INTO two VALUES(100, 101); } 1687 set authargs 1688 } {SQLITE_INSERT two {} main {} SQLITE_READ one a main {}} 1689 1690 # Return SQLITE_IGNORE to requests to read from the parent table. This 1691 # causes inserts of non-NULL keys into the child table to fail. 1692 # 1693 rename auth {} 1694 proc auth {args} { 1695 if {[lindex $args 1] == "long"} {return SQLITE_IGNORE} 1696 return SQLITE_OK 1697 } 1698 do_test without_rowid3-18.8 { 1699 catchsql { INSERT INTO short VALUES(1, 3, 2) } 1700 } {1 {FOREIGN KEY constraint failed}} 1701 do_test without_rowid3-18.9 { 1702 execsql { INSERT INTO short VALUES(1, 3, NULL) } 1703 } {} 1704 do_test without_rowid3-18.10 { 1705 execsql { SELECT * FROM short } 1706 } {1 3 2 1 3 {}} 1707 do_test without_rowid3-18.11 { 1708 catchsql { UPDATE short SET f = 2 WHERE f IS NULL } 1709 } {1 {FOREIGN KEY constraint failed}} 1710 1711 db auth {} 1712 unset authargs 1713 } 1714 1715 1716 do_test without_rowid3-19.1 { 1717 execsql { 1718 CREATE TABLE main(id INT PRIMARY KEY) WITHOUT rowid; 1719 CREATE TABLE sub(id INT REFERENCES main(id)); 1720 INSERT INTO main VALUES(1); 1721 INSERT INTO main VALUES(2); 1722 INSERT INTO sub VALUES(2); 1723 } 1724 } {} 1725 do_test without_rowid3-19.2 { 1726 set S [sqlite3_prepare_v2 db "DELETE FROM main WHERE id = ?" -1 dummy] 1727 sqlite3_bind_int $S 1 2 1728 sqlite3_step $S 1729 } {SQLITE_CONSTRAINT} 1730 verify_ex_errcode without_rowid3-19.2b SQLITE_CONSTRAINT_FOREIGNKEY 1731 do_test without_rowid3-19.3 { 1732 sqlite3_reset $S 1733 } {SQLITE_CONSTRAINT} 1734 verify_ex_errcode without_rowid3-19.3b SQLITE_CONSTRAINT_FOREIGNKEY 1735 do_test without_rowid3-19.4 { 1736 sqlite3_bind_int $S 1 1 1737 sqlite3_step $S 1738 } {SQLITE_DONE} 1739 do_test without_rowid3-19.4 { 1740 sqlite3_finalize $S 1741 } {SQLITE_OK} 1742 1743 drop_all_tables 1744 do_test without_rowid3-20.1 { 1745 execsql { 1746 CREATE TABLE pp(a PRIMARY KEY, b) WITHOUT rowid; 1747 CREATE TABLE cc(c PRIMARY KEY, d REFERENCES pp) WITHOUT rowid; 1748 } 1749 } {} 1750 1751 foreach {tn insert} { 1752 1 "INSERT" 1753 2 "INSERT OR IGNORE" 1754 3 "INSERT OR ABORT" 1755 4 "INSERT OR ROLLBACK" 1756 5 "INSERT OR REPLACE" 1757 6 "INSERT OR FAIL" 1758 } { 1759 do_test without_rowid3-20.2.$tn.1 { 1760 catchsql "$insert INTO cc VALUES(1, 2)" 1761 } {1 {FOREIGN KEY constraint failed}} 1762 do_test without_rowid3-20.2.$tn.2 { 1763 execsql { SELECT * FROM cc } 1764 } {} 1765 do_test without_rowid3-20.2.$tn.3 { 1766 execsql { 1767 BEGIN; 1768 INSERT INTO pp VALUES(2, 'two'); 1769 INSERT INTO cc VALUES(1, 2); 1770 } 1771 catchsql "$insert INTO cc VALUES(3, 4)" 1772 } {1 {FOREIGN KEY constraint failed}} 1773 do_test without_rowid3-20.2.$tn.4 { 1774 execsql { COMMIT ; SELECT * FROM cc } 1775 } {1 2} 1776 do_test without_rowid3-20.2.$tn.5 { 1777 execsql { DELETE FROM cc ; DELETE FROM pp } 1778 } {} 1779 } 1780 1781 foreach {tn update} { 1782 1 "UPDATE" 1783 2 "UPDATE OR IGNORE" 1784 3 "UPDATE OR ABORT" 1785 4 "UPDATE OR ROLLBACK" 1786 5 "UPDATE OR REPLACE" 1787 6 "UPDATE OR FAIL" 1788 } { 1789 do_test without_rowid3-20.3.$tn.1 { 1790 execsql { 1791 INSERT INTO pp VALUES(2, 'two'); 1792 INSERT INTO cc VALUES(1, 2); 1793 } 1794 } {} 1795 do_test without_rowid3-20.3.$tn.2 { 1796 catchsql "$update pp SET a = 1" 1797 } {1 {FOREIGN KEY constraint failed}} 1798 do_test without_rowid3-20.3.$tn.3 { 1799 execsql { SELECT * FROM pp } 1800 } {2 two} 1801 do_test without_rowid3-20.3.$tn.4 { 1802 catchsql "$update cc SET d = 1" 1803 } {1 {FOREIGN KEY constraint failed}} 1804 do_test without_rowid3-20.3.$tn.5 { 1805 execsql { SELECT * FROM cc } 1806 } {1 2} 1807 do_test without_rowid3-20.3.$tn.6 { 1808 execsql { 1809 BEGIN; 1810 INSERT INTO pp VALUES(3, 'three'); 1811 } 1812 catchsql "$update pp SET a = 1 WHERE a = 2" 1813 } {1 {FOREIGN KEY constraint failed}} 1814 do_test without_rowid3-20.3.$tn.7 { 1815 execsql { COMMIT ; SELECT * FROM pp } 1816 } {2 two 3 three} 1817 do_test without_rowid3-20.3.$tn.8 { 1818 execsql { 1819 BEGIN; 1820 INSERT INTO cc VALUES(2, 2); 1821 } 1822 catchsql "$update cc SET d = 1 WHERE c = 1" 1823 } {1 {FOREIGN KEY constraint failed}} 1824 do_test without_rowid3-20.3.$tn.9 { 1825 execsql { COMMIT ; SELECT * FROM cc } 1826 } {1 2 2 2} 1827 do_test without_rowid3-20.3.$tn.10 { 1828 execsql { DELETE FROM cc ; DELETE FROM pp } 1829 } {} 1830 } 1831 1832 #------------------------------------------------------------------------- 1833 # The following block of tests, those prefixed with "without_rowid3-genfkey.", 1834 # are the same tests that were used to test the ".genfkey" command provided 1835 # by the shell tool. So these tests show that the built-in foreign key 1836 # implementation is more or less compatible with the triggers generated 1837 # by genfkey. 1838 # 1839 drop_all_tables 1840 do_test without_rowid3-genfkey.1.1 { 1841 execsql { 1842 CREATE TABLE t1(a INT PRIMARY KEY, b, c, UNIQUE(b, c)) WITHOUT rowid; 1843 CREATE TABLE t2(e REFERENCES t1, f); 1844 CREATE TABLE t3(g, h, i, FOREIGN KEY (h, i) REFERENCES t1(b, c)); 1845 } 1846 } {} 1847 do_test without_rowid3-genfkey.1.2 { 1848 catchsql { INSERT INTO t2 VALUES(1, 2) } 1849 } {1 {FOREIGN KEY constraint failed}} 1850 do_test without_rowid3-genfkey.1.3 { 1851 execsql { 1852 INSERT INTO t1 VALUES(1, 2, 3); 1853 INSERT INTO t2 VALUES(1, 2); 1854 } 1855 } {} 1856 do_test without_rowid3-genfkey.1.4 { 1857 execsql { INSERT INTO t2 VALUES(NULL, 3) } 1858 } {} 1859 do_test without_rowid3-genfkey.1.5 { 1860 catchsql { UPDATE t2 SET e = 5 WHERE e IS NULL } 1861 } {1 {FOREIGN KEY constraint failed}} 1862 do_test without_rowid3-genfkey.1.6 { 1863 execsql { UPDATE t2 SET e = 1 WHERE e IS NULL } 1864 } {} 1865 do_test without_rowid3-genfkey.1.7 { 1866 execsql { UPDATE t2 SET e = NULL WHERE f = 3 } 1867 } {} 1868 do_test without_rowid3-genfkey.1.8 { 1869 catchsql { UPDATE t1 SET a = 10 } 1870 } {1 {FOREIGN KEY constraint failed}} 1871 do_test without_rowid3-genfkey.1.9 { 1872 catchsql { UPDATE t1 SET a = NULL } 1873 } {1 {NOT NULL constraint failed: t1.a}} 1874 do_test without_rowid3-genfkey.1.10 { 1875 catchsql { DELETE FROM t1 } 1876 } {1 {FOREIGN KEY constraint failed}} 1877 do_test without_rowid3-genfkey.1.11 { 1878 execsql { UPDATE t2 SET e = NULL } 1879 } {} 1880 do_test without_rowid3-genfkey.1.12 { 1881 execsql { 1882 UPDATE t1 SET a = 10; 1883 DELETE FROM t1; 1884 DELETE FROM t2; 1885 } 1886 } {} 1887 do_test without_rowid3-genfkey.1.13 { 1888 execsql { 1889 INSERT INTO t3 VALUES(1, NULL, NULL); 1890 INSERT INTO t3 VALUES(1, 2, NULL); 1891 INSERT INTO t3 VALUES(1, NULL, 3); 1892 } 1893 } {} 1894 do_test without_rowid3-genfkey.1.14 { 1895 catchsql { INSERT INTO t3 VALUES(3, 1, 4) } 1896 } {1 {FOREIGN KEY constraint failed}} 1897 do_test without_rowid3-genfkey.1.15 { 1898 execsql { 1899 INSERT INTO t1 VALUES(1, 1, 4); 1900 INSERT INTO t3 VALUES(3, 1, 4); 1901 } 1902 } {} 1903 do_test without_rowid3-genfkey.1.16 { 1904 catchsql { DELETE FROM t1 } 1905 } {1 {FOREIGN KEY constraint failed}} 1906 do_test without_rowid3-genfkey.1.17 { 1907 catchsql { UPDATE t1 SET b = 10} 1908 } {1 {FOREIGN KEY constraint failed}} 1909 do_test without_rowid3-genfkey.1.18 { 1910 execsql { UPDATE t1 SET a = 10} 1911 } {} 1912 do_test without_rowid3-genfkey.1.19 { 1913 catchsql { UPDATE t3 SET h = 'hello' WHERE i = 3} 1914 } {1 {FOREIGN KEY constraint failed}} 1915 1916 drop_all_tables 1917 do_test without_rowid3-genfkey.2.1 { 1918 execsql { 1919 CREATE TABLE t1(a INT PRIMARY KEY, b, c, UNIQUE(b, c)) WITHOUT rowid; 1920 CREATE TABLE t2(e REFERENCES t1 ON UPDATE CASCADE ON DELETE CASCADE, f); 1921 CREATE TABLE t3(g, h, i, 1922 FOREIGN KEY (h, i) 1923 REFERENCES t1(b, c) ON UPDATE CASCADE ON DELETE CASCADE 1924 ); 1925 } 1926 } {} 1927 do_test without_rowid3-genfkey.2.2 { 1928 execsql { 1929 INSERT INTO t1 VALUES(1, 2, 3); 1930 INSERT INTO t1 VALUES(4, 5, 6); 1931 INSERT INTO t2 VALUES(1, 'one'); 1932 INSERT INTO t2 VALUES(4, 'four'); 1933 } 1934 } {} 1935 do_test without_rowid3-genfkey.2.3 { 1936 execsql { 1937 UPDATE t1 SET a = 2 WHERE a = 1; 1938 SELECT * FROM t2; 1939 } 1940 } {2 one 4 four} 1941 do_test without_rowid3-genfkey.2.4 { 1942 execsql { 1943 DELETE FROM t1 WHERE a = 4; 1944 SELECT * FROM t2; 1945 } 1946 } {2 one} 1947 1948 do_test without_rowid3-genfkey.2.5 { 1949 execsql { 1950 INSERT INTO t3 VALUES('hello', 2, 3); 1951 UPDATE t1 SET c = 2; 1952 SELECT * FROM t3; 1953 } 1954 } {hello 2 2} 1955 do_test without_rowid3-genfkey.2.6 { 1956 execsql { 1957 DELETE FROM t1; 1958 SELECT * FROM t3; 1959 } 1960 } {} 1961 1962 drop_all_tables 1963 do_test without_rowid3-genfkey.3.1 { 1964 execsql { 1965 CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, UNIQUE(c, b)) WITHOUT rowid; 1966 CREATE TABLE t2(e REFERENCES t1 ON UPDATE SET NULL ON DELETE SET NULL, f); 1967 CREATE TABLE t3(g, h, i, 1968 FOREIGN KEY (h, i) 1969 REFERENCES t1(b, c) ON UPDATE SET NULL ON DELETE SET NULL 1970 ); 1971 } 1972 } {} 1973 do_test without_rowid3-genfkey.3.2 { 1974 execsql { 1975 INSERT INTO t1 VALUES(1, 2, 3); 1976 INSERT INTO t1 VALUES(4, 5, 6); 1977 INSERT INTO t2 VALUES(1, 'one'); 1978 INSERT INTO t2 VALUES(4, 'four'); 1979 } 1980 } {} 1981 do_test without_rowid3-genfkey.3.3 { 1982 execsql { 1983 UPDATE t1 SET a = 2 WHERE a = 1; 1984 SELECT * FROM t2; 1985 } 1986 } {{} one 4 four} 1987 do_test without_rowid3-genfkey.3.4 { 1988 execsql { 1989 DELETE FROM t1 WHERE a = 4; 1990 SELECT * FROM t2; 1991 } 1992 } {{} one {} four} 1993 do_test without_rowid3-genfkey.3.5 { 1994 execsql { 1995 INSERT INTO t3 VALUES('hello', 2, 3); 1996 UPDATE t1 SET c = 2; 1997 SELECT * FROM t3; 1998 } 1999 } {hello {} {}} 2000 do_test without_rowid3-genfkey.3.6 { 2001 execsql { 2002 UPDATE t3 SET h = 2, i = 2; 2003 DELETE FROM t1; 2004 SELECT * FROM t3; 2005 } 2006 } {hello {} {}} 2007 2008 #------------------------------------------------------------------------- 2009 # Verify that ticket dd08e5a988d00decc4a543daa8dbbfab9c577ad8 has been 2010 # fixed. 2011 # 2012 do_test without_rowid3-dd08e5.1.1 { 2013 execsql { 2014 PRAGMA foreign_keys=ON; 2015 CREATE TABLE tdd08(a INTEGER PRIMARY KEY, b) WITHOUT rowid; 2016 CREATE UNIQUE INDEX idd08 ON tdd08(a,b); 2017 INSERT INTO tdd08 VALUES(200,300); 2018 2019 CREATE TABLE tdd08_b(w,x,y, FOREIGN KEY(x,y) REFERENCES tdd08(a,b)); 2020 INSERT INTO tdd08_b VALUES(100,200,300); 2021 } 2022 } {} 2023 do_test without_rowid3-dd08e5.1.2 { 2024 catchsql { 2025 DELETE FROM tdd08; 2026 } 2027 } {1 {FOREIGN KEY constraint failed}} 2028 do_test without_rowid3-dd08e5.1.3 { 2029 execsql { 2030 SELECT * FROM tdd08; 2031 } 2032 } {200 300} 2033 do_test without_rowid3-dd08e5.1.4 { 2034 catchsql { 2035 INSERT INTO tdd08_b VALUES(400,500,300); 2036 } 2037 } {1 {FOREIGN KEY constraint failed}} 2038 do_test without_rowid3-dd08e5.1.5 { 2039 catchsql { 2040 UPDATE tdd08_b SET x=x+1; 2041 } 2042 } {1 {FOREIGN KEY constraint failed}} 2043 do_test without_rowid3-dd08e5.1.6 { 2044 catchsql { 2045 UPDATE tdd08 SET a=a+1; 2046 } 2047 } {1 {FOREIGN KEY constraint failed}} 2048 2049 #------------------------------------------------------------------------- 2050 # Verify that ticket ce7c133ea6cc9ccdc1a60d80441f80b6180f5eba 2051 # fixed. 2052 # 2053 do_test without_rowid3-ce7c13.1.1 { 2054 execsql { 2055 CREATE TABLE tce71(a INTEGER PRIMARY KEY, b) WITHOUT rowid; 2056 CREATE UNIQUE INDEX ice71 ON tce71(a,b); 2057 INSERT INTO tce71 VALUES(100,200); 2058 CREATE TABLE tce72(w, x, y, FOREIGN KEY(x,y) REFERENCES tce71(a,b)); 2059 INSERT INTO tce72 VALUES(300,100,200); 2060 UPDATE tce71 set b = 200 where a = 100; 2061 SELECT * FROM tce71, tce72; 2062 } 2063 } {100 200 300 100 200} 2064 do_test without_rowid3-ce7c13.1.2 { 2065 catchsql { 2066 UPDATE tce71 set b = 201 where a = 100; 2067 } 2068 } {1 {FOREIGN KEY constraint failed}} 2069 do_test without_rowid3-ce7c13.1.3 { 2070 catchsql { 2071 UPDATE tce71 set a = 101 where a = 100; 2072 } 2073 } {1 {FOREIGN KEY constraint failed}} 2074 do_test without_rowid3-ce7c13.1.4 { 2075 execsql { 2076 CREATE TABLE tce73(a INTEGER PRIMARY KEY, b, UNIQUE(a,b)) WITHOUT rowid; 2077 INSERT INTO tce73 VALUES(100,200); 2078 CREATE TABLE tce74(w, x, y, FOREIGN KEY(x,y) REFERENCES tce73(a,b)); 2079 INSERT INTO tce74 VALUES(300,100,200); 2080 UPDATE tce73 set b = 200 where a = 100; 2081 SELECT * FROM tce73, tce74; 2082 } 2083 } {100 200 300 100 200} 2084 do_test without_rowid3-ce7c13.1.5 { 2085 catchsql { 2086 UPDATE tce73 set b = 201 where a = 100; 2087 } 2088 } {1 {FOREIGN KEY constraint failed}} 2089 do_test without_rowid3-ce7c13.1.6 { 2090 catchsql { 2091 UPDATE tce73 set a = 101 where a = 100; 2092 } 2093 } {1 {FOREIGN KEY constraint failed}} 2094 2095 # Confirm that changes() works on WITHOUT ROWID tables that use the 2096 # xfer optimization. 2097 # 2098 db close 2099 sqlite3 db :memory: 2100 do_execsql_test without_rowid3-30.1 { 2101 CREATE TABLE t1(a,b,PRIMARY KEY(a,b)) WITHOUT ROWID; 2102 CREATE TABLE t2(a,b,PRIMARY KEY(a,b)) WITHOUT ROWID; 2103 INSERT INTO t1 VALUES(1,2),(3,4),(5,6); 2104 SELECT changes(); 2105 } {3} 2106 do_execsql_test without_rowid3-30.2 { 2107 INSERT INTO t2 SELECT * FROM t1; 2108 SELECT changes(); 2109 } {3} 2110 2111 finish_test