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