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