1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Allow the SQLITE_MAX_ATTACHED compile-time option to be larger than 62. The

default limit on the number of attached databases remains 10.

FossilOrigin-Name: 1a817ae2f35fa0396148dda2782cd4f919bf5c6f
This commit is contained in:
drh
2014-07-21 15:44:39 +00:00
parent 857745c089
commit a7ab6d8165
7 changed files with 72 additions and 49 deletions

View File

@@ -1,5 +1,5 @@
C Update\sthe\ssqlite3_stmt_busy()\sfunction\sso\sthat\sit\scorrectly\sreturns\strue\sfor\s"ROLLBACK"\sstatements\sthat\shave\sbeen\sstepped\sbut\snot\syet\sreset. C Allow\sthe\sSQLITE_MAX_ATTACHED\scompile-time\soption\sto\sbe\slarger\sthan\s62.\s\sThe\ndefault\slimit\son\sthe\snumber\sof\sattached\sdatabases\sremains\s10.
D 2014-07-19T17:57:10.785 D 2014-07-21T15:44:39.054
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308 F Makefile.in 5eb79e334a5de69c87740edd56af6527dd219308
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -170,7 +170,7 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c 70c60a3807b2072982f184d9614e020d2953f89c F src/btree.c 70c60a3807b2072982f184d9614e020d2953f89c
F src/btree.h 4245a349bfe09611d7ff887dbc3a80cee8b7955a F src/btree.h 4245a349bfe09611d7ff887dbc3a80cee8b7955a
F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3 F src/btreeInt.h cf180d86b2e9e418f638d65baa425c4c69c0e0e3
F src/build.c 927e39b6aaf872c7b28f154f6acfeb9a05a72442 F src/build.c 48f400fa14fd6add244b954ce7e223ce7ccacf0b
F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98 F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a F src/ctime.c 0231df905e2c4abba4483ee18ffc05adc321df2a
@@ -189,7 +189,7 @@ F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12 F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303 F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303
F src/main.c 7c2c3cafdd6313c8f9319ebec1565782e624372e F src/main.c bba87834413394f43b1a211c38c282c7d4092d1d
F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b
@@ -227,7 +227,7 @@ F src/shell.c 566aee8213372a2e81ba0eb34e9759f7b2574009
F src/sqlite.h.in fd8e3a36b0aded082dc93a4b89c1e85324b4cf75 F src/sqlite.h.in fd8e3a36b0aded082dc93a4b89c1e85324b4cf75
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
F src/sqliteInt.h e88614d7371b80ff69dbbb5e4b9813ee93dfd890 F src/sqliteInt.h 5dbcdcf81cb15e77df16f88699a15f7af491c580
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -283,11 +283,11 @@ F src/update.c 01564b3c430f6c7b0a35afaf7aba7987206fa3a5
F src/utf.c a0314e637768a030e6e84a957d0c4f6ba910cc05 F src/utf.c a0314e637768a030e6e84a957d0c4f6ba910cc05
F src/util.c 049fe1d3c0e2209c1bee107aec2fcff6285f909f F src/util.c 049fe1d3c0e2209c1bee107aec2fcff6285f909f
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179 F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
F src/vdbe.c 9bfe6becfc094382ae213656fbe511055ad83a54 F src/vdbe.c 514adcc9478e461d01b9b064565d2c99604ed537
F src/vdbe.h c63fad052c9e7388d551e556e119c0bcf6bebdf8 F src/vdbe.h c63fad052c9e7388d551e556e119c0bcf6bebdf8
F src/vdbeInt.h 5df5e9afe9b7839cd17256220fc4f7af84b8b1cd F src/vdbeInt.h 5df5e9afe9b7839cd17256220fc4f7af84b8b1cd
F src/vdbeapi.c 24e40422382beb774daab11fe9fe9d37e8a04949 F src/vdbeapi.c 24e40422382beb774daab11fe9fe9d37e8a04949
F src/vdbeaux.c 8d32b5a68670ccc6c64904924e6a0dddbc3a2fc5 F src/vdbeaux.c 1ffe0bbc3a2c8aedd95622de9be6b6d07b3d3c6b
F src/vdbeblob.c 9205ce9d3b064d9600f8418a897fc88b5687d9ac F src/vdbeblob.c 9205ce9d3b064d9600f8418a897fc88b5687d9ac
F src/vdbemem.c d90a1e8acf8b63dc9d14cbbea12bfec6cec31394 F src/vdbemem.c d90a1e8acf8b63dc9d14cbbea12bfec6cec31394
F src/vdbesort.c 44441d73b08b3a638dcdb725afffb87c6574ad27 F src/vdbesort.c 44441d73b08b3a638dcdb725afffb87c6574ad27
@@ -1182,7 +1182,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
P 574cc8eb1448cff67390f2e16cc9b7c3ddd4658b P 61cee3c0678f5abd9131a29ab946a5e71f55643e
R 3e17c7c287ebc0f7c8d4dc519939fd8f R 03bc11d876fd7682716b5fcb2f08b30c
U dan U drh
Z 2190a4b1d8dc0a3facc078eb683578eb Z 1b802be3c637c9b3363a3a4e9caf7d2a

