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