diff --git a/manifest b/manifest index 2c8cfd4c57..eb30806edf 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sfor\s#2451.\sCode\scomment\schanges\sonly.\s(CVS\s4114) -D 2007-06-24T16:11:03 +C Make\sthe\sauto_vacuum\smode\speristent\sin\sall\scases.\s(CVS\s4115) +D 2007-06-25T08:16:58 F Makefile.in 7f7485a4cc039476a42e534b3f26ec90e2f9753e F Makefile.linux-gcc 2d8574d1ba75f129aba2019f0b959db380a90935 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -65,7 +65,7 @@ F src/alter.c 1b1deeb97446ed87f2fa17a3eb6236548841a348 F src/analyze.c 8d345472e0f4e44fc88f5cf489c16dcb77904525 F src/attach.c ba628db0c2b6a362f036d017bf1196cdfe4ebb37 F src/auth.c 5ea90bc93dfea46e9fe4bf531e14c7cd98219ecb -F src/btree.c 63d40146c74499b8119ce4772b27210c7830313e +F src/btree.c 4a282b7f8746bec2a3f59b03eee7c4046a345607 F src/btree.h 1d527bf61ed176f980c34999d5793a0fd45dcf8c F src/btreeInt.h ac1ab1fb624ffbe571786cd2bd9559f9ae336355 F src/build.c 50992d92e131a9aa9aa6657fb1ddc13e176fd70c @@ -99,7 +99,7 @@ F src/os_win.h 41a946bea10f61c158ce8645e7646b29d44f122b F src/pager.c 39352b58ee840cae715a4f0d20e446aa5e1445fe F src/pager.h 94110a5570dca30d54a883e880a3633b2e4c05ae F src/parse.y ad2ce25665be7f7303137f774a4e3e72e0d036ff -F src/pragma.c d2e6f5da991594e1c2c7636927f6be7cf66e81bd +F src/pragma.c 838f7460e6f228cc80cd10846ee1139f3ae723dd F src/prepare.c 609bb27860ce98ab39889fecc0998dfd8220891b F src/printf.c 9b3048d270e8bb2f8b910b491ac3aadece6cfab2 F src/random.c 6119474a6f6917f708c1dee25b9a8e519a620e88 @@ -176,7 +176,7 @@ F test/bigrow.test f0aeb7573dcb8caaafea76454be3ade29b7fc747 F test/bind.test 261fd1603613e7f877a516d29f281c9d8c2ecf52 F test/bindxfer.test b9a57f66dbd317feeefa28bd65b6576f1592ee98 F test/blob.test 28c3b25150684ee3d108bb78cfb67a472deef2f0 -F test/btree.test 8b6168980efdd194289798f19d4c81434f6d3a66 +F test/btree.test d394f22b03712f05fca9c59f6f4848a3cad01379 F test/btree2.test 4b56a2a4a4f84d68c77aef271223a713bf5ebafc F test/btree4.test 3797b4305694c7af6828675b0f4b1424b8ca30e4 F test/btree5.test 8e5ff32c02e685d36516c6499add9375fe1377f2 @@ -267,7 +267,7 @@ F test/in.test 369cb2aa1eab02296b4ec470732fe8c131260b1d F test/in2.test b1f447f4f0f67e9f83ff931e7e2e30873f9ea055 F test/incrblob.test a23b9431596581f1f4ac03d04fa97c31776693d5 F test/incrblob_err.test 2501bec57e317e7051451b5093b47fc61a96c85a -F test/incrvacuum.test 433fbe59b4a77d50117adaef66b6dca52f611179 +F test/incrvacuum.test 92d0efe609509c65804be016cb376d5ec5abb5a5 F test/incrvacuum2.test 82397ceb5941cbe852fd29bb33fcdf5665bc80c2 F test/incrvacuum_ioerr.test cb331403b8dea3c5bae6163861ff25037b0df56a F test/index.test e65df12bed94b2903ee89987115e1578687e9266 @@ -514,7 +514,7 @@ F www/tclsqlite.tcl 8be95ee6dba05eabcd27a9d91331c803f2ce2130 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl 890248cf7b70e60c383b0e84d77d5132b3ead42b F www/whentouse.tcl fc46eae081251c3c181bd79c5faef8195d7991a5 -P c666fad151f25ab8365c497cd0967f4a5a2adb90 -R 55510efe85475a231257ad94221f8a4a +P bc61dcbf64af56d4a1394c8ff46e91245dc16d15 +R ad646b50fb78ca315c96e2f2605f5241 U danielk1977 -Z 19b49e3d7d8dd1d009e5f547530e18f8 +Z 7178761d0ea9f7ce5c978317ce1d9a00 diff --git a/manifest.uuid b/manifest.uuid index cc8bfeeff5..8bd02923a5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bc61dcbf64af56d4a1394c8ff46e91245dc16d15 \ No newline at end of file +5b0408ddd0f1c825f402d0f5a3088a61b5ecd2c3 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 5febf4e865..7591f9f97d 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.390 2007/06/24 10:14:00 danielk1977 Exp $ +** $Id: btree.c,v 1.391 2007/06/25 08:16:58 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. @@ -1362,12 +1362,10 @@ int sqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){ #else BtShared *pBt = p->pBt; int av = (autoVacuum?1:0); - int iv = (autoVacuum==BTREE_AUTOVACUUM_INCR?1:0); if( pBt->pageSizeFixed && av!=pBt->autoVacuum ){ return SQLITE_READONLY; } pBt->autoVacuum = av; - pBt->incrVacuum = iv; return SQLITE_OK; #endif } @@ -1436,6 +1434,7 @@ static int lockBtree(BtShared *pBt){ pBt->minLeafFrac = page1[23]; #ifndef SQLITE_OMIT_AUTOVACUUM pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0); + pBt->incrVacuum = (get4byte(&page1[36 + 7*4])?1:0); #endif } @@ -5679,6 +5678,11 @@ int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){ rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); if( rc ) return rc; put4byte(&pP1[36 + idx*4], iMeta); + if( idx==7 ){ + assert( pBt->autoVacuum || iMeta==0 ); + assert( iMeta==0 || iMeta==1 ); + pBt->incrVacuum = iMeta; + } return SQLITE_OK; } diff --git a/src/pragma.c b/src/pragma.c index 125f3f2a62..f6c1aa28e8 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** -** $Id: pragma.c,v 1.140 2007/06/24 08:00:43 danielk1977 Exp $ +** $Id: pragma.c,v 1.141 2007/06/25 08:16:58 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" @@ -424,6 +424,9 @@ void sqlite3Pragma( #ifndef SQLITE_OMIT_AUTOVACUUM if( sqlite3StrICmp(zLeft,"auto_vacuum")==0 ){ Btree *pBt = pDb->pBt; + if( sqlite3ReadSchema(pParse) ){ + goto pragma_out; + } if( !zRight ){ int auto_vacuum = pBt ? sqlite3BtreeGetAutoVacuum(pBt) : SQLITE_DEFAULT_AUTOVACUUM; @@ -431,7 +434,34 @@ void sqlite3Pragma( }else{ int eAuto = getAutoVacuum(zRight); if( eAuto>=0 ){ - sqlite3BtreeSetAutoVacuum(pBt, eAuto); + /* Call SetAutoVacuum() to set initialize the internal auto and + ** incr-vacuum flags. This is required in case this connection + ** creates the database file. It is important that it is created + ** as an auto-vacuum capable db. + */ + int rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto); + if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){ + /* When setting the auto_vacuum mode to either "full" or + ** "incremental", write the value of meta[6] in the database + ** file. Before writing to meta[6], check that meta[3] indicates + ** that this really is an auto-vacuum capable database. + */ + static const VdbeOpList setMeta6[] = { + { OP_Transaction, 0, 1, 0}, /* 0 */ + { OP_ReadCookie, 0, 3, 0}, /* 1 */ + { OP_If, 0, 0, 0}, /* 2 */ + { OP_Halt, SQLITE_OK, OE_Abort, 0}, /* 3 */ + { OP_Integer, 0, 0, 0}, /* 4 */ + { OP_SetCookie, 0, 6, 0}, /* 5 */ + }; + int iAddr; + iAddr = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6); + sqlite3VdbeChangeP1(v, iAddr, iDb); + sqlite3VdbeChangeP1(v, iAddr+1, iDb); + sqlite3VdbeChangeP2(v, iAddr+2, iAddr+4); + sqlite3VdbeChangeP1(v, iAddr+4, eAuto-1); + sqlite3VdbeChangeP1(v, iAddr+5, iDb); + } } } }else diff --git a/test/btree.test b/test/btree.test index a08e128162..dcd545bb0b 100644 --- a/test/btree.test +++ b/test/btree.test @@ -11,7 +11,7 @@ # This file implements regression tests for SQLite library. The # focus of this script is btree database backend # -# $Id: btree.test,v 1.39 2007/04/04 01:27:44 drh Exp $ +# $Id: btree.test,v 1.40 2007/06/25 08:16:58 danielk1977 Exp $ set testdir [file dirname $argv0] @@ -393,13 +393,13 @@ do_test btree-5.2 { do_test btree-5.3 { btree_begin_transaction $::b1 set rc [catch { - btree_update_meta $::b1 0 1 2 3 0 5 6 7 8 9 + btree_update_meta $::b1 0 1 2 3 0 5 6 0 8 9 } msg] lappend rc $msg } {0 {}} do_test btree-5.4 { btree_get_meta $::b1 -} {0 1 2 3 0 5 6 7 8 9} +} {0 1 2 3 0 5 6 0 8 9} do_test btree-5.5 { btree_close_cursor $::c1 btree_rollback $::b1 @@ -407,10 +407,10 @@ do_test btree-5.5 { } {0 0 0 0 0 0 0 0 0 0} do_test btree-5.6 { btree_begin_transaction $::b1 - btree_update_meta $::b1 0 10 20 30 0 50 60 70 80 90 + btree_update_meta $::b1 0 10 20 30 0 50 60 0 80 90 btree_commit $::b1 btree_get_meta $::b1 -} {0 10 20 30 0 50 60 70 80 90} +} {0 10 20 30 0 50 60 0 80 90} proc select_all {cursor} { set r {} diff --git a/test/incrvacuum.test b/test/incrvacuum.test index b0a688009a..53e86ff79f 100644 --- a/test/incrvacuum.test +++ b/test/incrvacuum.test @@ -14,7 +14,7 @@ # Note: There are also some tests for incremental vacuum and IO # errors in incrvacuum_ioerr.test. # -# $Id: incrvacuum.test,v 1.11 2007/06/24 10:14:00 danielk1977 Exp $ +# $Id: incrvacuum.test,v 1.12 2007/06/25 08:16:58 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -34,12 +34,19 @@ do_test incrvacuum-1.1 { pragma auto_vacuum; } } $sqlite_options(default_autovacuum) +do_test incrvacuum-1.2.0 { + expr {[file size test.db] > 0} +} {0} do_test incrvacuum-1.2 { + # This command will create the database. execsql { pragma auto_vacuum = 'full'; pragma auto_vacuum; } } {1} +do_test incrvacuum-1.2.1 { + expr {[file size test.db] > 0} +} {1} do_test incrvacuum-1.3 { execsql { pragma auto_vacuum = 'incremental'; @@ -47,11 +54,13 @@ do_test incrvacuum-1.3 { } } {2} do_test incrvacuum-1.4 { + # In this case the invalid value is ignored and the auto_vacuum + # setting remains unchanged. execsql { pragma auto_vacuum = 'invalid'; pragma auto_vacuum; } -} {0} +} {2} do_test incrvacuum-1.5 { execsql { pragma auto_vacuum = 1; @@ -65,11 +74,12 @@ do_test incrvacuum-1.6 { } } {2} do_test incrvacuum-1.7 { + # Invalid value. auto_vacuum setting remains unchanged. execsql { pragma auto_vacuum = 5; pragma auto_vacuum; } -} {0} +} {2} #--------------------------------------------------------------------- # Test the pragma on a non-empty database. It is possible to toggle @@ -579,12 +589,10 @@ do_test incrvacuum-11.3 { } } {2} do_test incrvacuum-11.4 { - file size test.db -} {0} + # The database has now been created. + expr {[file size test.db]>0} +} {1} do_test incrvacuum-11.5 { - # Create the database file. - execsql { CREATE TABLE abc(a, b, c); } - # Close and reopen the connection. db close sqlite3 db test.db @@ -603,9 +611,79 @@ do_test incrvacuum-11.7 { db close sqlite3 db test.db - # Test we are still in incremental vacuum mode. + # Test we are still in "full" auto-vacuum mode. execsql { PRAGMA auto_vacuum; } -} {2} +} {1} +#---------------------------------------------------------------------- +# Special case: What happens if the database is locked when a "PRAGMA +# auto_vacuum = XXX" statement is executed. +# +db close +file delete -force test.db test.db-journal +sqlite3 db test.db + +do_test incrvacuum-12.1 { + execsql { + PRAGMA auto_vacuum = 1; + } + expr {[file size test.db]>0} +} {1} + +# Try to change the auto-vacuum from "full" to "incremental" while the +# database is locked. Nothing should change. +# +do_test incrvacuum-12.2 { + sqlite3 db2 test.db + execsql { BEGIN EXCLUSIVE; } db2 + catchsql { PRAGMA auto_vacuum = 2; } +} {1 {database is locked}} + +do_test incrvacuum-12.3 { + execsql { ROLLBACK; } db2 + execsql { PRAGMA auto_vacuum } +} {1} + +do_test incrvacuum-12.3 { + execsql { SELECT * FROM sqlite_master } + execsql { PRAGMA auto_vacuum } +} {1} + +#---------------------------------------------------------------------- +# Special case #2: What if one process prepares a "PRAGMA auto_vacuum = XXX" +# statement when the database is empty, but doesn't execute it until +# after some other process has created the database. +# +db2 close +db close +file delete -force test.db test.db-journal +sqlite3 db test.db ; set ::DB [sqlite3_connection_pointer db] +sqlite3 db2 test.db + +do_test incrvacuum-13.1 { + expr {[file size test.db]>0} +} {0} +do_test incrvacuum-13.2 { + set ::STMT [sqlite3_prepare $::DB {PRAGMA auto_vacuum = 2} -1 DUMMY] + execsql { + PRAGMA auto_vacuum = none; + PRAGMA default_cache_size = 1024; + PRAGMA auto_vacuum; + } db2 +} {0} +do_test incrvacuum-13.3 { + expr {[file size test.db]>0} +} {1} +do_test incrvacuum-13.4 { + set rc [sqlite3_step $::STMT] + list $rc [sqlite3_finalize $::STMT] +} {SQLITE_DONE SQLITE_OK} +do_test incrvacuum-13.5 { + execsql { + PRAGMA auto_vacuum; + } +} {0} + +db2 close finish_test