diff options
author | drh <drh@noemail.net> | 2010-05-06 21:37:22 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2010-05-06 21:37:22 +0000 |
commit | 3ebaee9633db3e3d97cde82922bb50d95e731618 (patch) | |
tree | dc99485ca330d31387f767b08e7f4fd276588b77 /src | |
parent | 72af0774f9a2d75e8e2dccb0fb15626babf8a875 (diff) | |
download | sqlite-3ebaee9633db3e3d97cde82922bb50d95e731618.tar.gz sqlite-3ebaee9633db3e3d97cde82922bb50d95e731618.zip |
The PRAGMA journal_mode=WAL; command now makes WAL the default journal mode
for new databases added with ATTACH, so the behavior is consistent with the
other journal modes.
FossilOrigin-Name: c3520460a4a39fc5e981c3033068ffbb422a4af2
Diffstat (limited to 'src')
-rw-r--r-- | src/attach.c | 13 | ||||
-rw-r--r-- | src/pragma.c | 14 | ||||
-rw-r--r-- | src/vdbe.c | 20 | ||||
-rw-r--r-- | src/vdbeaux.c | 5 |
4 files changed, 43 insertions, 9 deletions
diff --git a/src/attach.c b/src/attach.c index 6f0acef94..2b57793f9 100644 --- a/src/attach.c +++ b/src/attach.c @@ -143,7 +143,8 @@ static void attachFunc( } pPager = sqlite3BtreePager(aNew->pBt); sqlite3PagerLockingMode(pPager, db->dfltLockMode); - sqlite3PagerJournalMode(pPager, db->dfltJournalMode); + /* journal_mode set by the OP_JournalMode opcode that will following + ** the OP_Function opcode that invoked this function. */ sqlite3BtreeSecureDelete(aNew->pBt, sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); } @@ -339,6 +340,16 @@ static void codeAttach( sqlite3VdbeChangeP5(v, (u8)(pFunc->nArg)); sqlite3VdbeChangeP4(v, -1, (char *)pFunc, P4_FUNCDEF); + if( type==SQLITE_ATTACH ){ + /* On an attach, also set the journal mode. Note that + ** sqlite3VdbeUsesBtree() is not call here since the iDb index + ** will be out of range prior to the new database being attached. + ** The OP_JournalMode opcode will all sqlite3VdbeUsesBtree() for us. + */ + sqlite3VdbeAddOp3(v, OP_JournalMode, db->nDb, regArgs+3, + db->dfltJournalMode); + } + /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this ** statement only). For DETACH, set it to false (expire all existing ** statements). diff --git a/src/pragma.c b/src/pragma.c index c3aaaf9b3..d98b68055 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -531,7 +531,8 @@ void sqlite3Pragma( /* ** PRAGMA [database.]journal_mode - ** PRAGMA [database.]journal_mode = (delete|persist|off|truncate|memory) + ** PRAGMA [database.]journal_mode = + ** (delete|persist|off|truncate|memory|wal|off) */ if( sqlite3StrICmp(zLeft,"journal_mode")==0 ){ int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */ @@ -562,15 +563,14 @@ void sqlite3Pragma( }else{ int ii; - if( pId2->n==0 && eMode!=PAGER_JOURNALMODE_WAL ){ - /* This indicates that no database name was specified as part - ** of the PRAGMA command. In this case the journal-mode must be - ** set on all attached databases, as well as the main db file. + if( pId2->n==0 ){ + /* When there is no database name before the "journal_mode" keyword + ** in the PRAGMA, then the journal-mode will be set on + ** all attached databases, as well as the main db file. ** ** Also, the sqlite3.dfltJournalMode variable is set so that ** any subsequently attached databases also use the specified - ** journal mode. Except, the default journal mode is never set - ** to WAL. + ** journal mode. */ db->dfltJournalMode = (u8)eMode; } diff --git a/src/vdbe.c b/src/vdbe.c index a5fe803f0..4e7cedb96 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5227,7 +5227,25 @@ case OP_JournalMode: { /* out2-prerelease */ || eNew==PAGER_JOURNALMODE_QUERY ); assert( pOp->p1>=0 && pOp->p1<db->nDb ); - assert( (p->btreeMask & (1<<pOp->p1))!=0 ); + + /* This opcode is used in two places: PRAGMA journal_mode and ATTACH. + ** In PRAGMA journal_mode, the sqlite3VdbeUsesBtree() routine is called + ** when the statment is prepared and so p->aMutex.nMutex>0. All mutexes + ** are already acquired. But when used in ATTACH, sqlite3VdbeUsesBtree() + ** is not called when the statement is prepared because it requires the + ** iDb index of the database as a parameter, and the database has not + ** yet been attached so that index is unavailable. We have to wait + ** until runtime (now) to get the mutex on the newly attached database. + ** No other mutexes are required by the ATTACH command so this is safe + ** to do. + */ + assert( (p->btreeMask & (1<<pOp->p1))!=0 || p->aMutex.nMutex==0 ); + if( p->aMutex.nMutex==0 ){ + /* This occurs right after ATTACH. Get a mutex on the newly ATTACHed + ** database. */ + sqlite3VdbeUsesBtree(p, pOp->p1); + sqlite3VdbeMutexArrayEnter(p); + } pBt = db->aDb[pOp->p1].pBt; pPager = sqlite3BtreePager(pBt); diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 9aeb50250..155a1ae89 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -950,6 +950,11 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ /* ** Declare to the Vdbe that the BTree object at db->aDb[i] is used. +** +** The prepared statement has to know in advance which Btree objects +** will be used so that it can acquire mutexes on them all in sorted +** order (via sqlite3VdbeMutexArrayEnter(). Mutexes are acquired +** in order (and released in reverse order) to avoid deadlocks. */ void sqlite3VdbeUsesBtree(Vdbe *p, int i){ int mask; |