Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add coverage tests for pager.c. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
228c5b16af80c22e97d9d4deb351e0d3 |
User & Date: | dan 2010-08-12 11:25:48.000 |
Context
2010-08-12
| ||
16:36 | If an error occurs in PagerSetPagesize(), set the output variable to the unmodified page-size before returning. (check-in: 02def8f925 user: dan tags: trunk) | |
11:25 | Add coverage tests for pager.c. (check-in: 228c5b16af user: dan tags: trunk) | |
02:41 | Increase the maximum page size from 32k to 64k. (check-in: 45362437d4 user: drh tags: trunk) | |
Changes
Changes to src/pager.c.
︙ | ︙ | |||
4122 4123 4124 4125 4126 4127 4128 | /* Mark the page as clean. */ if( rc==SQLITE_OK ){ PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno)); sqlite3PcacheMakeClean(pPg); } | | | 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 | /* Mark the page as clean. */ if( rc==SQLITE_OK ){ PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno)); sqlite3PcacheMakeClean(pPg); } return pager_error(pPager, rc); } /* ** Allocate and initialize a new Pager object and put a pointer to it ** in *ppPager. The pager should eventually be freed by passing it ** to sqlite3PagerClose(). |
︙ | ︙ | |||
5697 5698 5699 5700 5701 5702 5703 | ** file. This can only happen in auto-vacuum mode. ** ** Before reading the pages with page numbers larger than the ** current value of Pager.dbSize, set dbSize back to the value ** that it took at the start of the transaction. Otherwise, the ** calls to sqlite3PagerGet() return zeroed pages instead of ** reading data from the database file. | < < < | 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 | ** file. This can only happen in auto-vacuum mode. ** ** Before reading the pages with page numbers larger than the ** current value of Pager.dbSize, set dbSize back to the value ** that it took at the start of the transaction. Otherwise, the ** calls to sqlite3PagerGet() return zeroed pages instead of ** reading data from the database file. */ #ifndef SQLITE_OMIT_AUTOVACUUM if( pPager->dbSize<pPager->dbOrigSize && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ Pgno i; /* Iterator variable */ const Pgno iSkip = PAGER_MJ_PGNO(pPager); /* Pending lock page */ |
︙ | ︙ | |||
6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 6433 6434 | */ sqlite3OsClose(pPager->jfd); if( pPager->eLock>=RESERVED_LOCK ){ sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); }else{ int rc = SQLITE_OK; int state = pPager->eState; if( state==PAGER_OPEN ){ rc = sqlite3PagerSharedLock(pPager); } if( pPager->eState==PAGER_READER ){ assert( rc==SQLITE_OK ); rc = pagerLockDb(pPager, RESERVED_LOCK); } | > | 6418 6419 6420 6421 6422 6423 6424 6425 6426 6427 6428 6429 6430 6431 6432 | */ sqlite3OsClose(pPager->jfd); if( pPager->eLock>=RESERVED_LOCK ){ sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); }else{ int rc = SQLITE_OK; int state = pPager->eState; assert( state==PAGER_OPEN || state==PAGER_READER ); if( state==PAGER_OPEN ){ rc = sqlite3PagerSharedLock(pPager); } if( pPager->eState==PAGER_READER ){ assert( rc==SQLITE_OK ); rc = pagerLockDb(pPager, RESERVED_LOCK); } |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
2057 2058 2059 2060 2061 2062 2063 | /* Check for one of the special errors */ mrc = p->rc & 0xff; assert( p->rc!=SQLITE_IOERR_BLOCKED ); /* This error no longer exists */ isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR || mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL; if( isSpecialError ){ | | > > > > > > > > > | | 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 | /* Check for one of the special errors */ mrc = p->rc & 0xff; assert( p->rc!=SQLITE_IOERR_BLOCKED ); /* This error no longer exists */ isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR || mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL; if( isSpecialError ){ /* If the query was read-only and the error code is SQLITE_INTERRUPT, ** no rollback is necessary. Otherwise, at least a savepoint ** transaction must be rolled back to restore the database to a ** consistent state. ** ** Even if the statement is read-only, it is important to perform ** a statement or transaction rollback operation. If the error ** occured while writing to the journal, sub-journal or database ** file as part of an effort to free up cache space (see function ** pagerStress() in pager.c), the rollback is required to restore ** the pager to a consistent state. */ if( !p->readOnly || mrc!=SQLITE_INTERRUPT ){ if( (mrc==SQLITE_NOMEM || mrc==SQLITE_FULL) && p->usesStmtJournal ){ eStatementOp = SAVEPOINT_ROLLBACK; }else{ /* We are forced to roll back the active transaction. Before doing ** so, abort any other statements this handle currently has active. |
︙ | ︙ |
Changes to test/lock_common.tcl.
︙ | ︙ | |||
23 24 25 26 27 28 29 30 31 32 33 34 35 36 | set tn 1 } { proc code2 {tcl} { uplevel #0 $tcl } proc code3 {tcl} { uplevel #0 $tcl } set tn 2 }] { faultsim_delete_and_reopen # Open connections [db2] and [db3]. Depending on which iteration this # is, the connections may be created in this interpreter, or in # interpreters running in other OS processes. As such, the [db2] and [db3] # commands should only be accessed within [code2] and [code3] blocks, # respectively. # | > > | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | set tn 1 } { proc code2 {tcl} { uplevel #0 $tcl } proc code3 {tcl} { uplevel #0 $tcl } set tn 2 }] { faultsim_delete_and_reopen proc code1 {tcl} { uplevel #0 $tcl } # Open connections [db2] and [db3]. Depending on which iteration this # is, the connections may be created in this interpreter, or in # interpreters running in other OS processes. As such, the [db2] and [db3] # commands should only be accessed within [code2] and [code3] blocks, # respectively. # |
︙ | ︙ |
Changes to test/pager1.test.
︙ | ︙ | |||
11 12 13 14 15 16 17 | # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl source $testdir/malloc_common.tcl source $testdir/wal_common.tcl | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # set testdir [file dirname $argv0] source $testdir/tester.tcl source $testdir/lock_common.tcl source $testdir/malloc_common.tcl source $testdir/wal_common.tcl # Do not use a codec for tests in this file, as the database file is # manipulated directly using tcl scripts (using the [hexio_write] command). # do_not_use_codec # # pager1-1.*: Test inter-process locking (clients in multiple processes). |
︙ | ︙ | |||
2269 2270 2271 2272 2273 2274 2275 2276 | csql1 { BEGIN; INSERT INTO t1 VALUES('c', 'd'); } } {1 {database is locked}} code2 { db2 close ; sqlite3 db2 test.db } do_test pager1-28.$tn.4 { sql1 { INSERT INTO t1 VALUES('c', 'd'); COMMIT } } {} } finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 | csql1 { BEGIN; INSERT INTO t1 VALUES('c', 'd'); } } {1 {database is locked}} code2 { db2 close ; sqlite3 db2 test.db } do_test pager1-28.$tn.4 { sql1 { INSERT INTO t1 VALUES('c', 'd'); COMMIT } } {} } #------------------------------------------------------------------------- # Normally, when changing from journal_mode=PERSIST to DELETE the pager # attempts to delete the journal file. However, if it cannot obtain a # RESERVED lock on the database file, this step is skipped. # do_multiclient_test tn { do_test pager1-28.$tn.1 { sql1 { PRAGMA journal_mode = PERSIST; CREATE TABLE t1(a, b); INSERT INTO t1 VALUES('a', 'b'); } } {persist} do_test pager1-28.$tn.2 { file exists test.db-journal } 1 do_test pager1-28.$tn.3 { sql1 { PRAGMA journal_mode = DELETE } } delete do_test pager1-28.$tn.4 { file exists test.db-journal } 0 do_test pager1-28.$tn.5 { sql1 { PRAGMA journal_mode = PERSIST; INSERT INTO t1 VALUES('c', 'd'); } } {persist} do_test pager1-28.$tn.6 { file exists test.db-journal } 1 do_test pager1-28.$tn.7 { sql2 { BEGIN; INSERT INTO t1 VALUES('e', 'f'); } } {} do_test pager1-28.$tn.8 { file exists test.db-journal } 1 do_test pager1-28.$tn.9 { sql1 { PRAGMA journal_mode = DELETE } } delete do_test pager1-28.$tn.10 { file exists test.db-journal } 1 do_test pager1-28.$tn.11 { sql2 COMMIT } {} do_test pager1-28.$tn.12 { file exists test.db-journal } 0 do_test pager1-28-$tn.13 { code1 { set channel [db incrblob -readonly t1 a 2] } sql1 { PRAGMA journal_mode = PERSIST; INSERT INTO t1 VALUES('g', 'h'); } } {persist} do_test pager1-28.$tn.14 { file exists test.db-journal } 1 do_test pager1-28.$tn.15 { sql2 { BEGIN; INSERT INTO t1 VALUES('e', 'f'); } } {} do_test pager1-28.$tn.16 { sql1 { PRAGMA journal_mode = DELETE } } delete do_test pager1-28.$tn.17 { file exists test.db-journal } 1 do_test pager1-28.$tn.17 { csql2 { COMMIT } } {1 {database is locked}} do_test pager1-28-$tn.18 { code1 { read $channel } } c do_test pager1-28-$tn.19 { code1 { close $channel } } {} do_test pager1-28.$tn.20 { sql2 { COMMIT } } {} } finish_test |
Changes to test/pager2.test.
︙ | ︙ | |||
114 115 116 117 118 119 120 | } } db close tv delete #------------------------------------------------------------------------- | > | > > < > > > > > > > > > > > > > | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | } } db close tv delete #------------------------------------------------------------------------- # # pager2-2.1: Test a ROLLBACK with journal_mode=off. # pager2-2.2: Test shrinking the database (auto-vacuum) with # journal_mode=off # do_test pager2-2.1 { faultsim_delete_and_reopen execsql { CREATE TABLE t1(a, b); PRAGMA journal_mode = off; BEGIN; INSERT INTO t1 VALUES(1, 2); ROLLBACK; SELECT * FROM t1; } } {off 1 2} do_test pager2-2.2 { faultsim_delete_and_reopen execsql { PRAGMA auto_vacuum = incremental; PRAGMA page_size = 1024; PRAGMA journal_mode = off; CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(zeroblob(5000), zeroblob(5000)); DELETE FROM t1; PRAGMA incremental_vacuum; } file size test.db } {3072} finish_test |
Changes to test/pagerfault.test.
︙ | ︙ | |||
23 24 25 26 27 28 29 30 31 32 33 34 35 36 | set a_string_counter 1 proc a_string {n} { global a_string_counter incr a_string_counter string range [string repeat "${a_string_counter}." $n] 1 $n } db func a_string a_string #------------------------------------------------------------------------- # Test fault-injection while rolling back a hot-journal file. # do_test pagerfault-1-pre1 { execsql { PRAGMA journal_mode = DELETE; | > > | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | set a_string_counter 1 proc a_string {n} { global a_string_counter incr a_string_counter string range [string repeat "${a_string_counter}." $n] 1 $n } db func a_string a_string if 1 { #------------------------------------------------------------------------- # Test fault-injection while rolling back a hot-journal file. # do_test pagerfault-1-pre1 { execsql { PRAGMA journal_mode = DELETE; |
︙ | ︙ | |||
1113 1114 1115 1116 1117 1118 1119 | do_faultsim_test pagerfault-24 -prep { faultsim_delete_and_reopen db eval { PRAGMA temp_store = file } execsql { CREATE TABLE x(a, b) } } -body { execsql { CREATE TEMP TABLE t1(a, b) } } -test { | > | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 | do_faultsim_test pagerfault-24 -prep { faultsim_delete_and_reopen db eval { PRAGMA temp_store = file } execsql { CREATE TABLE x(a, b) } } -body { execsql { CREATE TEMP TABLE t1(a, b) } } -test { faultsim_test_result {0 {}} \ {1 {unable to open a temporary database file for storing temporary tables}} set ic [db eval { PRAGMA temp.integrity_check }] if {$ic != "ok"} { error "Integrity check: $ic" } } } proc lockrows {n} { if {$n==0} { return "" } db eval { SELECT * FROM t1 WHERE oid = $n } { return [lockrows [expr {$n-1}]] } } do_test pagerfault-25-pre1 { faultsim_delete_and_reopen db func a_string a_string execsql { PRAGMA page_size = 1024; PRAGMA auto_vacuum = 0; CREATE TABLE t1(a); INSERT INTO t1 VALUES(a_string(500)); INSERT INTO t1 SELECT a_string(500) FROM t1; INSERT INTO t1 SELECT a_string(500) FROM t1; INSERT INTO t1 SELECT a_string(500) FROM t1; INSERT INTO t1 SELECT a_string(500) FROM t1; INSERT INTO t1 SELECT a_string(500) FROM t1; } faultsim_save_and_close } {} do_faultsim_test pagerfault-25 -faults full -prep { faultsim_restore_and_reopen db func a_string a_string set ::channel [db incrblob -readonly t1 a 1] execsql { PRAGMA cache_size = 10; BEGIN; INSERT INTO t1 VALUES(a_string(3000)); INSERT INTO t1 VALUES(a_string(3000)); } } -body { lockrows 30 } -test { catch { lockrows 30 } close $::channel faultsim_test_result {0 {}} } finish_test |