1# 2001 September 15 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. The 12# focus of this script is database locks. 13# 14# $Id: trans.test,v 1.41 2009/04/28 16:37:59 danielk1977 Exp $ 15 16 17set testdir [file dirname $argv0] 18source $testdir/tester.tcl 19 20# Create several tables to work with. 21# 22wal_set_journal_mode 23do_test trans-1.0 { 24 execsql { 25 CREATE TABLE one(a int PRIMARY KEY, b text); 26 INSERT INTO one VALUES(1,'one'); 27 INSERT INTO one VALUES(2,'two'); 28 INSERT INTO one VALUES(3,'three'); 29 SELECT b FROM one ORDER BY a; 30 } 31} {one two three} 32integrity_check trans-1.0.1 33do_test trans-1.1 { 34 execsql { 35 CREATE TABLE two(a int PRIMARY KEY, b text); 36 INSERT INTO two VALUES(1,'I'); 37 INSERT INTO two VALUES(5,'V'); 38 INSERT INTO two VALUES(10,'X'); 39 SELECT b FROM two ORDER BY a; 40 } 41} {I V X} 42do_test trans-1.9 { 43 sqlite3 altdb test.db 44 execsql {SELECT b FROM one ORDER BY a} altdb 45} {one two three} 46do_test trans-1.10 { 47 execsql {SELECT b FROM two ORDER BY a} altdb 48} {I V X} 49integrity_check trans-1.11 50wal_check_journal_mode trans-1.12 51 52# Basic transactions 53# 54do_test trans-2.1 { 55 set v [catch {execsql {BEGIN}} msg] 56 lappend v $msg 57} {0 {}} 58do_test trans-2.2 { 59 set v [catch {execsql {END}} msg] 60 lappend v $msg 61} {0 {}} 62do_test trans-2.3 { 63 set v [catch {execsql {BEGIN TRANSACTION}} msg] 64 lappend v $msg 65} {0 {}} 66do_test trans-2.4 { 67 set v [catch {execsql {COMMIT TRANSACTION}} msg] 68 lappend v $msg 69} {0 {}} 70do_test trans-2.5 { 71 set v [catch {execsql {BEGIN TRANSACTION 'foo'}} msg] 72 lappend v $msg 73} {0 {}} 74do_test trans-2.6 { 75 set v [catch {execsql {ROLLBACK TRANSACTION 'foo'}} msg] 76 lappend v $msg 77} {0 {}} 78do_test trans-2.10 { 79 execsql { 80 BEGIN; 81 SELECT a FROM one ORDER BY a; 82 SELECT a FROM two ORDER BY a; 83 END; 84 } 85} {1 2 3 1 5 10} 86integrity_check trans-2.11 87wal_check_journal_mode trans-2.12 88 89# Check the locking behavior 90# 91do_test trans-3.1 { 92 execsql { 93 BEGIN; 94 UPDATE one SET a = 0 WHERE 0; 95 SELECT a FROM one ORDER BY a; 96 } 97} {1 2 3} 98do_test trans-3.2 { 99 catchsql { 100 SELECT a FROM two ORDER BY a; 101 } altdb 102} {0 {1 5 10}} 103 104do_test trans-3.3 { 105 catchsql { 106 SELECT a FROM one ORDER BY a; 107 } altdb 108} {0 {1 2 3}} 109do_test trans-3.4 { 110 catchsql { 111 INSERT INTO one VALUES(4,'four'); 112 } 113} {0 {}} 114do_test trans-3.5 { 115 catchsql { 116 SELECT a FROM two ORDER BY a; 117 } altdb 118} {0 {1 5 10}} 119do_test trans-3.6 { 120 catchsql { 121 SELECT a FROM one ORDER BY a; 122 } altdb 123} {0 {1 2 3}} 124do_test trans-3.7 { 125 catchsql { 126 INSERT INTO two VALUES(4,'IV'); 127 } 128} {0 {}} 129do_test trans-3.8 { 130 catchsql { 131 SELECT a FROM two ORDER BY a; 132 } altdb 133} {0 {1 5 10}} 134do_test trans-3.9 { 135 catchsql { 136 SELECT a FROM one ORDER BY a; 137 } altdb 138} {0 {1 2 3}} 139do_test trans-3.10 { 140 execsql {END TRANSACTION} 141} {} 142 143do_test trans-3.11 { 144 set v [catch {execsql { 145 SELECT a FROM two ORDER BY a; 146 } altdb} msg] 147 lappend v $msg 148} {0 {1 4 5 10}} 149do_test trans-3.12 { 150 set v [catch {execsql { 151 SELECT a FROM one ORDER BY a; 152 } altdb} msg] 153 lappend v $msg 154} {0 {1 2 3 4}} 155do_test trans-3.13 { 156 set v [catch {execsql { 157 SELECT a FROM two ORDER BY a; 158 } db} msg] 159 lappend v $msg 160} {0 {1 4 5 10}} 161do_test trans-3.14 { 162 set v [catch {execsql { 163 SELECT a FROM one ORDER BY a; 164 } db} msg] 165 lappend v $msg 166} {0 {1 2 3 4}} 167integrity_check trans-3.15 168wal_check_journal_mode trans-3.16 169 170do_test trans-4.1 { 171 set v [catch {execsql { 172 COMMIT; 173 } db} msg] 174 lappend v $msg 175} {1 {cannot commit - no transaction is active}} 176do_test trans-4.2 { 177 set v [catch {execsql { 178 ROLLBACK; 179 } db} msg] 180 lappend v $msg 181} {1 {cannot rollback - no transaction is active}} 182do_test trans-4.3 { 183 catchsql { 184 BEGIN TRANSACTION; 185 UPDATE two SET a = 0 WHERE 0; 186 SELECT a FROM two ORDER BY a; 187 } db 188} {0 {1 4 5 10}} 189do_test trans-4.4 { 190 catchsql { 191 SELECT a FROM two ORDER BY a; 192 } altdb 193} {0 {1 4 5 10}} 194do_test trans-4.5 { 195 catchsql { 196 SELECT a FROM one ORDER BY a; 197 } altdb 198} {0 {1 2 3 4}} 199do_test trans-4.6 { 200 catchsql { 201 BEGIN TRANSACTION; 202 SELECT a FROM one ORDER BY a; 203 } db 204} {1 {cannot start a transaction within a transaction}} 205do_test trans-4.7 { 206 catchsql { 207 SELECT a FROM two ORDER BY a; 208 } altdb 209} {0 {1 4 5 10}} 210do_test trans-4.8 { 211 catchsql { 212 SELECT a FROM one ORDER BY a; 213 } altdb 214} {0 {1 2 3 4}} 215do_test trans-4.9 { 216 set v [catch {execsql { 217 END TRANSACTION; 218 SELECT a FROM two ORDER BY a; 219 } db} msg] 220 lappend v $msg 221} {0 {1 4 5 10}} 222do_test trans-4.10 { 223 set v [catch {execsql { 224 SELECT a FROM two ORDER BY a; 225 } altdb} msg] 226 lappend v $msg 227} {0 {1 4 5 10}} 228do_test trans-4.11 { 229 set v [catch {execsql { 230 SELECT a FROM one ORDER BY a; 231 } altdb} msg] 232 lappend v $msg 233} {0 {1 2 3 4}} 234integrity_check trans-4.12 235wal_check_journal_mode trans-4.13 236wal_check_journal_mode trans-4.14 altdb 237do_test trans-4.98 { 238 altdb close 239 execsql { 240 DROP TABLE one; 241 DROP TABLE two; 242 } 243} {} 244integrity_check trans-4.99 245 246# Check out the commit/rollback behavior of the database 247# 248do_test trans-5.1 { 249 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name} 250} {} 251do_test trans-5.2 { 252 execsql {BEGIN TRANSACTION} 253 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name} 254} {} 255do_test trans-5.3 { 256 execsql {CREATE TABLE one(a text, b int)} 257 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name} 258} {one} 259do_test trans-5.4 { 260 execsql {SELECT a,b FROM one ORDER BY b} 261} {} 262do_test trans-5.5 { 263 execsql {INSERT INTO one(a,b) VALUES('hello', 1)} 264 execsql {SELECT a,b FROM one ORDER BY b} 265} {hello 1} 266do_test trans-5.6 { 267 execsql {ROLLBACK} 268 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name} 269} {} 270do_test trans-5.7 { 271 set v [catch { 272 execsql {SELECT a,b FROM one ORDER BY b} 273 } msg] 274 lappend v $msg 275} {1 {no such table: one}} 276 277# Test commits and rollbacks of table CREATE TABLEs, CREATE INDEXs 278# DROP TABLEs and DROP INDEXs 279# 280do_test trans-5.8 { 281 execsql { 282 SELECT name fROM sqlite_master 283 WHERE type='table' OR type='index' 284 ORDER BY name 285 } 286} {} 287do_test trans-5.9 { 288 execsql { 289 BEGIN TRANSACTION; 290 CREATE TABLE t1(a int, b int, c int); 291 SELECT name fROM sqlite_master 292 WHERE type='table' OR type='index' 293 ORDER BY name; 294 } 295} {t1} 296do_test trans-5.10 { 297 execsql { 298 CREATE INDEX i1 ON t1(a); 299 SELECT name fROM sqlite_master 300 WHERE type='table' OR type='index' 301 ORDER BY name; 302 } 303} {i1 t1} 304do_test trans-5.11 { 305 execsql { 306 COMMIT; 307 SELECT name fROM sqlite_master 308 WHERE type='table' OR type='index' 309 ORDER BY name; 310 } 311} {i1 t1} 312do_test trans-5.12 { 313 execsql { 314 BEGIN TRANSACTION; 315 CREATE TABLE t2(a int, b int, c int); 316 CREATE INDEX i2a ON t2(a); 317 CREATE INDEX i2b ON t2(b); 318 DROP TABLE t1; 319 SELECT name fROM sqlite_master 320 WHERE type='table' OR type='index' 321 ORDER BY name; 322 } 323} {i2a i2b t2} 324do_test trans-5.13 { 325 execsql { 326 ROLLBACK; 327 SELECT name fROM sqlite_master 328 WHERE type='table' OR type='index' 329 ORDER BY name; 330 } 331} {i1 t1} 332do_test trans-5.14 { 333 execsql { 334 BEGIN TRANSACTION; 335 DROP INDEX i1; 336 SELECT name fROM sqlite_master 337 WHERE type='table' OR type='index' 338 ORDER BY name; 339 } 340} {t1} 341do_test trans-5.15 { 342 execsql { 343 ROLLBACK; 344 SELECT name fROM sqlite_master 345 WHERE type='table' OR type='index' 346 ORDER BY name; 347 } 348} {i1 t1} 349do_test trans-5.16 { 350 execsql { 351 BEGIN TRANSACTION; 352 DROP INDEX i1; 353 CREATE TABLE t2(x int, y int, z int); 354 CREATE INDEX i2x ON t2(x); 355 CREATE INDEX i2y ON t2(y); 356 INSERT INTO t2 VALUES(1,2,3); 357 SELECT name fROM sqlite_master 358 WHERE type='table' OR type='index' 359 ORDER BY name; 360 } 361} {i2x i2y t1 t2} 362do_test trans-5.17 { 363 execsql { 364 COMMIT; 365 SELECT name fROM sqlite_master 366 WHERE type='table' OR type='index' 367 ORDER BY name; 368 } 369} {i2x i2y t1 t2} 370do_test trans-5.18 { 371 execsql { 372 SELECT * FROM t2; 373 } 374} {1 2 3} 375do_test trans-5.19 { 376 execsql { 377 SELECT x FROM t2 WHERE y=2; 378 } 379} {1} 380do_test trans-5.20 { 381 execsql { 382 BEGIN TRANSACTION; 383 DROP TABLE t1; 384 DROP TABLE t2; 385 SELECT name fROM sqlite_master 386 WHERE type='table' OR type='index' 387 ORDER BY name; 388 } 389} {} 390do_test trans-5.21 { 391 set r [catch {execsql { 392 SELECT * FROM t2 393 }} msg] 394 lappend r $msg 395} {1 {no such table: t2}} 396do_test trans-5.22 { 397 execsql { 398 ROLLBACK; 399 SELECT name fROM sqlite_master 400 WHERE type='table' OR type='index' 401 ORDER BY name; 402 } 403} {i2x i2y t1 t2} 404do_test trans-5.23 { 405 execsql { 406 SELECT * FROM t2; 407 } 408} {1 2 3} 409integrity_check trans-5.23 410 411 412# Try to DROP and CREATE tables and indices with the same name 413# within a transaction. Make sure ROLLBACK works. 414# 415do_test trans-6.1 { 416 execsql2 { 417 INSERT INTO t1 VALUES(1,2,3); 418 BEGIN TRANSACTION; 419 DROP TABLE t1; 420 CREATE TABLE t1(p,q,r); 421 ROLLBACK; 422 SELECT * FROM t1; 423 } 424} {a 1 b 2 c 3} 425do_test trans-6.2 { 426 execsql2 { 427 INSERT INTO t1 VALUES(1,2,3); 428 BEGIN TRANSACTION; 429 DROP TABLE t1; 430 CREATE TABLE t1(p,q,r); 431 COMMIT; 432 SELECT * FROM t1; 433 } 434} {} 435do_test trans-6.3 { 436 execsql2 { 437 INSERT INTO t1 VALUES(1,2,3); 438 SELECT * FROM t1; 439 } 440} {p 1 q 2 r 3} 441do_test trans-6.4 { 442 execsql2 { 443 BEGIN TRANSACTION; 444 DROP TABLE t1; 445 CREATE TABLE t1(a,b,c); 446 INSERT INTO t1 VALUES(4,5,6); 447 SELECT * FROM t1; 448 DROP TABLE t1; 449 } 450} {a 4 b 5 c 6} 451do_test trans-6.5 { 452 execsql2 { 453 ROLLBACK; 454 SELECT * FROM t1; 455 } 456} {p 1 q 2 r 3} 457do_test trans-6.6 { 458 execsql2 { 459 BEGIN TRANSACTION; 460 DROP TABLE t1; 461 CREATE TABLE t1(a,b,c); 462 INSERT INTO t1 VALUES(4,5,6); 463 SELECT * FROM t1; 464 DROP TABLE t1; 465 } 466} {a 4 b 5 c 6} 467do_test trans-6.7 { 468 catchsql { 469 COMMIT; 470 SELECT * FROM t1; 471 } 472} {1 {no such table: t1}} 473 474# Repeat on a table with an automatically generated index. 475# 476do_test trans-6.10 { 477 execsql2 { 478 CREATE TABLE t1(a unique,b,c); 479 INSERT INTO t1 VALUES(1,2,3); 480 BEGIN TRANSACTION; 481 DROP TABLE t1; 482 CREATE TABLE t1(p unique,q,r); 483 ROLLBACK; 484 SELECT * FROM t1; 485 } 486} {a 1 b 2 c 3} 487do_test trans-6.11 { 488 execsql2 { 489 BEGIN TRANSACTION; 490 DROP TABLE t1; 491 CREATE TABLE t1(p unique,q,r); 492 COMMIT; 493 SELECT * FROM t1; 494 } 495} {} 496do_test trans-6.12 { 497 execsql2 { 498 INSERT INTO t1 VALUES(1,2,3); 499 SELECT * FROM t1; 500 } 501} {p 1 q 2 r 3} 502do_test trans-6.13 { 503 execsql2 { 504 BEGIN TRANSACTION; 505 DROP TABLE t1; 506 CREATE TABLE t1(a unique,b,c); 507 INSERT INTO t1 VALUES(4,5,6); 508 SELECT * FROM t1; 509 DROP TABLE t1; 510 } 511} {a 4 b 5 c 6} 512do_test trans-6.14 { 513 execsql2 { 514 ROLLBACK; 515 SELECT * FROM t1; 516 } 517} {p 1 q 2 r 3} 518do_test trans-6.15 { 519 execsql2 { 520 BEGIN TRANSACTION; 521 DROP TABLE t1; 522 CREATE TABLE t1(a unique,b,c); 523 INSERT INTO t1 VALUES(4,5,6); 524 SELECT * FROM t1; 525 DROP TABLE t1; 526 } 527} {a 4 b 5 c 6} 528do_test trans-6.16 { 529 catchsql { 530 COMMIT; 531 SELECT * FROM t1; 532 } 533} {1 {no such table: t1}} 534 535do_test trans-6.20 { 536 execsql { 537 CREATE TABLE t1(a integer primary key,b,c); 538 INSERT INTO t1 VALUES(1,-2,-3); 539 INSERT INTO t1 VALUES(4,-5,-6); 540 SELECT * FROM t1; 541 } 542} {1 -2 -3 4 -5 -6} 543do_test trans-6.21 { 544 execsql { 545 CREATE INDEX i1 ON t1(b); 546 SELECT * FROM t1 WHERE b<1; 547 } 548} {4 -5 -6 1 -2 -3} 549do_test trans-6.22 { 550 execsql { 551 BEGIN TRANSACTION; 552 DROP INDEX i1; 553 SELECT * FROM t1 WHERE b<1; 554 ROLLBACK; 555 } 556} {1 -2 -3 4 -5 -6} 557do_test trans-6.23 { 558 execsql { 559 SELECT * FROM t1 WHERE b<1; 560 } 561} {4 -5 -6 1 -2 -3} 562do_test trans-6.24 { 563 execsql { 564 BEGIN TRANSACTION; 565 DROP TABLE t1; 566 ROLLBACK; 567 SELECT * FROM t1 WHERE b<1; 568 } 569} {4 -5 -6 1 -2 -3} 570 571do_test trans-6.25 { 572 execsql { 573 BEGIN TRANSACTION; 574 DROP INDEX i1; 575 CREATE INDEX i1 ON t1(c); 576 SELECT * FROM t1 WHERE b<1; 577 } 578} {1 -2 -3 4 -5 -6} 579do_test trans-6.26 { 580 execsql { 581 SELECT * FROM t1 WHERE c<1; 582 } 583} {4 -5 -6 1 -2 -3} 584do_test trans-6.27 { 585 execsql { 586 ROLLBACK; 587 SELECT * FROM t1 WHERE b<1; 588 } 589} {4 -5 -6 1 -2 -3} 590do_test trans-6.28 { 591 execsql { 592 SELECT * FROM t1 WHERE c<1; 593 } 594} {1 -2 -3 4 -5 -6} 595 596# The following repeats steps 6.20 through 6.28, but puts a "unique" 597# constraint the first field of the table in order to generate an 598# automatic index. 599# 600do_test trans-6.30 { 601 execsql { 602 BEGIN TRANSACTION; 603 DROP TABLE t1; 604 CREATE TABLE t1(a int unique,b,c); 605 COMMIT; 606 INSERT INTO t1 VALUES(1,-2,-3); 607 INSERT INTO t1 VALUES(4,-5,-6); 608 SELECT * FROM t1 ORDER BY a; 609 } 610} {1 -2 -3 4 -5 -6} 611do_test trans-6.31 { 612 execsql { 613 CREATE INDEX i1 ON t1(b); 614 SELECT * FROM t1 WHERE b<1; 615 } 616} {4 -5 -6 1 -2 -3} 617do_test trans-6.32 { 618 execsql { 619 BEGIN TRANSACTION; 620 DROP INDEX i1; 621 SELECT * FROM t1 WHERE b<1; 622 ROLLBACK; 623 } 624} {1 -2 -3 4 -5 -6} 625do_test trans-6.33 { 626 execsql { 627 SELECT * FROM t1 WHERE b<1; 628 } 629} {4 -5 -6 1 -2 -3} 630do_test trans-6.34 { 631 execsql { 632 BEGIN TRANSACTION; 633 DROP TABLE t1; 634 ROLLBACK; 635 SELECT * FROM t1 WHERE b<1; 636 } 637} {4 -5 -6 1 -2 -3} 638 639do_test trans-6.35 { 640 execsql { 641 BEGIN TRANSACTION; 642 DROP INDEX i1; 643 CREATE INDEX i1 ON t1(c); 644 SELECT * FROM t1 WHERE b<1; 645 } 646} {1 -2 -3 4 -5 -6} 647do_test trans-6.36 { 648 execsql { 649 SELECT * FROM t1 WHERE c<1; 650 } 651} {4 -5 -6 1 -2 -3} 652do_test trans-6.37 { 653 execsql { 654 DROP INDEX i1; 655 SELECT * FROM t1 WHERE c<1; 656 } 657} {1 -2 -3 4 -5 -6} 658do_test trans-6.38 { 659 execsql { 660 ROLLBACK; 661 SELECT * FROM t1 WHERE b<1; 662 } 663} {4 -5 -6 1 -2 -3} 664do_test trans-6.39 { 665 execsql { 666 SELECT * FROM t1 WHERE c<1; 667 } 668} {1 -2 -3 4 -5 -6} 669integrity_check trans-6.40 670 671# Test to make sure rollback restores the database back to its original 672# state. 673# 674do_test trans-7.1 { 675 execsql {BEGIN} 676 for {set i 0} {$i<1000} {incr i} { 677 set r1 [expr {rand()}] 678 set r2 [expr {rand()}] 679 set r3 [expr {rand()}] 680 execsql "INSERT INTO t2 VALUES($r1,$r2,$r3)" 681 } 682 execsql {COMMIT} 683 set ::checksum [execsql {SELECT md5sum(x,y,z) FROM t2}] 684 set ::checksum2 [ 685 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master} 686 ] 687 execsql {SELECT count(*) FROM t2} 688} {1001} 689do_test trans-7.2 { 690 execsql {SELECT md5sum(x,y,z) FROM t2} 691} $checksum 692do_test trans-7.2.1 { 693 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master} 694} $checksum2 695do_test trans-7.3 { 696 execsql { 697 BEGIN; 698 DELETE FROM t2; 699 ROLLBACK; 700 SELECT md5sum(x,y,z) FROM t2; 701 } 702} $checksum 703do_test trans-7.4 { 704 execsql { 705 BEGIN; 706 INSERT INTO t2 SELECT * FROM t2; 707 ROLLBACK; 708 SELECT md5sum(x,y,z) FROM t2; 709 } 710} $checksum 711do_test trans-7.5 { 712 execsql { 713 BEGIN; 714 DELETE FROM t2; 715 ROLLBACK; 716 SELECT md5sum(x,y,z) FROM t2; 717 } 718} $checksum 719do_test trans-7.6 { 720 execsql { 721 BEGIN; 722 INSERT INTO t2 SELECT * FROM t2; 723 ROLLBACK; 724 SELECT md5sum(x,y,z) FROM t2; 725 } 726} $checksum 727do_test trans-7.7 { 728 execsql { 729 BEGIN; 730 CREATE TABLE t3 AS SELECT * FROM t2; 731 INSERT INTO t2 SELECT * FROM t3; 732 ROLLBACK; 733 SELECT md5sum(x,y,z) FROM t2; 734 } 735} $checksum 736do_test trans-7.8 { 737 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master} 738} $checksum2 739ifcapable tempdb { 740 do_test trans-7.9 { 741 execsql { 742 BEGIN; 743 CREATE TEMP TABLE t3 AS SELECT * FROM t2; 744 INSERT INTO t2 SELECT * FROM t3; 745 ROLLBACK; 746 SELECT md5sum(x,y,z) FROM t2; 747 } 748 } $checksum 749} 750do_test trans-7.10 { 751 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master} 752} $checksum2 753ifcapable tempdb { 754 do_test trans-7.11 { 755 execsql { 756 BEGIN; 757 CREATE TEMP TABLE t3 AS SELECT * FROM t2; 758 INSERT INTO t2 SELECT * FROM t3; 759 DROP INDEX i2x; 760 DROP INDEX i2y; 761 CREATE INDEX i3a ON t3(x); 762 ROLLBACK; 763 SELECT md5sum(x,y,z) FROM t2; 764 } 765 } $checksum 766} 767do_test trans-7.12 { 768 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master} 769} $checksum2 770ifcapable tempdb { 771 do_test trans-7.13 { 772 execsql { 773 BEGIN; 774 DROP TABLE t2; 775 ROLLBACK; 776 SELECT md5sum(x,y,z) FROM t2; 777 } 778 } $checksum 779} 780do_test trans-7.14 { 781 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master} 782} $checksum2 783integrity_check trans-7.15 784wal_check_journal_mode trans-7.16 785 786# Arrange for another process to begin modifying the database but abort 787# and die in the middle of the modification. Then have this process read 788# the database. This process should detect the journal file and roll it 789# back. Verify that this happens correctly. 790# 791set fd [open test.tcl w] 792puts $fd { 793 sqlite3_test_control_pending_byte 0x0010000 794 sqlite3 db test.db 795 db eval { 796 PRAGMA default_cache_size=20; 797 BEGIN; 798 CREATE TABLE t3 AS SELECT * FROM t2; 799 DELETE FROM t2; 800 } 801 sqlite_abort 802} 803close $fd 804do_test trans-8.1 { 805 catch {exec [info nameofexec] test.tcl} 806 execsql {SELECT md5sum(x,y,z) FROM t2} 807} $checksum 808do_test trans-8.2 { 809 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master} 810} $checksum2 811integrity_check trans-8.3 812set fd [open test.tcl w] 813puts $fd { 814 sqlite3_test_control_pending_byte 0x0010000 815 sqlite3 db test.db 816 db eval { 817 PRAGMA journal_mode=persist; 818 PRAGMA default_cache_size=20; 819 BEGIN; 820 CREATE TABLE t3 AS SELECT * FROM t2; 821 DELETE FROM t2; 822 } 823 sqlite_abort 824} 825close $fd 826do_test trans-8.4 { 827 catch {exec [info nameofexec] test.tcl} 828 execsql {SELECT md5sum(x,y,z) FROM t2} 829} $checksum 830do_test trans-8.5 { 831 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master} 832} $checksum2 833integrity_check trans-8.6 834wal_check_journal_mode trans-8.7 835 836# In the following sequence of tests, compute the MD5 sum of the content 837# of a table, make lots of modifications to that table, then do a rollback. 838# Verify that after the rollback, the MD5 checksum is unchanged. 839# 840do_test trans-9.1 { 841 execsql { 842 PRAGMA default_cache_size=10; 843 } 844 db close 845 sqlite3 db test.db 846 execsql { 847 BEGIN; 848 CREATE TABLE t3(x TEXT); 849 INSERT INTO t3 VALUES(randstr(10,400)); 850 INSERT INTO t3 VALUES(randstr(10,400)); 851 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 852 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 853 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 854 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 855 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 856 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 857 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 858 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 859 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 860 COMMIT; 861 SELECT count(*) FROM t3; 862 } 863} {1024} 864wal_check_journal_mode trans-9.1.1 865 866# The following procedure computes a "signature" for table "t3". If 867# T3 changes in any way, the signature should change. 868# 869# This is used to test ROLLBACK. We gather a signature for t3, then 870# make lots of changes to t3, then rollback and take another signature. 871# The two signatures should be the same. 872# 873proc signature {} { 874 return [db eval {SELECT count(*), md5sum(x) FROM t3}] 875} 876 877# Repeat the following group of tests 20 times for quick testing and 878# 40 times for full testing. Each iteration of the test makes table 879# t3 a little larger, and thus takes a little longer, so doing 40 tests 880# is more than 2.0 times slower than doing 20 tests. Considerably more. 881# 882# Also, if temporary tables are stored in memory and the test pcache 883# is in use, only 20 iterations. Otherwise the test pcache runs out 884# of page slots and SQLite reports "out of memory". 885# 886if {[info exists G(isquick)] || ( 887 $TEMP_STORE==3 && [regexp {^pcache[[:digit:]]*$} [permutation]] 888) } { 889 set limit 20 890} elseif {[info exists G(issoak)]} { 891 set limit 100 892} else { 893 set limit 40 894} 895 896# Do rollbacks. Make sure the signature does not change. 897# 898for {set i 2} {$i<=$limit} {incr i} { 899 set ::sig [signature] 900 set cnt [lindex $::sig 0] 901 if {$i%2==0} { 902 execsql {PRAGMA fullfsync=ON} 903 } else { 904 execsql {PRAGMA fullfsync=OFF} 905 } 906 set sqlite_sync_count 0 907 set sqlite_fullsync_count 0 908 do_test trans-9.$i.1-$cnt { 909 execsql { 910 BEGIN; 911 DELETE FROM t3 WHERE random()%10!=0; 912 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; 913 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; 914 ROLLBACK; 915 } 916 signature 917 } $sig 918 do_test trans-9.$i.2-$cnt { 919 execsql { 920 BEGIN; 921 DELETE FROM t3 WHERE random()%10!=0; 922 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; 923 DELETE FROM t3 WHERE random()%10!=0; 924 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; 925 ROLLBACK; 926 } 927 signature 928 } $sig 929 if {$i<$limit} { 930 do_test trans-9.$i.3-$cnt { 931 execsql { 932 INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE random()%10==0; 933 } 934 } {} 935 catch flush_async_queue 936 if {$tcl_platform(platform)=="unix"} { 937 do_test trans-9.$i.4-$cnt { 938 expr {$sqlite_sync_count>0} 939 } 1 940 ifcapable pager_pragmas { 941 do_test trans-9.$i.5-$cnt { 942 expr {$sqlite_fullsync_count>0} 943 } [expr {$i%2==0}] 944 } else { 945 do_test trans-9.$i.5-$cnt { 946 expr {$sqlite_fullsync_count==0} 947 } {1} 948 } 949 } 950 } 951 952 wal_check_journal_mode trans-9.$i.6-$cnt 953 set ::pager_old_format 0 954} 955 956finish_test 957