112dd5496Sdanielk1977# 2008 December 15 212dd5496Sdanielk1977# 312dd5496Sdanielk1977# The author disclaims copyright to this source code. In place of 412dd5496Sdanielk1977# a legal notice, here is a blessing: 512dd5496Sdanielk1977# 612dd5496Sdanielk1977# May you do good and not evil. 712dd5496Sdanielk1977# May you find forgiveness for yourself and forgive others. 812dd5496Sdanielk1977# May you share freely, never taking more than you give. 912dd5496Sdanielk1977# 1012dd5496Sdanielk1977#*********************************************************************** 1112dd5496Sdanielk1977# 12dda70fe3Sdrh# $Id: savepoint2.test,v 1.5 2009/06/05 17:09:12 drh Exp $ 1312dd5496Sdanielk1977 1412dd5496Sdanielk1977set testdir [file dirname $argv0] 1512dd5496Sdanielk1977source $testdir/tester.tcl 1612dd5496Sdanielk1977 17*71cb518fSdan 1812dd5496Sdanielk1977# Tests in this file are quite similar to those run by trans.test and 1912dd5496Sdanielk1977# avtrans.test. 2012dd5496Sdanielk1977# 2112dd5496Sdanielk1977 2212dd5496Sdanielk1977proc signature {} { 2312dd5496Sdanielk1977 return [db eval {SELECT count(*), md5sum(x) FROM t3}] 2412dd5496Sdanielk1977} 2512dd5496Sdanielk1977 2612dd5496Sdanielk1977do_test savepoint2-1 { 27*71cb518fSdan wal_set_journal_mode 2812dd5496Sdanielk1977 execsql { 2912dd5496Sdanielk1977 PRAGMA cache_size=10; 3012dd5496Sdanielk1977 BEGIN; 3112dd5496Sdanielk1977 CREATE TABLE t3(x TEXT); 3212dd5496Sdanielk1977 INSERT INTO t3 VALUES(randstr(10,400)); 3312dd5496Sdanielk1977 INSERT INTO t3 VALUES(randstr(10,400)); 3412dd5496Sdanielk1977 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 3512dd5496Sdanielk1977 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 3612dd5496Sdanielk1977 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 3712dd5496Sdanielk1977 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 3812dd5496Sdanielk1977 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 3912dd5496Sdanielk1977 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 4012dd5496Sdanielk1977 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 4112dd5496Sdanielk1977 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 4212dd5496Sdanielk1977 INSERT INTO t3 SELECT randstr(10,400) FROM t3; 4312dd5496Sdanielk1977 COMMIT; 4412dd5496Sdanielk1977 SELECT count(*) FROM t3; 4512dd5496Sdanielk1977 } 4612dd5496Sdanielk1977} {1024} 47*71cb518fSdanwal_check_journal_mode savepoint2-1.1 4812dd5496Sdanielk1977 4912dd5496Sdanielk1977unset -nocomplain ::sig 5012dd5496Sdanielk1977unset -nocomplain SQL 5112dd5496Sdanielk1977 5212dd5496Sdanielk1977set iterations 20 5312dd5496Sdanielk1977 5412dd5496Sdanielk1977set SQL(1) { 5512dd5496Sdanielk1977 DELETE FROM t3 WHERE random()%10!=0; 5612dd5496Sdanielk1977 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; 5712dd5496Sdanielk1977 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; 5812dd5496Sdanielk1977} 5912dd5496Sdanielk1977set SQL(2) { 6012dd5496Sdanielk1977 DELETE FROM t3 WHERE random()%10!=0; 6112dd5496Sdanielk1977 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; 6212dd5496Sdanielk1977 DELETE FROM t3 WHERE random()%10!=0; 6312dd5496Sdanielk1977 INSERT INTO t3 SELECT randstr(10,10)||x FROM t3; 6412dd5496Sdanielk1977} 6512dd5496Sdanielk1977set SQL(3) { 6612dd5496Sdanielk1977 UPDATE t3 SET x = randstr(10, 400) WHERE random()%10; 6712dd5496Sdanielk1977 INSERT INTO t3 SELECT x FROM t3 WHERE random()%10; 6812dd5496Sdanielk1977 DELETE FROM t3 WHERE random()%10; 6912dd5496Sdanielk1977} 7012dd5496Sdanielk1977set SQL(4) { 7112dd5496Sdanielk1977 INSERT INTO t3 SELECT randstr(10,400) FROM t3 WHERE (random()%10 == 0); 7212dd5496Sdanielk1977} 7312dd5496Sdanielk1977 7412dd5496Sdanielk1977 7512dd5496Sdanielk1977 7612dd5496Sdanielk1977for {set ii 2} {$ii < ($iterations+2)} {incr ii} { 7712dd5496Sdanielk1977 7812dd5496Sdanielk1977 # Record the database signature. Optionally (every second run) open a 7912dd5496Sdanielk1977 # transaction. In all cases open savepoint "one", which may or may 8012dd5496Sdanielk1977 # not be a transaction savepoint, depending on whether or not a real 8112dd5496Sdanielk1977 # transaction has been opened. 8212dd5496Sdanielk1977 # 8312dd5496Sdanielk1977 do_test savepoint2-$ii.1 { 8412dd5496Sdanielk1977 if {$ii % 2} { execsql BEGIN } 8512dd5496Sdanielk1977 set ::sig(one) [signature] 8612dd5496Sdanielk1977 execsql "SAVEPOINT one" 8712dd5496Sdanielk1977 } {} 8812dd5496Sdanielk1977 8912dd5496Sdanielk1977 # Execute some SQL on the database. Then rollback to savepoint "one". 9012dd5496Sdanielk1977 # Check that the database signature is as it was when "one" was opened. 9112dd5496Sdanielk1977 # 9212dd5496Sdanielk1977 do_test savepoint2-$ii.2 { 9312dd5496Sdanielk1977 execsql $SQL(1) 9412dd5496Sdanielk1977 execsql "ROLLBACK to one" 9512dd5496Sdanielk1977 signature 9612dd5496Sdanielk1977 } $::sig(one) 9712dd5496Sdanielk1977 integrity_check savepoint2-$ii.2.1 9812dd5496Sdanielk1977 9912dd5496Sdanielk1977 # Execute some SQL. Then open savepoint "two". Savepoint "two" is therefore 10012dd5496Sdanielk1977 # nested in savepoint "one". 10112dd5496Sdanielk1977 # 10212dd5496Sdanielk1977 do_test savepoint2-$ii.3 { 10312dd5496Sdanielk1977 execsql $SQL(1) 10412dd5496Sdanielk1977 set ::sig(two) [signature] 10512dd5496Sdanielk1977 execsql "SAVEPOINT two" 10612dd5496Sdanielk1977 } {} 10712dd5496Sdanielk1977 10812dd5496Sdanielk1977 # More SQL changes. The rollback to savepoint "two". Check that the 10912dd5496Sdanielk1977 # signature is as it was when savepoint "two" was opened. 11012dd5496Sdanielk1977 # 11112dd5496Sdanielk1977 do_test savepoint2-$ii.4 { 11212dd5496Sdanielk1977 execsql $SQL(2) 11312dd5496Sdanielk1977 execsql "ROLLBACK to two" 11412dd5496Sdanielk1977 signature 11512dd5496Sdanielk1977 } $::sig(two) 11612dd5496Sdanielk1977 integrity_check savepoint2-$ii.4.1 11712dd5496Sdanielk1977 11812dd5496Sdanielk1977 # More SQL changes. The rollback to savepoint "two". Check that the 11912dd5496Sdanielk1977 # signature is as it was when savepoint "two" was opened. 12012dd5496Sdanielk1977 # 12112dd5496Sdanielk1977 do_test savepoint2-$ii.5 { 12212dd5496Sdanielk1977 execsql $SQL(2) 12312dd5496Sdanielk1977 execsql "SAVEPOINT three" 12412dd5496Sdanielk1977 execsql $SQL(3) 12512dd5496Sdanielk1977 execsql "RELEASE three" 12612dd5496Sdanielk1977 execsql "ROLLBACK to one" 12712dd5496Sdanielk1977 signature 12812dd5496Sdanielk1977 } $::sig(one) 12912dd5496Sdanielk1977 13012dd5496Sdanielk1977 # By this point the database is in the same state as it was at the 13112dd5496Sdanielk1977 # top of the for{} loop (everything having been rolled back by the 13212dd5496Sdanielk1977 # "ROLLBACK TO one" command above). So make a few changes to the 13312dd5496Sdanielk1977 # database and COMMIT the open transaction, so that the next iteration 13412dd5496Sdanielk1977 # of the for{} loop works on a different dataset. 13512dd5496Sdanielk1977 # 13612dd5496Sdanielk1977 # The transaction being committed here may have been opened normally using 13712dd5496Sdanielk1977 # "BEGIN", or may have been opened using a transaction savepoint created 13812dd5496Sdanielk1977 # by the "SAVEPOINT one" statement. 13912dd5496Sdanielk1977 # 14012dd5496Sdanielk1977 do_test savepoint2-$ii.6 { 14112dd5496Sdanielk1977 execsql $SQL(4) 14212dd5496Sdanielk1977 execsql COMMIT 14312dd5496Sdanielk1977 sqlite3_get_autocommit db 14412dd5496Sdanielk1977 } {1} 14512dd5496Sdanielk1977 integrity_check savepoint2-$ii.6.1 146*71cb518fSdan 147*71cb518fSdan # Check that the connection is still running in WAL mode. 148*71cb518fSdan wal_check_journal_mode savepoint2-$ii.7 14912dd5496Sdanielk1977} 15012dd5496Sdanielk1977 15112dd5496Sdanielk1977unset -nocomplain ::sig 15212dd5496Sdanielk1977unset -nocomplain SQL 15312dd5496Sdanielk1977 15412dd5496Sdanielk1977finish_test 155