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