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