Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Increase test coverage of new savepoint code. (CVS 6040) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
d915718d0b346982d686d131a159b67e |
User & Date: | danielk1977 2008-12-18 18:31:39.000 |
Context
2008-12-18
| ||
22:25 | Fix the Oracle and MS-Sql command-line terminator logic in the CLI. Ticket #3544. (CVS 6041) (check-in: dcc8935fa0 user: drh tags: trunk) | |
18:31 | Increase test coverage of new savepoint code. (CVS 6040) (check-in: d915718d0b user: danielk1977 tags: trunk) | |
15:45 | Add savepoint2.test, a file containing savepoint tests similar to tests in trans.test and avtrans.test. And a few savepoint bug fixes. (CVS 6039) (check-in: 98a53d91f6 user: danielk1977 tags: trunk) | |
Changes
Changes to src/pager.c.
︙ | ︙ | |||
14 15 16 17 18 19 20 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** | | | 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file ** locking to prevent two processes from writing the same database ** file simultaneously, or one process from reading the database while ** another is writing. ** ** @(#) $Id: pager.c,v 1.517 2008/12/18 18:31:39 danielk1977 Exp $ */ #ifndef SQLITE_OMIT_DISKIO #include "sqliteInt.h" /* ** Macros for troubleshooting. Normally turned off */ |
︙ | ︙ | |||
918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 | ** to access those pages will likely result in a coredump. */ static void pager_reset(Pager *pPager){ if( pPager->errCode ) return; sqlite3PcacheClear(pPager->pPCache); } static void releaseAllSavepoint(Pager *pPager){ int ii; for(ii=0; ii<pPager->nSavepoint; ii++){ sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint); } if( !pPager->exclusiveMode ){ sqlite3OsClose(pPager->sjfd); } sqlite3_free(pPager->aSavepoint); pPager->aSavepoint = 0; pPager->nSavepoint = 0; } static int addToSavepointBitvecs(Pager *pPager, Pgno pgno){ int ii; for(ii=0; ii<pPager->nSavepoint; ii++){ PagerSavepoint *p = &pPager->aSavepoint[ii]; if( pgno<=p->nOrig ){ /* TODO: malloc() failure handling */ sqlite3BitvecSet(p->pInSavepoint, pgno); | > > > > > > > > > | 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 | ** to access those pages will likely result in a coredump. */ static void pager_reset(Pager *pPager){ if( pPager->errCode ) return; sqlite3PcacheClear(pPager->pPCache); } /* ** Free all structures in the Pager.aSavepoint[] array and set both ** Pager.aSavepoint and Pager.nSavepoint to zero. Close the sub-journal ** if it is open and the pager is not in exclusive mode. */ static void releaseAllSavepoint(Pager *pPager){ int ii; for(ii=0; ii<pPager->nSavepoint; ii++){ sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint); } if( !pPager->exclusiveMode ){ sqlite3OsClose(pPager->sjfd); } sqlite3_free(pPager->aSavepoint); pPager->aSavepoint = 0; pPager->nSavepoint = 0; } /* ** Set the bit number pgno in the PagerSavepoint.pInSavepoint bitvecs of ** all open savepoints. */ static int addToSavepointBitvecs(Pager *pPager, Pgno pgno){ int ii; for(ii=0; ii<pPager->nSavepoint; ii++){ PagerSavepoint *p = &pPager->aSavepoint[ii]; if( pgno<=p->nOrig ){ /* TODO: malloc() failure handling */ sqlite3BitvecSet(p->pInSavepoint, pgno); |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.805 2008/12/18 18:31:39 danielk1977 Exp $ */ #include "sqliteInt.h" #include <ctype.h> #include "vdbeInt.h" /* ** The following global variable is incremented every time a cursor |
︙ | ︙ | |||
2391 2392 2393 2394 2395 2396 2397 | */ assert( db->pSavepoint==0 || db->autoCommit==0 ); assert( p1==SAVEPOINT_BEGIN||p1==SAVEPOINT_RELEASE||p1==SAVEPOINT_ROLLBACK ); assert( db->pSavepoint || db->isTransactionSavepoint==0 ); assert( checkSavepointCount(db) ); if( p1==SAVEPOINT_BEGIN ){ | | | 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 | */ assert( db->pSavepoint==0 || db->autoCommit==0 ); assert( p1==SAVEPOINT_BEGIN||p1==SAVEPOINT_RELEASE||p1==SAVEPOINT_ROLLBACK ); assert( db->pSavepoint || db->isTransactionSavepoint==0 ); assert( checkSavepointCount(db) ); if( p1==SAVEPOINT_BEGIN ){ if( db->writeVdbeCnt>0 ){ /* A new savepoint cannot be created if there are active write ** statements (i.e. open read/write incremental blob handles). */ sqlite3SetString(&p->zErrMsg, db, "cannot open savepoint - " "SQL statements in progress"); rc = SQLITE_BUSY; }else{ |
︙ | ︙ | |||
2453 2454 2455 2456 2457 2458 2459 | "cannot %s savepoint - SQL statements in progress", (p1==SAVEPOINT_ROLLBACK ? "rollback": "release") ); rc = SQLITE_BUSY; }else{ /* Determine whether or not this is a transaction savepoint. If so, | | | < < < > > | 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 | "cannot %s savepoint - SQL statements in progress", (p1==SAVEPOINT_ROLLBACK ? "rollback": "release") ); rc = SQLITE_BUSY; }else{ /* Determine whether or not this is a transaction savepoint. If so, ** and this is a RELEASE command, then the current transaction ** is committed. */ int isTransaction = pSavepoint->pNext==0 && db->isTransactionSavepoint; if( isTransaction && p1==SAVEPOINT_RELEASE ){ db->autoCommit = 1; if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ p->pc = pc; db->autoCommit = 0; p->rc = rc = SQLITE_BUSY; goto vdbe_return; } db->isTransactionSavepoint = 0; rc = p->rc; }else{ int ii; iSavepoint = db->nSavepoint - iSavepoint - 1; for(ii=0; ii<db->nDb; ii++){ rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint); if( rc!=SQLITE_OK ){ goto abort_due_to_error; |
︙ | ︙ |
Changes to test/savepoint.test.
1 2 3 4 5 6 7 8 9 10 11 | # 2008 December 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # 2008 December 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # $Id: savepoint.test,v 1.2 2008/12/18 18:31:39 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl #---------------------------------------------------------------------- # The following tests - savepoint-1.* - test that the SAVEPOINT, RELEASE |
︙ | ︙ | |||
260 261 262 263 264 265 266 267 268 269 | INSERT INTO t3 VALUES('value'); } execsql {SELECT * FROM t3} } {value} do_test savepoint-4.8 { execsql COMMIT } {} finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 | INSERT INTO t3 VALUES('value'); } execsql {SELECT * FROM t3} } {value} do_test savepoint-4.8 { execsql COMMIT } {} #------------------------------------------------------------------------ # Test some logic errors to do with the savepoint feature. # do_test savepoint-5.1.1 { execsql { CREATE TABLE blobs(x); INSERT INTO blobs VALUES('a twentyeight character blob'); } set fd [db incrblob blobs x 1] puts -nonewline $fd "hello" catchsql {SAVEPOINT abc} } {1 {cannot open savepoint - SQL statements in progress}} do_test savepoint-5.1.2 { close $fd catchsql {SAVEPOINT abc} } {0 {}} do_test savepoint-5.2 { execsql {RELEASE abc} catchsql {RELEASE abc} } {1 {no such savepoint: abc}} do_test savepoint-5.3.1 { execsql {SAVEPOINT abc} catchsql {ROLLBACK TO def} } {1 {no such savepoint: def}} do_test savepoint-5.3.2 { execsql {SAVEPOINT def} set fd [db incrblob -readonly blobs x 1] catchsql {ROLLBACK TO def} } {1 {cannot rollback savepoint - SQL statements in progress}} do_test savepoint-5.3.3 { catchsql {RELEASE def} } {0 {}} do_test savepoint-5.3.4 { close $fd execsql {savepoint def} set fd [db incrblob blobs x 1] catchsql {release def} } {1 {cannot release savepoint - SQL statements in progress}} do_test savepoint-5.3.5 { close $fd execsql {release abc} } {} do_test savepoint-5.4.1 { execsql { SAVEPOINT main; INSERT INTO blobs VALUES('another blob'); } } {} do_test savepoint-5.4.2 { sqlite3 db2 test.db execsql { BEGIN ; SELECT * FROM blobs } db2 catchsql { RELEASE main } } {1 {database is locked}} do_test savepoint-5.4.3 { db2 close catchsql { RELEASE main } } {0 {}} do_test savepoint-5.4.4 { execsql { SELECT x FROM blobs WHERE rowid = 2 } } {{another blob}} finish_test |
Changes to test/savepoint2.test.
1 2 3 4 5 6 7 8 9 10 11 | # 2008 December 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # | | < < < < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | # 2008 December 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # $Id: savepoint2.test,v 1.2 2008/12/18 18:31:39 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Tests in this file are quite similar to those run by trans.test and # avtrans.test. # proc signature {} { return [db eval {SELECT count(*), md5sum(x) FROM t3}] } do_test savepoint2-1 { execsql { PRAGMA cache_size=10; BEGIN; CREATE TABLE t3(x TEXT); INSERT INTO t3 VALUES(randstr(10,400)); INSERT INTO t3 VALUES(randstr(10,400)); INSERT INTO t3 SELECT randstr(10,400) FROM t3; INSERT INTO t3 SELECT randstr(10,400) FROM t3; INSERT INTO t3 SELECT randstr(10,400) FROM t3; |
︙ | ︙ |
Added test/savepoint3.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | # 2008 December 15 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # $Id: savepoint3.test,v 1.1 2008/12/18 18:31:39 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/malloc_common.tcl do_malloc_test savepoint3-1 -sqlprep { CREATE TABLE t1(a, b, c); INSERT INTO t1 VALUES(1, 2, 3); } -sqlbody { SAVEPOINT one; INSERT INTO t1 VALUES(4, 5, 6); SAVEPOINT two; DELETE FROM t1; ROLLBACK TO two; RELEASE one; } do_malloc_test savepoint3-1 -sqlprep { PRAGMA cache_size = 10; CREATE TABLE t1(a, b, c); INSERT INTO t1 VALUES(randstr(400,400), randstr(400,400), randstr(400,400)); INSERT INTO t1 SELECT randstr(400,400), randstr(400,400), randstr(400,400) FROM t1; INSERT INTO t1 SELECT randstr(400,400), randstr(400,400), randstr(400,400) FROM t1; INSERT INTO t1 SELECT randstr(400,400), randstr(400,400), randstr(400,400) FROM t1; INSERT INTO t1 SELECT randstr(400,400), randstr(400,400), randstr(400,400) FROM t1; INSERT INTO t1 SELECT randstr(400,400), randstr(400,400), randstr(400,400) FROM t1; INSERT INTO t1 SELECT randstr(400,400), randstr(400,400), randstr(400,400) FROM t1; INSERT INTO t1 SELECT randstr(400,400), randstr(400,400), randstr(400,400) FROM t1; INSERT INTO t1 SELECT randstr(400,400), randstr(400,400), randstr(400,400) FROM t1; } -sqlbody { PRAGMA cache_size = 10; SAVEPOINT one; DELETE FROM t1 WHERE rowid < 5; SAVEPOINT two; DELETE FROM t1 WHERE rowid > 10; ROLLBACK TO two; ROLLBACK TO one; RELEASE one; } finish_test |