Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix issues with the io.test script. There is still a problem with a ROLLBACK TO not working on an initially empty database files. And much more testing is needed. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | experimental |
Files: | files | file ages | folders |
SHA1: |
09786e2a51817d572a01ae7f3621f03f |
User & Date: | drh 2010-03-29 19:36:52.000 |
Context
2010-03-29
| ||
21:13 | The btree layer now tracks when a database is empty at the start of a transaction and rolls back to that state. (Closed-Leaf check-in: 01ef6c1944 user: drh tags: experimental) | |
19:36 | Fix issues with the io.test script. There is still a problem with a ROLLBACK TO not working on an initially empty database files. And much more testing is needed. (check-in: 09786e2a51 user: drh tags: experimental) | |
2010-03-27
| ||
17:12 | Experimental changes that cause SQLite to use bytes 28..31 of the database header to determine the database size, rather than using the actual database size. This allows database space to be preallocated. (check-in: b844ac6fcb user: drh tags: experimental) | |
Changes
Changes to src/btree.c.
︙ | ︙ | |||
3228 3229 3230 3231 3232 3233 3234 | int rc; BtShared *pBt = p->pBt; sqlite3BtreeEnter(p); assert( p->inTrans==TRANS_WRITE ); assert( pBt->readOnly==0 ); assert( iStatement>0 ); assert( iStatement>p->db->nSavepoint ); | < < < | | | | | | | < | 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 | int rc; BtShared *pBt = p->pBt; sqlite3BtreeEnter(p); assert( p->inTrans==TRANS_WRITE ); assert( pBt->readOnly==0 ); assert( iStatement>0 ); assert( iStatement>p->db->nSavepoint ); assert( pBt->inTransaction==TRANS_WRITE ); /* At the pager level, a statement transaction is a savepoint with ** an index greater than all savepoints created explicitly using ** SQL statements. It is illegal to open, release or rollback any ** such savepoints while the statement transaction savepoint is active. */ rc = sqlite3PagerOpenSavepoint(pBt->pPager, iStatement); sqlite3BtreeLeave(p); return rc; } /* ** The second argument to this function, op, is always SAVEPOINT_ROLLBACK ** or SAVEPOINT_RELEASE. This function either releases or rolls back the |
︙ | ︙ | |||
4844 4845 4846 4847 4848 4849 4850 | /* If *pPgno refers to a pointer-map page, allocate two new pages ** at the end of the file instead of one. The first allocated page ** becomes a new pointer-map page, the second is used by the caller. */ MemPage *pPg = 0; TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage)); assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) ); | | | | 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 | /* If *pPgno refers to a pointer-map page, allocate two new pages ** at the end of the file instead of one. The first allocated page ** becomes a new pointer-map page, the second is used by the caller. */ MemPage *pPg = 0; TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage)); assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) ); rc = btreeGetPage(pBt, pBt->nPage, &pPg, 1); if( rc==SQLITE_OK ){ rc = sqlite3PagerWrite(pPg->pDbPage); releasePage(pPg); } if( rc ) return rc; pBt->nPage++; if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ){ pBt->nPage++; } } #endif put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage); *pPgno = pBt->nPage; assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); rc = btreeGetPage(pBt, *pPgno, ppPage, 1); if( rc ) return rc; rc = sqlite3PagerWrite((*ppPage)->pDbPage); if( rc!=SQLITE_OK ){ releasePage(*ppPage); } TRACE(("ALLOCATE: %d from end of file\n", *pPgno)); } |
︙ | ︙ |
Changes to test/io.test.
︙ | ︙ | |||
196 197 198 199 200 201 202 203 204 | # Test that the journal file is created and sync()d if the transaction # modifies a single database page and also appends a page to the file. # Internally, this case is handled differently to the one above. The # journal file is not actually created until the 'COMMIT' statement # is executed. # do_test io-2.6.1 { execsql { | > > > > > > | | | > > > | | 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | # Test that the journal file is created and sync()d if the transaction # modifies a single database page and also appends a page to the file. # Internally, this case is handled differently to the one above. The # journal file is not actually created until the 'COMMIT' statement # is executed. # # Changed 2010-03-27: The size of the database is now stored in # bytes 28..31 and so when a page is added to the database, page 1 # is immediately modified and the journal file immediately comes into # existance. To fix this test, the BEGIN is changed into a a # BEGIN IMMEDIATE and the INSERT is omitted. # do_test io-2.6.1 { execsql { BEGIN IMMEDIATE; -- INSERT INTO abc VALUES(9, randstr(1000,1000)); } file exists test.db-journal } {0} do_test io-2.6.2 { # Create a file at "test.db-journal". This will prevent SQLite from # opening the journal for exclusive access. As a result, the COMMIT # should fail with SQLITE_CANTOPEN and the transaction rolled back. # file mkdir test.db-journal catchsql { INSERT INTO abc VALUES(9, randstr(1000,1000)); COMMIT } } {1 {unable to open database file}} do_test io-2.6.3 { file delete -force test.db-journal catchsql { COMMIT } } {0 {}} do_test io-2.6.4 { execsql { SELECT * FROM abc } } {1 2 3 4 5 6 7 8} # Test that if the database modification is part of multi-file commit, # the journal file is always created. In this case, the journal file # is created during execution of the COMMIT statement, so we have to |
︙ | ︙ |