CoolFace
Modelpublic

AryaWu/sqlite

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
savepoint.test1059 linesDownload Raw Back to test
1# 2008 December 152#3# The author disclaims copyright to this source code.  In place of4# 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#12# $Id: savepoint.test,v 1.13 2009/07/18 08:30:45 danielk1977 Exp $13 14set testdir [file dirname $argv0]15source $testdir/tester.tcl16source $testdir/lock_common.tcl17source $testdir/malloc_common.tcl18 19forcedelete test2.db20 21#----------------------------------------------------------------------22# The following tests - savepoint-1.* - test that the SAVEPOINT, RELEASE23# and ROLLBACK TO comands are correctly parsed, and that the auto-commit24# flag is correctly set and unset as a result.25#26do_test savepoint-1.1 {27  wal_set_journal_mode28  execsql {29    SAVEPOINT sp1;30    RELEASE sp1;31  }32} {}33do_test savepoint-1.2 {34  execsql {35    SAVEPOINT sp1;36    ROLLBACK TO sp1;37  }38} {}39do_test savepoint-1.3 {40  execsql { SAVEPOINT sp1 }41  db close42} {}43sqlite3 db test.db44do_test savepoint-1.4.1 {45  execsql {46    SAVEPOINT sp1;47    SAVEPOINT sp2;48    RELEASE sp1;49  }50  sqlite3_get_autocommit db51} {1}52do_test savepoint-1.4.2 {53  execsql {54    SAVEPOINT sp1;55    SAVEPOINT sp2;56    RELEASE sp2;57  }58  sqlite3_get_autocommit db59} {0}60do_test savepoint-1.4.3 {61  execsql { RELEASE sp1 }62  sqlite3_get_autocommit db63} {1}64do_test savepoint-1.4.4 {65  execsql {66    SAVEPOINT sp1;67    SAVEPOINT sp2;68    ROLLBACK TO sp1;69  }70  sqlite3_get_autocommit db71} {0}72do_test savepoint-1.4.5 {73  execsql { RELEASE SAVEPOINT sp1 }74  sqlite3_get_autocommit db75} {1}76do_test savepoint-1.4.6 {77  execsql {78    SAVEPOINT sp1;79    SAVEPOINT sp2;80    SAVEPOINT sp3;81    ROLLBACK TO SAVEPOINT sp3;82    ROLLBACK TRANSACTION TO sp2;83    ROLLBACK TRANSACTION TO SAVEPOINT sp1;84  }85  sqlite3_get_autocommit db86} {0}87do_test savepoint-1.4.7 {88  execsql { RELEASE SAVEPOINT SP1 }89  sqlite3_get_autocommit db90} {1}91do_test savepoint-1.5 {92  execsql {93    SAVEPOINT sp1;94    ROLLBACK TO sp1;95  }96} {}97do_test savepoint-1.6 {98  execsql COMMIT99} {}100wal_check_journal_mode savepoint-1.7101 102#------------------------------------------------------------------------103# These tests - savepoint-2.* - test rollbacks and releases of savepoints104# with a very simple data set.105# 106 107do_test savepoint-2.1 {108  execsql {109    CREATE TABLE t1(a, b, c);110    BEGIN;111    INSERT INTO t1 VALUES(1, 2, 3);112    SAVEPOINT one;113    UPDATE t1 SET a = 2, b = 3, c = 4;114  }115  execsql { SELECT * FROM t1 }116} {2 3 4}117do_test savepoint-2.2 {118  execsql {119    ROLLBACK TO one;120  }121  execsql { SELECT * FROM t1 }122} {1 2 3}123do_test savepoint-2.3 {124  execsql {125    INSERT INTO t1 VALUES(4, 5, 6);126  }127  execsql { SELECT * FROM t1 }128} {1 2 3 4 5 6}129do_test savepoint-2.4 {130  execsql {131    ROLLBACK TO one;132  }133  execsql { SELECT * FROM t1 }134} {1 2 3}135 136 137do_test savepoint-2.5 {138  execsql {139    INSERT INTO t1 VALUES(7, 8, 9);140    SAVEPOINT two;141    INSERT INTO t1 VALUES(10, 11, 12);142  }143  execsql { SELECT * FROM t1 }144} {1 2 3 7 8 9 10 11 12}145do_test savepoint-2.6 {146  execsql {147    ROLLBACK TO two;148  }149  execsql { SELECT * FROM t1 }150} {1 2 3 7 8 9}151do_test savepoint-2.7 {152  execsql {153    INSERT INTO t1 VALUES(10, 11, 12);154  }155  execsql { SELECT * FROM t1 }156} {1 2 3 7 8 9 10 11 12}157do_test savepoint-2.8 {158  execsql {159    ROLLBACK TO one;160  }161  execsql { SELECT * FROM t1 }162} {1 2 3}163do_test savepoint-2.9 {164  execsql {165    INSERT INTO t1 VALUES('a', 'b', 'c');166    SAVEPOINT two;167    INSERT INTO t1 VALUES('d', 'e', 'f');168  }169  execsql { SELECT * FROM t1 }170} {1 2 3 a b c d e f}171do_test savepoint-2.10 {172  execsql {173    RELEASE two;174  }175  execsql { SELECT * FROM t1 }176} {1 2 3 a b c d e f}177do_test savepoint-2.11 {178  execsql {179    ROLLBACK;180  }181  execsql { SELECT * FROM t1 }182} {}183wal_check_journal_mode savepoint-2.12184 185#------------------------------------------------------------------------186# This block of tests - savepoint-3.* - test that when a transaction187# savepoint is rolled back, locks are not released from database files.188# And that when a transaction savepoint is released, they are released.189#190# These tests do not work in WAL mode. WAL mode does not take RESERVED191# locks on the database file.192# 193if {[wal_is_wal_mode]==0} {194  do_test savepoint-3.1 {195    execsql { SAVEPOINT "transaction" }196    execsql { PRAGMA lock_status }197  } {main unlocked temp closed}198  199  do_test savepoint-3.2 {200    execsql { INSERT INTO t1 VALUES(1, 2, 3) }201    execsql { PRAGMA lock_status }202  } {main reserved temp closed}203  204  do_test savepoint-3.3 {205    execsql { ROLLBACK TO "transaction" }206    execsql { PRAGMA lock_status }207  } {main reserved temp closed}208  209  do_test savepoint-3.4 {210    execsql { INSERT INTO t1 VALUES(1, 2, 3) }211    execsql { PRAGMA lock_status }212  } {main reserved temp closed}213  214  do_test savepoint-3.5 {215    execsql { RELEASE "transaction" }216    execsql { PRAGMA lock_status }217  } {main unlocked temp closed}218}219 220#------------------------------------------------------------------------221# Test that savepoints that include schema modifications are handled222# correctly. Test cases savepoint-4.*.223# 224do_test savepoint-4.1 {225  execsql {226    CREATE TABLE t2(d, e, f);227    SELECT sql FROM sqlite_master;228  }229} {{CREATE TABLE t1(a, b, c)} {CREATE TABLE t2(d, e, f)}}230do_test savepoint-4.2 {231  execsql {232    BEGIN;233    CREATE TABLE t3(g,h);234    INSERT INTO t3 VALUES('I', 'II');235    SAVEPOINT one;236    DROP TABLE t3;237  }238} {}239do_test savepoint-4.3 {240  execsql {241    CREATE TABLE t3(g, h, i);242    INSERT INTO t3 VALUES('III', 'IV', 'V');243  }244  execsql {SELECT * FROM t3}245} {III IV V}246do_test savepoint-4.4 {247  execsql { ROLLBACK TO one; }248  execsql {SELECT * FROM t3}249} {I II}250do_test savepoint-4.5 {251  execsql {252    ROLLBACK;253    SELECT sql FROM sqlite_master;254  }255} {{CREATE TABLE t1(a, b, c)} {CREATE TABLE t2(d, e, f)}}256 257do_test savepoint-4.6 {258  execsql {259    BEGIN;260    INSERT INTO t1 VALUES('o', 't', 't');261    SAVEPOINT sp1;262    CREATE TABLE t3(a, b, c);263    INSERT INTO t3 VALUES('z', 'y', 'x');264  }265  execsql {SELECT * FROM t3}266} {z y x}267do_test savepoint-4.7 {268  execsql {269    ROLLBACK TO sp1;270    CREATE TABLE t3(a);271    INSERT INTO t3 VALUES('value');272  }273  execsql {SELECT * FROM t3}274} {value}275do_test savepoint-4.8 {276  execsql COMMIT277} {}278wal_check_journal_mode savepoint-4.9279 280#------------------------------------------------------------------------281# Test some logic errors to do with the savepoint feature.282# 283 284ifcapable incrblob {285  do_test savepoint-5.1.1 {286    execsql {287      CREATE TABLE blobs(x);288      INSERT INTO blobs VALUES('a twentyeight character blob');289    }290    set fd [db incrblob blobs x 1]291    puts -nonewline $fd "hello"292    catchsql {SAVEPOINT abc}293  } {1 {cannot open savepoint - SQL statements in progress}}294  do_test savepoint-5.1.2 {295    close $fd296    catchsql {SAVEPOINT abc}297  } {0 {}}298  299  do_test savepoint-5.2 {300    execsql  {RELEASE abc}301    catchsql {RELEASE abc}302  } {1 {no such savepoint: abc}}303  304  do_test savepoint-5.3.1 {305    execsql  {SAVEPOINT abc}306    catchsql {ROLLBACK TO def}307  } {1 {no such savepoint: def}}308  do_test savepoint-5.3.2.1 {309    execsql  {SAVEPOINT def}310    set fd [db incrblob -readonly blobs x 1]311    set rc [catch {seek $fd 0;read $fd} res]312    lappend rc $res313  } {0 {hellontyeight character blob}}314  do_test savepoint-5.3.2.2 {315    catchsql {ROLLBACK TO def}316  } {0 {}}317  do_test savepoint-5.3.2.3 {318    set rc [catch {seek $fd 0; read $fd} res]319    set rc320  } {0}321  do_test savepoint-5.3.3 {322    catchsql  {RELEASE def}323  } {0 {}}324  do_test savepoint-5.3.4 {325    close $fd326    execsql  {savepoint def}327    set fd [db incrblob blobs x 1]328    catchsql {release def}329  } {1 {cannot release savepoint - SQL statements in progress}}330  do_test savepoint-5.3.5 {331    close $fd332    execsql {release abc}333  } {}334  335  # Rollback mode:336  #337  #   Open a savepoint transaction and insert a row into the database. Then,338  #   using a second database handle, open a read-only transaction on the339  #   database file. Check that the savepoint transaction cannot be committed340  #   until after the read-only transaction has been closed.341  #342  # WAL mode:343  # 344  #   As above, except that the savepoint transaction can be successfully345  #   committed before the read-only transaction has been closed.346  #347  do_test savepoint-5.4.1 {348    execsql {349      SAVEPOINT main;350      INSERT INTO blobs VALUES('another blob');351    }352  } {}353  do_test savepoint-5.4.2 {354    sqlite3 db2 test.db355    execsql { BEGIN ; SELECT count(*) FROM blobs } db2356  } {1}357  if {[wal_is_wal_mode]} {358    do_test savepoint-5.4.3 { catchsql "RELEASE main" } {0 {}}359    do_test savepoint-5.4.4 { db2 close               } {}360  } else {361    do_test savepoint-5.4.3 {362      catchsql { RELEASE main }363    } {1 {database is locked}}364    do_test savepoint-5.4.4 {365      db2 close366      catchsql { RELEASE main }367    } {0 {}}368  }369  do_test savepoint-5.4.5 {370    execsql { SELECT x FROM blobs WHERE rowid = 2 }371  } {{another blob}}372  do_test savepoint-5.4.6 {373    execsql { SELECT count(*) FROM blobs }374  } {2}375}376wal_check_journal_mode savepoint-5.5377 378#-------------------------------------------------------------------------379# The following tests, savepoint-6.*, test an incr-vacuum inside of a380# couple of nested savepoints.381#382ifcapable {autovacuum && pragma} {383  db close384  forcedelete test.db385  sqlite3 db test.db386 387  do_test savepoint-6.1 {388    execsql { PRAGMA auto_vacuum = incremental }389    wal_set_journal_mode390    execsql {391      CREATE TABLE t1(a, b, c);392      CREATE INDEX i1 ON t1(a, b);393      BEGIN;394      INSERT INTO t1 VALUES(randstr(10,400),randstr(10,400),randstr(10,400));395    }396    set r "randstr(10,400)"397    for {set ii 0} {$ii < 10} {incr ii} {398      execsql "INSERT INTO t1 SELECT $r, $r, $r FROM t1"399    }400    execsql { COMMIT }401  } {}402 403  integrity_check savepoint-6.2404 405  do_test savepoint-6.3 {406    execsql {407      PRAGMA cache_size = 10;408      BEGIN;409        UPDATE t1 SET a = randstr(10,10) WHERE (rowid%4)==0;410        SAVEPOINT one;411          DELETE FROM t1 WHERE rowid%2;412          PRAGMA incr_vacuum;413          SAVEPOINT two;414            INSERT INTO t1 SELECT randstr(10,400), randstr(10,400), c FROM t1;415            DELETE FROM t1 WHERE rowid%2;416            PRAGMA incr_vacuum;417        ROLLBACK TO one;418      COMMIT;419    }420  } {}421 422  integrity_check savepoint-6.4423 424  wal_check_journal_mode savepoint-6.5425}426 427#-------------------------------------------------------------------------428# The following tests, savepoint-7.*, attempt to break the logic 429# surrounding savepoints by growing and shrinking the database file.430#431db close432forcedelete test.db433sqlite3 db test.db434 435do_test savepoint-7.1 {436  execsql { PRAGMA auto_vacuum = incremental }437  wal_set_journal_mode438  execsql {439    PRAGMA cache_size = 10;440    BEGIN;441    CREATE TABLE t1(a PRIMARY KEY, b);442      INSERT INTO t1(a) VALUES('alligator');443      INSERT INTO t1(a) VALUES('angelfish');444      INSERT INTO t1(a) VALUES('ant');445      INSERT INTO t1(a) VALUES('antelope');446      INSERT INTO t1(a) VALUES('ape');447      INSERT INTO t1(a) VALUES('baboon');448      INSERT INTO t1(a) VALUES('badger');449      INSERT INTO t1(a) VALUES('bear');450      INSERT INTO t1(a) VALUES('beetle');451      INSERT INTO t1(a) VALUES('bird');452      INSERT INTO t1(a) VALUES('bison');453      UPDATE t1 SET b =    randstr(1000,1000);454      UPDATE t1 SET b = b||randstr(1000,1000);455      UPDATE t1 SET b = b||randstr(1000,1000);456      UPDATE t1 SET b = b||randstr(10,1000);457    COMMIT;458  }459  expr ([execsql { PRAGMA page_count }] > 20)460} {1}461do_test savepoint-7.2.1 {462  execsql {463    BEGIN;464      SAVEPOINT one;465      CREATE TABLE t2(a, b);466      INSERT INTO t2 SELECT a, b FROM t1;467      ROLLBACK TO one;468  }469  execsql {470    PRAGMA integrity_check;471  }472} {ok}473do_test savepoint-7.2.2 {474  execsql {475    COMMIT;476    PRAGMA integrity_check;477  }478} {ok}479 480do_test savepoint-7.3.1 {481  execsql {482    CREATE TABLE t2(a, b);483    INSERT INTO t2 SELECT a, b FROM t1;484  }485} {}486do_test savepoint-7.3.2 {487  execsql {488    BEGIN;489      SAVEPOINT one;490        DELETE FROM t2;491        PRAGMA incremental_vacuum;492        SAVEPOINT two;493          INSERT INTO t2 SELECT a, b FROM t1;494        ROLLBACK TO two;495    COMMIT;496  }497  execsql { PRAGMA integrity_check }498} {ok}499wal_check_journal_mode savepoint-7.3.3500 501do_test savepoint-7.4.1 {502  db close503  forcedelete test.db504  sqlite3 db test.db505  execsql { PRAGMA auto_vacuum = incremental }506  wal_set_journal_mode507  execsql {508    CREATE TABLE t1(a, b, PRIMARY KEY(a, b));509    INSERT INTO t1 VALUES(randstr(1000,1000), randstr(1000,1000));510    BEGIN;511      DELETE FROM t1;512      SAVEPOINT one;513      PRAGMA incremental_vacuum;514      ROLLBACK TO one;515    COMMIT;516  }517 518  execsql { PRAGMA integrity_check }519} {ok}520 521do_test savepoint-7.5.1 {522  execsql {523    PRAGMA incremental_vacuum;524    CREATE TABLE t5(x, y);525    INSERT INTO t5 VALUES(1, randstr(1000,1000));526    INSERT INTO t5 VALUES(2, randstr(1000,1000));527    INSERT INTO t5 VALUES(3, randstr(1000,1000));528 529    BEGIN;530      INSERT INTO t5 VALUES(4, randstr(1000,1000));531      INSERT INTO t5 VALUES(5, randstr(1000,1000));532      DELETE FROM t5 WHERE x=1 OR x=2;533      SAVEPOINT one;534        PRAGMA incremental_vacuum;535        SAVEPOINT two;536          INSERT INTO t5 VALUES(1, randstr(1000,1000));537          INSERT INTO t5 VALUES(2, randstr(1000,1000));538        ROLLBACK TO two;539      ROLLBACK TO one;540    COMMIT;541    PRAGMA integrity_check;542  }543} {ok}544do_test savepoint-7.5.2 {545  execsql {546    DROP TABLE t5;547  }548} {}549wal_check_journal_mode savepoint-7.5.3550 551# Test oddly named and quoted savepoints.552#553do_test savepoint-8-1 {554  execsql { SAVEPOINT "save1" }555  execsql { RELEASE save1 }556} {}557do_test savepoint-8-2 {558  execsql { SAVEPOINT "Including whitespace " }559  execsql { RELEASE "including Whitespace " }560} {}561 562# Test that the authorization callback works.563#564ifcapable auth {565  proc auth {args} {566    eval lappend ::authdata [lrange $args 0 4]567    return SQLITE_OK568  }569  db auth auth570 571  do_test savepoint-9.1 {572    set ::authdata [list]573    execsql { SAVEPOINT sp1 }574    set ::authdata575  } {SQLITE_SAVEPOINT BEGIN sp1 {} {}}576  do_test savepoint-9.2 {577    set ::authdata [list]578    execsql { ROLLBACK TO sp1 }579    set ::authdata580  } {SQLITE_SAVEPOINT ROLLBACK sp1 {} {}}581  do_test savepoint-9.3 {582    set ::authdata [list]583    execsql { RELEASE sp1 }584    set ::authdata585  } {SQLITE_SAVEPOINT RELEASE sp1 {} {}}586 587  proc auth {args} {588    eval lappend ::authdata [lrange $args 0 4]589    return SQLITE_DENY590  }591  db auth auth592 593  do_test savepoint-9.4 {594    set ::authdata [list]595    set res [catchsql { SAVEPOINT sp1 }]596    concat $::authdata $res597  } {SQLITE_SAVEPOINT BEGIN sp1 {} {} 1 {not authorized}}598  do_test savepoint-9.5 {599    set ::authdata [list]600    set res [catchsql { ROLLBACK TO sp1 }]601    concat $::authdata $res602  } {SQLITE_SAVEPOINT ROLLBACK sp1 {} {} 1 {not authorized}}603  do_test savepoint-9.6 {604    set ::authdata [list]605    set res [catchsql { RELEASE sp1 }]606    concat $::authdata $res607  } {SQLITE_SAVEPOINT RELEASE sp1 {} {} 1 {not authorized}}608 609  catch { db eval ROLLBACK }610  db auth ""611}612 613#-------------------------------------------------------------------------614# The following tests - savepoint-10.* - test the interaction of 615# savepoints and ATTACH statements.616# 617 618# First make sure it is not possible to attach or detach a database while619# a savepoint is open (it is not possible if any transaction is open).620#621# UPDATE 2017-07-26:  It is not possible to ATTACH and DETACH within a622# a transaction.623#624do_test savepoint-10.1.1 {625  catchsql {626    SAVEPOINT one;627    ATTACH 'test2.db' AS aux;628    DETACH aux;629  }630} {0 {}}631do_test savepoint-10.1.2 {632  execsql {633    RELEASE one;634    ATTACH 'test2.db' AS aux;635  }636  catchsql {637    SAVEPOINT one;638    DETACH aux;639    ATTACH 'test2.db' AS aux;640  }641} {0 {}}642do_test savepoint-10.1.3 {643  execsql {644    RELEASE one;645    DETACH aux;646  }647} {}648 649# The lock state of the TEMP database can vary if SQLITE_TEMP_STORE=3650# And the following set of tests is only really interested in the status651# of the aux1 and aux2 locks.  So record the current lock status of652# TEMP for use in the answers.653set templockstate [lindex [db eval {PRAGMA lock_status}] 3]654 655 656if {[wal_is_wal_mode]==0} {657  do_test savepoint-10.2.1 {658    forcedelete test3.db659    forcedelete test2.db660    execsql {661      ATTACH 'test2.db' AS aux1;662      ATTACH 'test3.db' AS aux2;663      DROP TABLE t1;664      CREATE TABLE main.t1(x, y);665      CREATE TABLE aux1.t2(x, y);666      CREATE TABLE aux2.t3(x, y);667      SELECT name FROM sqlite_master;668      SELECT name FROM aux1.sqlite_master;669      SELECT name FROM aux2.sqlite_master;670    }671  } {t1 t2 t3}672  do_test savepoint-10.2.2 {673    execsql { PRAGMA lock_status }674  } [list main unlocked temp $templockstate aux1 unlocked aux2 unlocked]675  676  do_test savepoint-10.2.3 {677    execsql {678      SAVEPOINT one;679      INSERT INTO t1 VALUES(1, 2);680      PRAGMA lock_status;681    }682  } [list main reserved temp $templockstate aux1 unlocked aux2 unlocked]683  do_test savepoint-10.2.4 {684    execsql {685      INSERT INTO t3 VALUES(3, 4);686      PRAGMA lock_status;687    }688  } [list main reserved temp $templockstate aux1 unlocked aux2 reserved]689  do_test savepoint-10.2.5 {690    execsql {691      SAVEPOINT two;692      INSERT INTO t2 VALUES(5, 6);693      PRAGMA lock_status;694    }695  } [list main reserved temp $templockstate aux1 reserved aux2 reserved]696  do_test savepoint-10.2.6 {697    execsql { SELECT * FROM t2 }698  } {5 6}699  do_test savepoint-10.2.7 {700    execsql { ROLLBACK TO two }701    execsql { SELECT * FROM t2 }702  } {}703  do_test savepoint-10.2.8 {704    execsql { PRAGMA lock_status }705  } [list main reserved temp $templockstate aux1 reserved aux2 reserved]706  do_test savepoint-10.2.9 {707    execsql { SELECT 'a', * FROM t1 ; SELECT 'b', * FROM t3 }708  } {a 1 2 b 3 4}709  do_test savepoint-10.2.9 {710    execsql {711      INSERT INTO t2 VALUES(5, 6);712      RELEASE one;713    }714    execsql { 715      SELECT * FROM t1;716      SELECT * FROM t2;717      SELECT * FROM t3;718    }719  } {1 2 5 6 3 4}720  do_test savepoint-10.2.9 {721    execsql { PRAGMA lock_status }722  } [list main unlocked temp $templockstate aux1 unlocked aux2 unlocked]723  724  do_test savepoint-10.2.10 {725    execsql { 726      SAVEPOINT one;727        INSERT INTO t1 VALUES('a', 'b');728        SAVEPOINT two;729          INSERT INTO t2 VALUES('c', 'd');730          SAVEPOINT three;731            INSERT INTO t3 VALUES('e', 'f');732    }733    execsql { 734      SELECT * FROM t1;735      SELECT * FROM t2;736      SELECT * FROM t3;737    }738  } {1 2 a b 5 6 c d 3 4 e f}739  do_test savepoint-10.2.11 {740    execsql { ROLLBACK TO two }741    execsql { 742      SELECT * FROM t1;743      SELECT * FROM t2;744      SELECT * FROM t3;745    }746  } {1 2 a b 5 6 3 4}747  do_test savepoint-10.2.12 {748    execsql { 749      INSERT INTO t3 VALUES('g', 'h');750      ROLLBACK TO two;751    }752    execsql { 753      SELECT * FROM t1;754      SELECT * FROM t2;755      SELECT * FROM t3;756    }757  } {1 2 a b 5 6 3 4}758  do_test savepoint-10.2.13 {759    execsql { ROLLBACK }760    execsql { 761      SELECT * FROM t1;762      SELECT * FROM t2;763      SELECT * FROM t3;764    }765  } {1 2 5 6 3 4}766  do_test savepoint-10.2.14 {767    execsql { PRAGMA lock_status }768  } [list main unlocked temp $templockstate aux1 unlocked aux2 unlocked]769}770 771#-------------------------------------------------------------------------772# The following tests - savepoint-11.* - test the interaction of 773# savepoints and creating or dropping tables and indexes in 774# auto-vacuum mode.775# 776do_test savepoint-11.1 {777  db close778  forcedelete test.db779  sqlite3 db test.db780  execsql { PRAGMA auto_vacuum = full; }781  wal_set_journal_mode782  execsql {783    CREATE TABLE t1(a, b, UNIQUE(a, b));784    INSERT INTO t1 VALUES(1, randstr(1000,1000));785    INSERT INTO t1 VALUES(2, randstr(1000,1000));786  }787} {}788do_test savepoint-11.2 {789  execsql {790    SAVEPOINT one;791      CREATE TABLE t2(a, b, UNIQUE(a, b));792      SAVEPOINT two;793        CREATE TABLE t3(a, b, UNIQUE(a, b));794  }795} {}796integrity_check savepoint-11.3797do_test savepoint-11.4 {798  execsql { ROLLBACK TO two }799} {}800integrity_check savepoint-11.5801do_test savepoint-11.6 {802  execsql { 803    CREATE TABLE t3(a, b, UNIQUE(a, b));804    ROLLBACK TO one;805  }806} {}807integrity_check savepoint-11.7808do_test savepoint-11.8 {809  execsql { ROLLBACK }810  execsql { PRAGMA wal_checkpoint }811  file size test.db812} {8192}813 814do_test savepoint-11.9 {815  execsql {816    DROP TABLE IF EXISTS t1;817    DROP TABLE IF EXISTS t2;818    DROP TABLE IF EXISTS t3;819  }820} {}821do_test savepoint-11.10 {822  execsql {823    BEGIN;824      CREATE TABLE t1(a, b);825      CREATE TABLE t2(x, y);826      INSERT INTO t2 VALUES(1, 2);827      SAVEPOINT one;828        INSERT INTO t2 VALUES(3, 4);829        SAVEPOINT two;830          DROP TABLE t1;831        ROLLBACK TO two;832  }833  execsql {SELECT * FROM t2}834} {1 2 3 4}835do_test savepoint-11.11 {836  execsql COMMIT837} {}838do_test savepoint-11.12 {839  execsql {SELECT * FROM t2}840} {1 2 3 4}841wal_check_journal_mode savepoint-11.13842 843#-------------------------------------------------------------------------844# The following tests - savepoint-12.* - test the interaction of 845# savepoints and "ON CONFLICT ROLLBACK" clauses.846# 847do_test savepoint-12.1 {848  execsql {849    CREATE TABLE t4(a PRIMARY KEY, b);850    INSERT INTO t4 VALUES(1, 'one');851  }852} {}853do_test savepoint-12.2 {854  # The final statement of the following SQL hits a constraint when the855  # conflict handling mode is "OR ROLLBACK" and there are a couple of856  # open savepoints. At one point this would fail to clear the internal857  # record of the open savepoints, resulting in an assert() failure 858  # later on.859  # 860  catchsql {861    BEGIN;862      INSERT INTO t4 VALUES(2, 'two');863      SAVEPOINT sp1;864        INSERT INTO t4 VALUES(3, 'three');865        SAVEPOINT sp2;866          INSERT OR ROLLBACK INTO t4 VALUES(1, 'one');867  }868} {1 {UNIQUE constraint failed: t4.a}}869do_test savepoint-12.3 {870  sqlite3_get_autocommit db871} {1}872do_test savepoint-12.4 {873  execsql { SAVEPOINT one }874} {}875wal_check_journal_mode savepoint-12.5876 877#-------------------------------------------------------------------------878# The following tests - savepoint-13.* - test the interaction of 879# savepoints and "journal_mode = off".880# 881if {[wal_is_wal_mode]==0} {882  do_test savepoint-13.1 {883    db close884    catch {forcedelete test.db}885    sqlite3 db test.db886    execsql {887      BEGIN;888        CREATE TABLE t1(a PRIMARY KEY, b);889        INSERT INTO t1 VALUES(1, 2);890      COMMIT;891      PRAGMA journal_mode = off;892    }893  } {off}894  do_test savepoint-13.2 {895    execsql {896      BEGIN;897      INSERT INTO t1 VALUES(3, 4);898      INSERT INTO t1 SELECT a+4,b+4  FROM t1;899      COMMIT;900    }901  } {}902  do_test savepoint-13.3 {903    execsql {904      BEGIN;905        INSERT INTO t1 VALUES(9, 10);906        SAVEPOINT s1;907          INSERT INTO t1 VALUES(11, 12);908      COMMIT;909    }910  } {}911  do_test savepoint-13.4 {912    execsql {913      BEGIN;914        INSERT INTO t1 VALUES(13, 14);915        SAVEPOINT s1;916          INSERT INTO t1 VALUES(15, 16);917        ROLLBACK TO s1;918      ROLLBACK;919      SELECT * FROM t1;920    }921  } {1 2 3 4 5 6 7 8 9 10 11 12}922}923 924db close925delete_file test.db926do_multiclient_test tn {927  do_test savepoint-14.$tn.1 {928    sql1 {929      CREATE TABLE foo(x);930      INSERT INTO foo VALUES(1);931      INSERT INTO foo VALUES(2);932    }933    sql2 {934      BEGIN;935        SELECT * FROM foo;936    }937  } {1 2}938  do_test savepoint-14.$tn.2 {939    sql1 {940      SAVEPOINT one;941      INSERT INTO foo VALUES(1);942    }943    csql1 { RELEASE one }944  } {1 {database is locked}}945  do_test savepoint-14.$tn.3 {946    sql1 { ROLLBACK TO one }947    sql2 { COMMIT }948    sql1 { RELEASE one }949  } {}950 951  do_test savepoint-14.$tn.4 {952    sql2 {953      BEGIN;954        SELECT * FROM foo;955    }956  } {1 2}957  do_test savepoint-14.$tn.5 {958    sql1 {959      SAVEPOINT one;960      INSERT INTO foo VALUES(1);961    }962    csql1 { RELEASE one }963  } {1 {database is locked}}964  do_test savepoint-14.$tn.6 {965    sql2 { COMMIT }966    sql1 {967      ROLLBACK TO one;968      INSERT INTO foo VALUES(3);969      INSERT INTO foo VALUES(4);970      INSERT INTO foo VALUES(5);971      RELEASE one;972    }973  } {}974  do_test savepoint-14.$tn.7 {975    sql2 { CREATE INDEX fooidx ON foo(x); }976    sql3 { PRAGMA integrity_check }977  } {ok}978}979 980do_multiclient_test tn {981  do_test savepoint-15.$tn.1 {982    sql1 {983      CREATE TABLE foo(x);984      INSERT INTO foo VALUES(1);985      INSERT INTO foo VALUES(2);986    }987    sql2 { BEGIN; SELECT * FROM foo; }988  } {1 2}989  do_test savepoint-15.$tn.2 {990    sql1 {991      PRAGMA locking_mode = EXCLUSIVE;992      BEGIN;993        INSERT INTO foo VALUES(3);994    }995    csql1 { COMMIT }996  } {1 {database is locked}}997  do_test savepoint-15.$tn.3 {998    sql1 { ROLLBACK }999    sql2 { COMMIT }1000    sql1 {1001      INSERT INTO foo VALUES(3);1002      PRAGMA locking_mode = NORMAL;1003      INSERT INTO foo VALUES(4);1004    }1005    sql2 { CREATE INDEX fooidx ON foo(x); }1006    sql3 { PRAGMA integrity_check }1007  } {ok}1008}1009 1010do_multiclient_test tn {1011  do_test savepoint-16.$tn.1 {1012    sql1 {1013      CREATE TABLE foo(x);1014      INSERT INTO foo VALUES(1);1015      INSERT INTO foo VALUES(2);1016    }1017  } {}1018  do_test savepoint-16.$tn.2 {1019 1020    db eval {SELECT * FROM foo} {1021      sql1 { INSERT INTO foo VALUES(3) }1022      sql2 { SELECT * FROM foo }1023      sql1 { INSERT INTO foo VALUES(4) }1024      break1025    }1026 1027    sql2 { CREATE INDEX fooidx ON foo(x); }1028    sql3 { PRAGMA integrity_check }1029  } {ok}1030  do_test savepoint-16.$tn.3 {1031    sql1 { SELECT * FROM foo }1032  } {1 2 3 4}1033}1034 1035#-------------------------------------------------------------------------1036# This next block of tests verifies that a problem reported on the mailing1037# list has been resolved. At one point the second "CREATE TABLE t6" would1038# fail as table t6 still existed in the internal cache of the db schema1039# (even though it had been removed from the database by the ROLLBACK 1040# command).1041#1042sqlite3 db test.db1043do_execsql_test savepoint-17.1 {1044  BEGIN;1045    CREATE TABLE t6(a, b);1046    INSERT INTO t6 VALUES(1, 2);1047    SAVEPOINT one;1048      INSERT INTO t6 VALUES(3, 4);1049    ROLLBACK TO one;1050    SELECT * FROM t6;1051  ROLLBACK;1052} {1 2}1053 1054do_execsql_test savepoint-17.2 {1055  CREATE TABLE t6(a, b);1056} {}1057 1058finish_test1059