diff --git a/manifest b/manifest index 9be67451d2..dab32989d7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sCREATE\sTABLE\sto\soccur\swhile\sother\squeries\sare\srunning.\s\sDROP\sTABLE\sis\nstill\sprohibited,\showever,\ssince\swe\sdo\snot\swant\sto\sdelete\sa\stable\sout\nfrom\sunder\san\srunning\squery.\s(CVS\s3902) -D 2007-05-02T17:54:56 +C Minor\sbugfixes\sfor\sincrblob\smode.\s(CVS\s3903) +D 2007-05-03T11:43:33 F Makefile.in 8cab54f7c9f5af8f22fd97ddf1ecfd1e1860de62 F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -59,7 +59,7 @@ F src/alter.c 2c79ec40f65e33deaf90ca493422c74586e481a3 F src/analyze.c 4bbf5ddf9680587c6d4917e02e378b6037be3651 F src/attach.c a16ada4a4654a0d126b8223ec9494ebb81bc5c3c F src/auth.c 902f4722661c796b97f007d9606bd7529c02597f -F src/btree.c a84c848ee737354441ab443ccc50710e34dcac62 +F src/btree.c ae37926682a6e6da49dacad25a8da50b49abbc31 F src/btree.h 2c187d60cf76d74c2b4767294d6b5fa267037ff0 F src/build.c 02e01ec7907c7d947ab3041fda0e81eaed05db42 F src/callback.c 6414ed32d55859d0f65067aa5b88d2da27b3af9e @@ -130,7 +130,7 @@ F src/vdbe.h 0025259af1939fb264a545816c69e4b5b8d52691 F src/vdbeInt.h cb02cbbceddf3b40d49012e9f41576f17bcbec97 F src/vdbeapi.c 37d793559390bec8a00c556f651f21b5f9e589af F src/vdbeaux.c 8c7f22e22d1ea578971f5a3fcd3a56a6882ced64 -F src/vdbeblob.c 396148feb5917e666edfb643f259f185051351b4 +F src/vdbeblob.c 0e070ded61b5db6ac55085d542bda5c2ee9e1a5f F src/vdbefifo.c 3ca8049c561d5d67cbcb94dc909ae9bb68c0bf8f F src/vdbemem.c ba98f8572ec4609846b368fa7580db178022f1bb F src/vtab.c 89a0d5f39c1beba65a77fdb4d507b831fc5e6baf @@ -242,7 +242,7 @@ F test/fts2n.test a70357e72742681eaebfdbe9007b87ff3b771638 F test/func.test 6727c7729472ae52b5acd86e802f89aa350ba50f F test/hook.test 7e7645fd9a033f79cce8fdff151e32715e7ec50a F test/in.test 369cb2aa1eab02296b4ec470732fe8c131260b1d -F test/incrblob.test 09db22f90137dc4f449cf6c7f8e554156fb68fd2 +F test/incrblob.test e86fbd7187109a322acb756df64802247ac05ae6 F test/incrvacuum.test 2173bc075c7b3b96ccf228d737dd4f5c29500dc4 F test/incrvacuum_ioerr.test 0ebc382bcc2036ec58cf49cc5ffada45f75d907b F test/index.test e65df12bed94b2903ee89987115e1578687e9266 @@ -472,7 +472,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P a100a5304b0e7cbbdb6dac71a39c78eb71d44a03 -R c9f54fc44781d76345fb394cf6f2ebe4 -U drh -Z 2dba2ac56ac693c05f71eb4014af1de4 +P 5b4bf1fce4d589337cfb1b46d75c751bbdc607d5 +R b6ef9d6353faa34f0c7bbdd7931d71b1 +U danielk1977 +Z 292eae4f6ebc53deece1b93e6958239a diff --git a/manifest.uuid b/manifest.uuid index 6da7e5c454..2343eaab9f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5b4bf1fce4d589337cfb1b46d75c751bbdc607d5 \ No newline at end of file +db54a9466e3bea9c03740ce0b755cfa02bafaccd \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 6e59747783..4c433a085e 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.368 2007/05/02 17:54:56 drh Exp $ +** $Id: btree.c,v 1.369 2007/05/03 11:43:33 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -3105,7 +3105,7 @@ static int getOverflowPage( iGuess++; } - if( iGuesspPager) ){ + if( iGuess<=sqlite3PagerPagecount(pBt->pPager) ){ rc = ptrmapGet(pBt, iGuess, &eType, &pgno); if( rc!=SQLITE_OK ){ return rc; @@ -5763,6 +5763,19 @@ int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){ Pgno pgnoMove; /* Move a page here to make room for the root-page */ MemPage *pPageMove; /* The page to move to. */ +#ifndef SQLITE_OMIT_INCRBLOB + /* Creating a new table may probably require moving an existing database + ** to make room for the new tables root page. In case this page turns + ** out to be an overflow page, delete all overflow page-map caches + ** held by open cursors. + */ + BtCursor *pCur; + for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ + sqliteFree(pCur->aOverflow); + pCur->aOverflow = 0; + } +#endif + /* Read the value of meta[3] from the database to determine where the ** root page of the new table should go. meta[3] is the largest root-page ** created so far, so the new root-page is (meta[3]+1). @@ -6943,17 +6956,6 @@ int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){ */ int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, const void *z){ BtShared *pBt = pCsr->pBtree->pBt; - int rc; - - u32 iRem = amt; /* Remaining bytes to write */ - u8 *zRem = (u8 *)z; /* Pointer to data not yet written */ - u32 iOffset = offset; /* Offset from traversal point to start of write */ - - Pgno iIdx = 0; /* Index of overflow page in pCsr->aOverflow */ - Pgno iOvfl; /* Page number for next overflow page */ - int ovflSize; /* Bytes of data per overflow page. */ - - CellInfo *pInfo; /* Check some preconditions: ** (a) a write-transaction is open, diff --git a/src/vdbeblob.c b/src/vdbeblob.c index 711802b9f6..7c55a635b9 100644 --- a/src/vdbeblob.c +++ b/src/vdbeblob.c @@ -10,7 +10,7 @@ ** ************************************************************************* ** -** $Id: vdbeblob.c,v 1.2 2007/05/02 16:48:37 danielk1977 Exp $ +** $Id: vdbeblob.c,v 1.3 2007/05/03 11:43:33 danielk1977 Exp $ */ #include "sqliteInt.h" @@ -91,11 +91,17 @@ int sqlite3_blob_open( memset(&sParse, 0, sizeof(Parse)); sParse.db = db; + rc = sqlite3SafetyOn(db); + if( rc!=SQLITE_OK ){ + return rc; + } + pTab = sqlite3LocateTable(&sParse, zTable, zDb); if( !pTab ){ sqlite3Error(db, sParse.rc, "%s", sParse.zErrMsg); sqliteFree(sParse.zErrMsg); rc = sParse.rc; + sqlite3SafetyOff(db); goto blob_open_out; } @@ -109,6 +115,7 @@ int sqlite3_blob_open( sqlite3Error(db, SQLITE_ERROR, "no such column: %s", zColumn); sqliteFree(sParse.zErrMsg); rc = SQLITE_ERROR; + sqlite3SafetyOff(db); goto blob_open_out; } @@ -145,6 +152,11 @@ int sqlite3_blob_open( sqlite3VdbeMakeReady(v, 1, 0, 1, 0); } + rc = sqlite3SafetyOff(db); + if( rc!=SQLITE_OK ){ + return rc; + } + sqlite3_bind_int64((sqlite3_stmt *)v, 1, iRow); rc = sqlite3_step((sqlite3_stmt *)v); if( rc!=SQLITE_ROW ){ diff --git a/test/incrblob.test b/test/incrblob.test index 176e61e67c..a5b244b13f 100644 --- a/test/incrblob.test +++ b/test/incrblob.test @@ -9,7 +9,8 @@ # #*********************************************************************** # -# $Id: incrblob.test,v 1.2 2007/05/02 13:16:31 danielk1977 Exp $ +# $Id: incrblob.test,v 1.3 2007/05/03 11:43:35 danielk1977 Exp $ +# set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -49,34 +50,90 @@ do_test incrblob-1.2.6 { } {1234567890} #-------------------------------------------------------------------- -# Test cases incrblob-2.X check that it is possible to read and write +# Test cases incrblob-1.3.X check that it is possible to read and write # regions of a blob that lie on overflow pages. -do_test incrblob-2.1 { +# +do_test incrblob-1.3.1 { set ::str "[string repeat . 10000]" execsql { INSERT INTO blobs(rowid, k, v) VALUES(3, 'three', $::str); } } {} -do_test incrblob-2.2 { +do_test incrblob-1.3.2 { set ::blob [db incrblob blobs v 3] seek $::blob 8500 read $::blob 10 } {..........} - -do_test incrblob-2.3 { +do_test incrblob-1.3.3 { seek $::blob 8500 puts -nonewline $::blob 1234567890 } {} - -do_test incrblob-2.4 { +do_test incrblob-1.3.4 { seek $::blob 8496 read $::blob 10 } {....123456} - -do_test incrblob-2.10 { +do_test incrblob-1.3.10 { close $::blob } {} -finish_test +#------------------------------------------------------------------------ +# incrblob-2.*: Test seeking in an incremental blob can use ptrmap pages. +# +proc nRead {db} { + set bt [btree_from_db $db] + array set stats [btree_pager_stats $bt] + return $stats(read) +} + +foreach AutoVacuumMode [list 0 1] { + + db close + file delete -force test.db test.db-journal + + sqlite3 db test.db + execsql "PRAGMA auto_vacuum = $AutoVacuumMode" + + do_test incrblob-2.$AutoVacuumMode.1 { + set ::str [string repeat abcdefghij 2900] + execsql { + BEGIN; + CREATE TABLE blobs(k PRIMARY KEY, v BLOB); + DELETE FROM blobs; + INSERT INTO blobs VALUES('one', $::str || randstr(500,500)); + COMMIT; + } + expr [file size test.db]/1024 + } [expr 31 + $AutoVacuumMode] + + do_test incrblob-2.$AutoVacuumMode.2 { + execsql { + PRAGMA auto_vacuum; + } + } $AutoVacuumMode + + do_test incrblob-2.$AutoVacuumMode.3 { + # Open and close the db to make sure the page cache is empty. + db close + sqlite3 db test.db + + # Read the last 20 bytes of the blob via a blob handle. + set ::blob [db incrblob blobs v 1] + seek $::blob -20 end + set ::fragment [read $::blob] + close $::blob + + # If the database is not in auto-vacuum mode, the whole of + # the overflow-chain must be scanned. In auto-vacuum mode, + # sqlite uses the ptrmap pages to avoid reading the other pages. + # + nRead db + } [expr $AutoVacuumMode ? 4 : 30] + + do_test incrblob-2.3 { + string range [db one {SELECT v FROM blobs}] end-19 end + } $::fragment +} + +finish_test