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 17 set testdir [file dirname $argv0] 18 source $testdir/tester.tcl 19 20 # Create several tables to work with. 21 # 22 wal_set_journal_mode 23 do_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} 32 integrity_check trans-1.0.1 33 do_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} 42 do_test trans-1.9 { 43 sqlite3 altdb test.db 44 execsql {SELECT b FROM one ORDER BY a} altdb 45 } {one two three} 46 do_test trans-1.10 { 47 execsql {SELECT b FROM two ORDER BY a} altdb 48 } {I V X} 49 integrity_check trans-1.11 50 wal_check_journal_mode trans-1.12 51 52 # Basic transactions 53 # 54 do_test trans-2.1 { 55 set v [catch {execsql {BEGIN}} msg] 56 lappend v $msg 57 } {0 {}} 58 do_test trans-2.2 { 59 set v [catch {execsql {END}} msg] 60 lappend v $msg 61 } {0 {}} 62 do_test trans-2.3 { 63 set v [catch {execsql {BEGIN TRANSACTION}} msg] 64 lappend v $msg 65 } {0 {}} 66 do_test trans-2.4 { 67 set v [catch {execsql {COMMIT TRANSACTION}} msg] 68 lappend v $msg 69 } {0 {}} 70 do_test trans-2.5 { 71 set v [catch {execsql {BEGIN TRANSACTION 'foo'}} msg] 72 lappend v $msg 73 } {0 {}} 74 do_test trans-2.6 { 75 set v [catch {execsql {ROLLBACK TRANSACTION 'foo'}} msg] 76 lappend v $msg 77 } {0 {}} 78 do_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} 86 integrity_check trans-2.11 87 wal_check_journal_mode trans-2.12 88 89 # Check the locking behavior 90 # 91 do_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} 98 do_test trans-3.2 { 99 catchsql { 100 SELECT a FROM two ORDER BY a; 101 } altdb 102 } {0 {1 5 10}} 103 104 do_test trans-3.3 { 105 catchsql { 106 SELECT a FROM one ORDER BY a; 107 } altdb 108 } {0 {1 2 3}} 109 do_test trans-3.4 { 110 catchsql { 111 INSERT INTO one VALUES(4,'four'); 112 } 113 } {0 {}} 114 do_test trans-3.5 { 115 catchsql { 116 SELECT a FROM two ORDER BY a; 117 } altdb 118 } {0 {1 5 10}} 119 do_test trans-3.6 { 120 catchsql { 121 SELECT a FROM one ORDER BY a; 122 } altdb 123 } {0 {1 2 3}} 124 do_test trans-3.7 { 125 catchsql { 126 INSERT INTO two VALUES(4,'IV'); 127 } 128 } {0 {}} 129 do_test trans-3.8 { 130 catchsql { 131 SELECT a FROM two ORDER BY a; 132 } altdb 133 } {0 {1 5 10}} 134 do_test trans-3.9 { 135 catchsql { 136 SELECT a FROM one ORDER BY a; 137 } altdb 138 } {0 {1 2 3}} 139 do_test trans-3.10 { 140 execsql {END TRANSACTION} 141 } {} 142 143 do_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}} 149 do_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}} 155 do_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}} 161 do_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}} 167 integrity_check trans-3.15 168 wal_check_journal_mode trans-3.16 169 170 do_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}} 176 do_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}} 182 do_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}} 189 do_test trans-4.4 { 190 catchsql { 191 SELECT a FROM two ORDER BY a; 192 } altdb 193 } {0 {1 4 5 10}} 194 do_test trans-4.5 { 195 catchsql { 196 SELECT a FROM one ORDER BY a; 197 } altdb 198 } {0 {1 2 3 4}} 199 do_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}} 205 do_test trans-4.7 { 206 catchsql { 207 SELECT a FROM two ORDER BY a; 208 } altdb 209 } {0 {1 4 5 10}} 210 do_test trans-4.8 { 211 catchsql { 212 SELECT a FROM one ORDER BY a; 213 } altdb 214 } {0 {1 2 3 4}} 215 do_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}} 222 do_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}} 228 do_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}} 234 integrity_check trans-4.12 235 wal_check_journal_mode trans-4.13 236 wal_check_journal_mode trans-4.14 altdb 237 do_test trans-4.98 { 238 altdb close 239 execsql { 240 DROP TABLE one; 241 DROP TABLE two; 242 } 243 } {} 244 integrity_check trans-4.99 245 246 # Check out the commit/rollback behavior of the database 247 # 248 do_test trans-5.1 { 249 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name} 250 } {} 251 do_test trans-5.2 { 252 execsql {BEGIN TRANSACTION} 253 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name} 254 } {} 255 do_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} 259 do_test trans-5.4 { 260 execsql {SELECT a,b FROM one ORDER BY b} 261 } {} 262 do_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} 266 do_test trans-5.6 { 267 execsql {ROLLBACK} 268 execsql {SELECT name FROM sqlite_master WHERE type='table' ORDER BY name} 269 } {} 270 do_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 # 280 do_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 } {} 287 do_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} 296 do_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} 304 do_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} 312 do_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} 324 do_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} 332 do_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} 341 do_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} 349 do_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} 362 do_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} 370 do_test trans-5.18 { 371 execsql { 372 SELECT * FROM t2; 373 } 374 } {1 2 3} 375 do_test trans-5.19 { 376 execsql { 377 SELECT x FROM t2 WHERE y=2; 378 } 379 } {1} 380 do_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 } {} 390 do_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}} 396 do_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} 404 do_test trans-5.23 { 405 execsql { 406 SELECT * FROM t2; 407 } 408 } {1 2 3} 409 integrity_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 # 415 do_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} 425 do_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 } {} 435 do_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} 441 do_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} 451 do_test trans-6.5 { 452 execsql2 { 453 ROLLBACK; 454 SELECT * FROM t1; 455 } 456 } {p 1 q 2 r 3} 457 do_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} 467 do_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 # 476 do_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} 487 do_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 } {} 496 do_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} 502 do_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} 512 do_test trans-6.14 { 513 execsql2 { 514 ROLLBACK; 515 SELECT * FROM t1; 516 } 517 } {p 1 q 2 r 3} 518 do_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} 528 do_test trans-6.16 { 529 catchsql { 530 COMMIT; 531 SELECT * FROM t1; 532 } 533 } {1 {no such table: t1}} 534 535 do_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} 543 do_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} 549 do_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} 557 do_test trans-6.23 { 558 execsql { 559 SELECT * FROM t1 WHERE b<1; 560 } 561 } {4 -5 -6 1 -2 -3} 562 do_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 571 do_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} 579 do_test trans-6.26 { 580 execsql { 581 SELECT * FROM t1 WHERE c<1; 582 } 583 } {4 -5 -6 1 -2 -3} 584 do_test trans-6.27 { 585 execsql { 586 ROLLBACK; 587 SELECT * FROM t1 WHERE b<1; 588 } 589 } {4 -5 -6 1 -2 -3} 590 do_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 # 600 do_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} 611 do_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} 617 do_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} 625 do_test trans-6.33 { 626 execsql { 627 SELECT * FROM t1 WHERE b<1; 628 } 629 } {4 -5 -6 1 -2 -3} 630 do_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 639 do_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} 647 do_test trans-6.36 { 648 execsql { 649 SELECT * FROM t1 WHERE c<1; 650 } 651 } {4 -5 -6 1 -2 -3} 652 do_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} 658 do_test trans-6.38 { 659 execsql { 660 ROLLBACK; 661 SELECT * FROM t1 WHERE b<1; 662 } 663 } {4 -5 -6 1 -2 -3} 664 do_test trans-6.39 { 665 execsql { 666 SELECT * FROM t1 WHERE c<1; 667 } 668 } {1 -2 -3 4 -5 -6} 669 integrity_check trans-6.40 670 671 # Test to make sure rollback restores the database back to its original 672 # state. 673 # 674 do_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} 689 do_test trans-7.2 { 690 execsql {SELECT md5sum(x,y,z) FROM t2} 691 } $checksum 692 do_test trans-7.2.1 { 693 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master} 694 } $checksum2 695 do_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 703 do_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 711 do_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 719 do_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 727 do_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 736 do_test trans-7.8 { 737 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master} 738 } $checksum2 739 ifcapable 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 } 750 do_test trans-7.10 { 751 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master} 752 } $checksum2 753 ifcapable 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 } 767 do_test trans-7.12 { 768 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master} 769 } $checksum2 770 ifcapable 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 } 780 do_test trans-7.14 { 781 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master} 782 } $checksum2 783 integrity_check trans-7.15 784 wal_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 # 791 set fd [open test.tcl w] 792 puts $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 } 803 close $fd 804 do_test trans-8.1 { 805 catch {exec [info nameofexec] test.tcl} 806 execsql {SELECT md5sum(x,y,z) FROM t2} 807 } $checksum 808 do_test trans-8.2 { 809 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master} 810 } $checksum2 811 integrity_check trans-8.3 812 set fd [open test.tcl w] 813 puts $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 } 825 close $fd 826 do_test trans-8.4 { 827 catch {exec [info nameofexec] test.tcl} 828 execsql {SELECT md5sum(x,y,z) FROM t2} 829 } $checksum 830 do_test trans-8.5 { 831 execsql {SELECT md5sum(type,name,tbl_name,rootpage,sql) FROM sqlite_master} 832 } $checksum2 833 integrity_check trans-8.6 834 wal_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 # 840 do_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} 864 wal_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 # 873 proc 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 # 886 if {[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 # 898 for {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 956 finish_test 957