aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2010-05-06 21:37:22 +0000
committerdrh <drh@noemail.net>2010-05-06 21:37:22 +0000
commit3ebaee9633db3e3d97cde82922bb50d95e731618 (patch)
treedc99485ca330d31387f767b08e7f4fd276588b77 /src
parent72af0774f9a2d75e8e2dccb0fb15626babf8a875 (diff)
downloadsqlite-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.c13
-rw-r--r--src/pragma.c14
-rw-r--r--src/vdbe.c20
-rw-r--r--src/vdbeaux.c5
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;