Index: src/attach.c ================================================================== --- src/attach.c +++ src/attach.c @@ -156,10 +156,11 @@ } pPager = sqlite3BtreePager(aNew->pBt); sqlite3PagerLockingMode(pPager, db->dfltLockMode); sqlite3BtreeSecureDelete(aNew->pBt, sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); + sqlite3BtreeSetPagerFlags(aNew->pBt, 3 | (db->flags & PAGER_FLAGS_MASK)); } aNew->safety_level = 3; aNew->zName = sqlite3DbStrDup(db, zName); if( rc==SQLITE_OK && aNew->zName==0 ){ rc = SQLITE_NOMEM; Index: src/pragma.c ================================================================== --- src/pragma.c +++ src/pragma.c @@ -155,10 +155,38 @@ sqlite3VdbeAddOp4(v, OP_Int64, 0, mem, 0, (char*)pI64, P4_INT64); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC); sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1); } + + +/* +** Set the safety_level and pager flags for pager iDb. Or if iDb<0 +** set these values for all pagers. +*/ +#ifndef SQLITE_OMIT_PAGER_PRAGMAS +static void setAllPagerFlags(sqlite3 *db){ + if( db->autoCommit ){ + Db *pDb = db->aDb; + int n = db->nDb; + assert( SQLITE_FullFSync==PAGER_FULLFSYNC ); + assert( SQLITE_CkptFullFSync==PAGER_CKPT_FULLFSYNC ); + assert( SQLITE_CacheSpill==PAGER_CACHESPILL ); + assert( (PAGER_FULLFSYNC | PAGER_CKPT_FULLFSYNC | PAGER_CACHESPILL) + == PAGER_FLAGS_MASK ); + assert( (pDb->safety_level & PAGER_SYNCHRONOUS_MASK)==pDb->safety_level ); + while( (n--) > 0 ){ + if( pDb->pBt ){ + sqlite3BtreeSetPagerFlags(pDb->pBt, + pDb->safety_level | (db->flags & PAGER_FLAGS_MASK) ); + } + pDb++; + } + } +} +#endif + #ifndef SQLITE_OMIT_FLAG_PRAGMAS /* ** Check to see if zRight and zLeft refer to a pragma that queries ** or changes one of the flags in db->flags. Return 1 if so and 0 if not. @@ -965,19 +993,19 @@ if( !db->autoCommit ){ sqlite3ErrorMsg(pParse, "Safety level may not be changed inside a transaction"); }else{ pDb->safety_level = getSafetyLevel(zRight,0,1)+1; + setAllPagerFlags(db); } } }else #endif /* SQLITE_OMIT_PAGER_PRAGMAS */ #ifndef SQLITE_OMIT_FLAG_PRAGMAS if( flagPragma(pParse, zLeft, zRight) ){ - /* The flagPragma() subroutine also generates any necessary code - ** there is nothing more to do here */ + setAllPagerFlags(db); }else #endif /* SQLITE_OMIT_FLAG_PRAGMAS */ #ifndef SQLITE_OMIT_SCHEMA_PRAGMAS /* @@ -1804,27 +1832,11 @@ #endif {/* Empty ELSE clause */} - /* - ** Reset the safety level, in case the fullfsync flag or synchronous - ** setting changed. - */ -#ifndef SQLITE_OMIT_PAGER_PRAGMAS - if( db->autoCommit ){ - assert( (pDb->safety_level & PAGER_SYNCHRONOUS_MASK)==pDb->safety_level ); - assert( SQLITE_FullFSync==PAGER_FULLFSYNC ); - assert( SQLITE_CkptFullFSync==PAGER_CKPT_FULLFSYNC ); - assert( SQLITE_CacheSpill==PAGER_CACHESPILL ); - assert( (PAGER_FULLFSYNC | PAGER_CKPT_FULLFSYNC | PAGER_CACHESPILL) - == PAGER_FLAGS_MASK ); - sqlite3BtreeSetPagerFlags(pDb->pBt, - pDb->safety_level | (db->flags & PAGER_FLAGS_MASK) ); - } -#endif pragma_out: sqlite3DbFree(db, zLeft); sqlite3DbFree(db, zRight); } #endif /* SQLITE_OMIT_PRAGMA */ Index: test/pragma2.test ================================================================== --- test/pragma2.test +++ test/pragma2.test @@ -119,10 +119,11 @@ # Default setting of PRAGMA cache_spill is always ON # db close delete_file test.db test.db-journal +delete_file test2.db test2.db-journal sqlite3 db test.db do_execsql_test pragma2-4.1 { PRAGMA cache_spill; PRAGMA main.cache_spill; PRAGMA temp.cache_spill; @@ -145,10 +146,14 @@ INSERT INTO t1 SELECT a+8, randomblob(400), a+8, randomblob(400) FROM t1; INSERT INTO t1 SELECT a+16, randomblob(400), a+16, randomblob(400) FROM t1; INSERT INTO t1 SELECT a+32, randomblob(400), a+32, randomblob(400) FROM t1; INSERT INTO t1 SELECT a+64, randomblob(400), a+64, randomblob(400) FROM t1; COMMIT; + ATTACH 'test2.db' AS aux1; + CREATE TABLE aux1.t2(a INTEGER PRIMARY KEY, b, c, d); + INSERT INTO t2 SELECT * FROM t1; + DETACH aux1; PRAGMA cache_spill=ON; } {} do_test pragma2-4.4 { db eval { BEGIN; @@ -163,7 +168,27 @@ BEGIN; UPDATE t1 SET c=c-1; PRAGMA lock_status; } } {main reserved temp unknown} ;# No cache spill, so no exclusive lock + +# Verify that newly attached databases inherit the cache_spill=OFF +# setting. +# +do_execsql_test pragma2-4.6 { + COMMIT; + ATTACH 'test2.db' AS aux1; + PRAGMA aux1.cache_size=50; + BEGIN; + UPDATE t2 SET c=c+1; + PRAGMA lock_status; +} {main unlocked temp unknown aux1 reserved} +do_execsql_test pragma2-4.7 { + COMMIT; + PRAGMA cache_spill=ON; -- Applies to all databases + BEGIN; + UPDATE t2 SET c=c-1; + PRAGMA lock_status; +} {main unlocked temp unknown aux1 exclusive} + finish_test