View File

@@ -1 +1 @@
61cee3c0678f5abd9131a29ab946a5e71f55643e 1a817ae2f35fa0396148dda2782cd4f919bf5c6f

View File

@@ -113,6 +113,19 @@ static void codeTableLocks(Parse *pParse){
#define codeTableLocks(x) #define codeTableLocks(x)
#endif #endif
/*
** Return TRUE if the given yDbMask object is empty - if it contains no
** 1 bits. This routine is used by the DbMaskAllZero() and DbMaskNotZero()
** macros when SQLITE_MAX_ATTACHED is greater than 30.
*/
#if SQLITE_MAX_ATTACHED>30
int sqlite3DbMaskAllZero(yDbMask m){
int i;
for(i=0; i<sizeof(yDbMask); i++) if( m[i] ) return 0;
return 1;
}
#endif
/* /*
** This routine is called after a single SQL statement has been ** This routine is called after a single SQL statement has been
** parsed and a VDBE program to execute that statement has been ** parsed and a VDBE program to execute that statement has been
@@ -149,18 +162,19 @@ void sqlite3FinishCoding(Parse *pParse){
** transaction on each used database and to verify the schema cookie ** transaction on each used database and to verify the schema cookie
** on each used database. ** on each used database.
*/ */
if( db->mallocFailed==0 && (pParse->cookieMask || pParse->pConstExpr) ){ if( db->mallocFailed==0
yDbMask mask; && (DbMaskNonZero(pParse->cookieMask) || pParse->pConstExpr)
){
int iDb, i; int iDb, i;
assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init );
sqlite3VdbeJumpHere(v, 0); sqlite3VdbeJumpHere(v, 0);
for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){ for(iDb=0; iDb<db->nDb; iDb++){
if( (mask & pParse->cookieMask)==0 ) continue; if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue;
sqlite3VdbeUsesBtree(v, iDb); sqlite3VdbeUsesBtree(v, iDb);
sqlite3VdbeAddOp4Int(v, sqlite3VdbeAddOp4Int(v,
OP_Transaction, /* Opcode */ OP_Transaction, /* Opcode */
iDb, /* P1 */ iDb, /* P1 */
(mask & pParse->writeMask)!=0, /* P2 */ DbMaskTest(pParse->writeMask,iDb), /* P2 */
pParse->cookieValue[iDb], /* P3 */ pParse->cookieValue[iDb], /* P3 */
db->aDb[iDb].pSchema->iGeneration /* P4 */ db->aDb[iDb].pSchema->iGeneration /* P4 */
); );
@@ -216,7 +230,7 @@ void sqlite3FinishCoding(Parse *pParse){
pParse->nMem = 0; pParse->nMem = 0;
pParse->nSet = 0; pParse->nSet = 0;
pParse->nVar = 0; pParse->nVar = 0;
pParse->cookieMask = 0; DbMaskZero(pParse->cookieMask);
} }
/* /*
@@ -3843,15 +3857,13 @@ int sqlite3OpenTempDatabase(Parse *pParse){
void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ void sqlite3CodeVerifySchema(Parse *pParse, int iDb){
Parse *pToplevel = sqlite3ParseToplevel(pParse); Parse *pToplevel = sqlite3ParseToplevel(pParse);
sqlite3 *db = pToplevel->db; sqlite3 *db = pToplevel->db;
yDbMask mask;
assert( iDb>=0 && iDb<db->nDb ); assert( iDb>=0 && iDb<db->nDb );
assert( db->aDb[iDb].pBt!=0 || iDb==1 ); assert( db->aDb[iDb].pBt!=0 || iDb==1 );
assert( iDb<SQLITE_MAX_ATTACHED+2 ); assert( iDb<SQLITE_MAX_ATTACHED+2 );
assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
mask = ((yDbMask)1)<<iDb; if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){
if( (pToplevel->cookieMask & mask)==0 ){ DbMaskSet(pToplevel->cookieMask, iDb);
pToplevel->cookieMask |= mask;
pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie; pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
if( !OMIT_TEMPDB && iDb==1 ){ if( !OMIT_TEMPDB && iDb==1 ){
sqlite3OpenTempDatabase(pToplevel); sqlite3OpenTempDatabase(pToplevel);
@@ -3890,7 +3902,7 @@ void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){
void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){
Parse *pToplevel = sqlite3ParseToplevel(pParse); Parse *pToplevel = sqlite3ParseToplevel(pParse);
sqlite3CodeVerifySchema(pParse, iDb); sqlite3CodeVerifySchema(pParse, iDb);
pToplevel->writeMask |= ((yDbMask)1)<<iDb; DbMaskSet(pToplevel->writeMask, iDb);
pToplevel->isMultiWrite |= setStatement; pToplevel->isMultiWrite |= setStatement;
} }

View File

@@ -2101,8 +2101,8 @@ static const int aHardLimit[] = {
#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000 #if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000
# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000 # error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000
#endif #endif
#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>62 #if SQLITE_MAX_ATTACHED<0
# error SQLITE_MAX_ATTACHED must be between 0 and 62 # error SQLITE_MAX_ATTACHED must be greater than 0
#endif #endif
#if SQLITE_MAX_LIKE_PATTERN_LENGTH<1 #if SQLITE_MAX_LIKE_PATTERN_LENGTH<1
# error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1 # error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1

View File

@@ -2392,9 +2392,19 @@ struct TriggerPrg {
** The yDbMask datatype for the bitmask of all attached databases. ** The yDbMask datatype for the bitmask of all attached databases.
*/ */
#if SQLITE_MAX_ATTACHED>30 #if SQLITE_MAX_ATTACHED>30
typedef sqlite3_uint64 yDbMask; typedef unsigned char yDbMask[(SQLITE_MAX_ATTACHED+9)/8];
# define DbMaskTest(M,I) (((M)[(I)/8]&(1<<((I)&7)))!=0)
# define DbMaskZero(M) memset((M),0,sizeof(M))
# define DbMaskSet(M,I) (M)[(I)/8]|=(1<<((I)&7))
# define DbMaskAllZero(M) sqlite3DbMaskAllZero(M)
# define DbMaskNonZero(M) (sqlite3DbMaskAllZero(M)==0)
#else #else
typedef unsigned int yDbMask; typedef unsigned int yDbMask;
# define DbMaskTest(M,I) (((M)&(((yDbMask)1)<<(I)))!=0)
# define DbMaskZero(M) (M)=0
# define DbMaskSet(M,I) (M)|=(((yDbMask)1)<<(I))
# define DbMaskAllZero(M) (M)==0
# define DbMaskNonZero(M) (M)!=0
#endif #endif
/* /*
@@ -3067,6 +3077,9 @@ void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int);
# define sqlite3ViewGetColumnNames(A,B) 0 # define sqlite3ViewGetColumnNames(A,B) 0
#endif #endif
#if SQLITE_MAX_ATTACHED>30
int sqlite3DbMaskAllZero(yDbMask);
#endif
void sqlite3DropTable(Parse*, SrcList*, int, int); void sqlite3DropTable(Parse*, SrcList*, int, int);
void sqlite3CodeDropTable(Parse*, Table*, int, int); void sqlite3CodeDropTable(Parse*, Table*, int, int);
void sqlite3DeleteTable(sqlite3*, Table*); void sqlite3DeleteTable(sqlite3*, Table*);

View File

@@ -3034,7 +3034,7 @@ case OP_Transaction: {
assert( p->bIsReader ); assert( p->bIsReader );
assert( p->readOnly==0 || pOp->p2==0 ); assert( p->readOnly==0 || pOp->p2==0 );
assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); assert( DbMaskTest(p->btreeMask, pOp->p1) );
if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){ if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){
rc = SQLITE_READONLY; rc = SQLITE_READONLY;
goto abort_due_to_error; goto abort_due_to_error;
@@ -3129,7 +3129,7 @@ case OP_ReadCookie: { /* out2-prerelease */
assert( pOp->p3<SQLITE_N_BTREE_META ); assert( pOp->p3<SQLITE_N_BTREE_META );
assert( iDb>=0 && iDb<db->nDb ); assert( iDb>=0 && iDb<db->nDb );
assert( db->aDb[iDb].pBt!=0 ); assert( db->aDb[iDb].pBt!=0 );
assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); assert( DbMaskTest(p->btreeMask, iDb) );
sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta); sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta);
pOut->u.i = iMeta; pOut->u.i = iMeta;
@@ -3150,7 +3150,7 @@ case OP_SetCookie: { /* in3 */
Db *pDb; Db *pDb;
assert( pOp->p2<SQLITE_N_BTREE_META ); assert( pOp->p2<SQLITE_N_BTREE_META );
assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); assert( DbMaskTest(p->btreeMask, pOp->p1) );
assert( p->readOnly==0 ); assert( p->readOnly==0 );
pDb = &db->aDb[pOp->p1]; pDb = &db->aDb[pOp->p1];
assert( pDb->pBt!=0 ); assert( pDb->pBt!=0 );
@@ -3253,7 +3253,7 @@ case OP_OpenWrite: {
p2 = pOp->p2; p2 = pOp->p2;
iDb = pOp->p3; iDb = pOp->p3;
assert( iDb>=0 && iDb<db->nDb ); assert( iDb>=0 && iDb<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); assert( DbMaskTest(p->btreeMask, iDb) );
pDb = &db->aDb[iDb]; pDb = &db->aDb[iDb];
pX = pDb->pBt; pX = pDb->pBt;
assert( pX!=0 ); assert( pX!=0 );
@@ -4844,7 +4844,7 @@ case OP_Destroy: { /* out2-prerelease */
}else{ }else{
iDb = pOp->p3; iDb = pOp->p3;
assert( iCnt==1 ); assert( iCnt==1 );
assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 ); assert( DbMaskTest(p->btreeMask, iDb) );
iMoved = 0; /* Not needed. Only to silence a warning. */ iMoved = 0; /* Not needed. Only to silence a warning. */
rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved); rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved);
pOut->flags = MEM_Int; pOut->flags = MEM_Int;
@@ -4884,7 +4884,7 @@ case OP_Clear: {
nChange = 0; nChange = 0;
assert( p->readOnly==0 ); assert( p->readOnly==0 );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); assert( DbMaskTest(p->btreeMask, pOp->p2) );
rc = sqlite3BtreeClearTable( rc = sqlite3BtreeClearTable(
db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0) db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0)
); );
@@ -4954,7 +4954,7 @@ case OP_CreateTable: { /* out2-prerelease */
pgno = 0; pgno = 0;
assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); assert( DbMaskTest(p->btreeMask, pOp->p1) );
assert( p->readOnly==0 ); assert( p->readOnly==0 );
pDb = &db->aDb[pOp->p1]; pDb = &db->aDb[pOp->p1];
assert( pDb->pBt!=0 ); assert( pDb->pBt!=0 );
@@ -5119,7 +5119,7 @@ case OP_IntegrityCk: {
} }
aRoot[j] = 0; aRoot[j] = 0;
assert( pOp->p5<db->nDb ); assert( pOp->p5<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p5))!=0 ); assert( DbMaskTest(p->btreeMask, pOp->p5) );
z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot, z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, aRoot, nRoot,
(int)pnErr->u.i, &nErr); (int)pnErr->u.i, &nErr);
sqlite3DbFree(db, aRoot); sqlite3DbFree(db, aRoot);
@@ -5779,7 +5779,7 @@ case OP_IncrVacuum: { /* jump */
Btree *pBt; Btree *pBt;
assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( pOp->p1>=0 && pOp->p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 ); assert( DbMaskTest(p->btreeMask, pOp->p1) );
assert( p->readOnly==0 ); assert( p->readOnly==0 );
pBt = db->aDb[pOp->p1].pBt; pBt = db->aDb[pOp->p1].pBt;
rc = sqlite3BtreeIncrVacuum(pBt); rc = sqlite3BtreeIncrVacuum(pBt);
@@ -5831,7 +5831,7 @@ case OP_TableLock: {
if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){ if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){
int p1 = pOp->p1; int p1 = pOp->p1;
assert( p1>=0 && p1<db->nDb ); assert( p1>=0 && p1<db->nDb );
assert( (p->btreeMask & (((yDbMask)1)<<p1))!=0 ); assert( DbMaskTest(p->btreeMask, p1) );
assert( isWriteLock==0 || isWriteLock==1 ); assert( isWriteLock==0 || isWriteLock==1 );
rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock); rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
if( (rc&0xFF)==SQLITE_LOCKED ){ if( (rc&0xFF)==SQLITE_LOCKED ){
@@ -6281,7 +6281,7 @@ case OP_Init: { /* jump */
if( zTrace ){ if( zTrace ){
int i; int i;
for(i=0; i<db->nDb; i++){ for(i=0; i<db->nDb; i++){
if( (MASKBIT(i) & p->btreeMask)==0 ) continue; if( DbMaskTest(p->btreeMask, i)==0 ) continue;
sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace); sqlite3_file_control(db, db->aDb[i].zName, SQLITE_FCNTL_TRACE, zTrace);
} }
} }

View File

@@ -499,7 +499,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
pParse->aLabel = 0; pParse->aLabel = 0;
pParse->nLabel = 0; pParse->nLabel = 0;
*pMaxFuncArgs = nMaxArgs; *pMaxFuncArgs = nMaxArgs;
assert( p->bIsReader!=0 || p->btreeMask==0 ); assert( p->bIsReader!=0 || DbMaskAllZero(p->btreeMask) );
} }
/* /*
@@ -526,7 +526,7 @@ VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){
assert( aOp && !p->db->mallocFailed ); assert( aOp && !p->db->mallocFailed );
/* Check that sqlite3VdbeUsesBtree() was not called on this VM */ /* Check that sqlite3VdbeUsesBtree() was not called on this VM */
assert( p->btreeMask==0 ); assert( DbMaskAllZero(p->btreeMask) );
resolveP2Values(p, pnMaxArg); resolveP2Values(p, pnMaxArg);
*pnOp = p->nOp; *pnOp = p->nOp;
@@ -1111,9 +1111,9 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
void sqlite3VdbeUsesBtree(Vdbe *p, int i){ void sqlite3VdbeUsesBtree(Vdbe *p, int i){
assert( i>=0 && i<p->db->nDb && i<(int)sizeof(yDbMask)*8 ); assert( i>=0 && i<p->db->nDb && i<(int)sizeof(yDbMask)*8 );
assert( i<(int)sizeof(p->btreeMask)*8 ); assert( i<(int)sizeof(p->btreeMask)*8 );
p->btreeMask |= ((yDbMask)1)<<i; DbMaskSet(p->btreeMask, i);
if( i!=1 && sqlite3BtreeSharable(p->db->aDb[i].pBt) ){ if( i!=1 && sqlite3BtreeSharable(p->db->aDb[i].pBt) ){
p->lockMask |= ((yDbMask)1)<<i; DbMaskSet(p->lockMask, i);
} }
} }
@@ -1141,16 +1141,15 @@ void sqlite3VdbeUsesBtree(Vdbe *p, int i){
*/ */
void sqlite3VdbeEnter(Vdbe *p){ void sqlite3VdbeEnter(Vdbe *p){
int i; int i;
yDbMask mask;
sqlite3 *db; sqlite3 *db;
Db *aDb; Db *aDb;
int nDb; int nDb;
if( p->lockMask==0 ) return; /* The common case */ if( DbMaskAllZero(p->lockMask) ) return; /* The common case */
db = p->db; db = p->db;
aDb = db->aDb; aDb = db->aDb;
nDb = db->nDb; nDb = db->nDb;
for(i=0, mask=1; i<nDb; i++, mask += mask){ for(i=0; i<nDb; i++){
if( i!=1 && (mask & p->lockMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){ if( i!=1 && DbMaskTest(p->lockMask,i) && ALWAYS(aDb[i].pBt!=0) ){
sqlite3BtreeEnter(aDb[i].pBt); sqlite3BtreeEnter(aDb[i].pBt);
} }
} }
@@ -1163,16 +1162,15 @@ void sqlite3VdbeEnter(Vdbe *p){
*/ */
void sqlite3VdbeLeave(Vdbe *p){ void sqlite3VdbeLeave(Vdbe *p){
int i; int i;
yDbMask mask;
sqlite3 *db; sqlite3 *db;
Db *aDb; Db *aDb;
int nDb; int nDb;
if( p->lockMask==0 ) return; /* The common case */ if( DbMaskAllZero(p->lockMask) ) return; /* The common case */
db = p->db; db = p->db;
aDb = db->aDb; aDb = db->aDb;
nDb = db->nDb; nDb = db->nDb;
for(i=0, mask=1; i<nDb; i++, mask += mask){ for(i=0; i<nDb; i++){
if( i!=1 && (mask & p->lockMask)!=0 && ALWAYS(aDb[i].pBt!=0) ){ if( i!=1 && DbMaskTest(p->lockMask,i) && ALWAYS(aDb[i].pBt!=0) ){
sqlite3BtreeLeave(aDb[i].pBt); sqlite3BtreeLeave(aDb[i].pBt);
} }
} }