Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Increase the upper bound on SQLITE_MAX_ATTACHED from 30 to 62. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
7aaf8772274422f5020fad9eea490e19 |
User & Date: | drh 2011-03-23 18:22:34.232 |
References
2011-04-03
| ||
18:19 | Make sure that the constant 1 is cast to yDbType before shifting to create an attached database mask. This check-in is a follow-up and fix to the [7aaf8772274422] change that increases the maximum number of attached databases from 30 to 62. (check-in: e2a09ea73c user: drh tags: trunk) | |
Context
2011-03-23
| ||
22:02 | Change the xSetSyscall methods of the VFS so that they do not cast object pointers into function pointers. Fix other unrelated compiler warnings. (check-in: e059152adc user: drh tags: trunk) | |
18:22 | Increase the upper bound on SQLITE_MAX_ATTACHED from 30 to 62. (check-in: 7aaf877227 user: drh tags: trunk) | |
17:10 | Fix a bug in fts4 to do with matchinfo and deferred tokens. (check-in: 30d42dc66f user: dan tags: trunk) | |
Changes
Changes to src/build.c.
︙ | ︙ | |||
144 145 146 147 148 149 150 | /* The cookie mask contains one bit for each database file open. ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are ** set for each database that is used. Generate code to start a ** transaction on each used database and to verify the schema cookie ** on each used database. */ if( pParse->cookieGoto>0 ){ | | | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | /* The cookie mask contains one bit for each database file open. ** (Bit 0 is for main, bit 1 is for temp, and so forth.) Bits are ** set for each database that is used. Generate code to start a ** transaction on each used database and to verify the schema cookie ** on each used database. */ if( pParse->cookieGoto>0 ){ tAttachMask mask; int iDb; sqlite3VdbeJumpHere(v, pParse->cookieGoto-1); for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){ if( (mask & pParse->cookieMask)==0 ) continue; sqlite3VdbeUsesBtree(v, iDb); sqlite3VdbeAddOp2(v,OP_Transaction, iDb, (mask & pParse->writeMask)!=0); if( db->init.busy==0 ){ |
︙ | ︙ | |||
3440 3441 3442 3443 3444 3445 3446 | if( pToplevel->cookieGoto==0 ){ Vdbe *v = sqlite3GetVdbe(pToplevel); if( v==0 ) return; /* This only happens if there was a prior error */ pToplevel->cookieGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0)+1; } if( iDb>=0 ){ sqlite3 *db = pToplevel->db; | | | | 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 | if( pToplevel->cookieGoto==0 ){ Vdbe *v = sqlite3GetVdbe(pToplevel); if( v==0 ) return; /* This only happens if there was a prior error */ pToplevel->cookieGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0)+1; } if( iDb>=0 ){ sqlite3 *db = pToplevel->db; tAttachMask mask; assert( iDb<db->nDb ); assert( db->aDb[iDb].pBt!=0 || iDb==1 ); assert( iDb<SQLITE_MAX_ATTACHED+2 ); mask = ((tAttachMask)1)<<iDb; if( (pToplevel->cookieMask & mask)==0 ){ pToplevel->cookieMask |= mask; pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie; if( !OMIT_TEMPDB && iDb==1 ){ sqlite3OpenTempDatabase(pToplevel); } } |
︙ | ︙ | |||
3472 3473 3474 3475 3476 3477 3478 | ** rollback the whole transaction. For operations where all constraints ** can be checked before any changes are made to the database, it is never ** necessary to undo a write and the checkpoint should not be set. */ void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ Parse *pToplevel = sqlite3ParseToplevel(pParse); sqlite3CodeVerifySchema(pParse, iDb); | | | 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 | ** rollback the whole transaction. For operations where all constraints ** can be checked before any changes are made to the database, it is never ** necessary to undo a write and the checkpoint should not be set. */ void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ Parse *pToplevel = sqlite3ParseToplevel(pParse); sqlite3CodeVerifySchema(pParse, iDb); pToplevel->writeMask |= ((tAttachMask)1)<<iDb; pToplevel->isMultiWrite |= setStatement; } /* ** Indicate that the statement currently under construction might write ** more than one entry (example: deleting one row then inserting another, ** inserting multiple rows in a table, or inserting a row and index entries.) |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
1719 1720 1721 1722 1723 1724 1725 | #endif #if SQLITE_MAX_VDBE_OP<40 # error SQLITE_MAX_VDBE_OP must be at least 40 #endif #if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000 # error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000 #endif | | | | 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 | #endif #if SQLITE_MAX_VDBE_OP<40 # error SQLITE_MAX_VDBE_OP must be at least 40 #endif #if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000 # error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000 #endif #if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>62 # error SQLITE_MAX_ATTACHED must be between 0 and 62 #endif #if SQLITE_MAX_LIKE_PATTERN_LENGTH<1 # error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1 #endif #if SQLITE_MAX_COLUMN>32767 # error SQLITE_MAX_COLUMN must not exceed 32767 #endif |
︙ | ︙ |
Changes to src/sqliteInt.h.
︙ | ︙ | |||
2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 | Trigger *pTrigger; /* Trigger this program was coded from */ int orconf; /* Default ON CONFLICT policy */ SubProgram *pProgram; /* Program implementing pTrigger/orconf */ u32 aColmask[2]; /* Masks of old.*, new.* columns accessed */ TriggerPrg *pNext; /* Next entry in Parse.pTriggerPrg list */ }; /* ** An SQL parser context. A copy of this structure is passed through ** the parser and down into all the parser action routine in order to ** carry around information that is global to the entire parse. ** ** The structure is divided into two parts. When the parser and code ** generate call themselves recursively, the first part of the structure | > > > > > > > | 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 | Trigger *pTrigger; /* Trigger this program was coded from */ int orconf; /* Default ON CONFLICT policy */ SubProgram *pProgram; /* Program implementing pTrigger/orconf */ u32 aColmask[2]; /* Masks of old.*, new.* columns accessed */ TriggerPrg *pNext; /* Next entry in Parse.pTriggerPrg list */ }; /* Datatype for the bitmask of all attached databases */ #if SQLITE_MAX_ATTACHED>30 typedef sqlite3_uint64 tAttachMask; #else typedef unsigned int tAttachMask; #endif /* ** An SQL parser context. A copy of this structure is passed through ** the parser and down into all the parser action routine in order to ** carry around information that is global to the entire parse. ** ** The structure is divided into two parts. When the parser and code ** generate call themselves recursively, the first part of the structure |
︙ | ︙ | |||
2169 2170 2171 2172 2173 2174 2175 | int iTable; /* Table cursor number */ int iColumn; /* Table column number */ u8 tempReg; /* iReg is a temp register that needs to be freed */ int iLevel; /* Nesting level */ int iReg; /* Reg with value of this column. 0 means none. */ int lru; /* Least recently used entry has the smallest value */ } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */ | | | | 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 | int iTable; /* Table cursor number */ int iColumn; /* Table column number */ u8 tempReg; /* iReg is a temp register that needs to be freed */ int iLevel; /* Nesting level */ int iReg; /* Reg with value of this column. 0 means none. */ int lru; /* Least recently used entry has the smallest value */ } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */ tAttachMask writeMask; /* Start a write transaction on these databases */ tAttachMask cookieMask; /* Bitmask of schema verified databases */ u8 isMultiWrite; /* True if statement may affect/insert multiple rows */ u8 mayAbort; /* True if statement may throw an ABORT exception */ int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */ int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */ #ifndef SQLITE_OMIT_SHARED_CACHE int nTableLock; /* Number of locks in aTableLock */ TableLock *aTableLock; /* Required table locks for shared-cache mode */ |
︙ | ︙ |
Changes to src/vdbeInt.h.
︙ | ︙ | |||
298 299 300 301 302 303 304 | u8 runOnlyOnce; /* Automatically expire on reset */ u8 minWriteFileFormat; /* Minimum file format for writable database files */ u8 inVtabMethod; /* See comments above */ u8 usesStmtJournal; /* True if uses a statement journal */ u8 readOnly; /* True for read-only statements */ u8 isPrepareV2; /* True if prepared with prepare_v2() */ int nChange; /* Number of db changes made since last reset */ | | | 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 | u8 runOnlyOnce; /* Automatically expire on reset */ u8 minWriteFileFormat; /* Minimum file format for writable database files */ u8 inVtabMethod; /* See comments above */ u8 usesStmtJournal; /* True if uses a statement journal */ u8 readOnly; /* True for read-only statements */ u8 isPrepareV2; /* True if prepared with prepare_v2() */ int nChange; /* Number of db changes made since last reset */ tAttachMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ int iStatement; /* Statement number (or 0 if has not opened stmt) */ int aCounter[3]; /* Counters used by sqlite3_stmt_status() */ BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */ #ifndef SQLITE_OMIT_TRACE i64 startTime; /* Time when query started - used for profiling */ #endif i64 nFkConstraint; /* Number of imm. FK constraints this VM */ |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
946 947 948 949 950 951 952 | ** ** 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){ | | | | 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 | ** ** 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){ tAttachMask mask; assert( i>=0 && i<p->db->nDb && i<sizeof(tAttachMask)*8 ); assert( i<(int)sizeof(p->btreeMask)*8 ); mask = ((u32)1)<<i; if( (p->btreeMask & mask)==0 ){ p->btreeMask |= mask; sqlite3BtreeMutexArrayInsert(&p->aMutex, p->db->aDb[i].pBt); } } |
︙ | ︙ |
Changes to test/attach.test.
︙ | ︙ | |||
148 149 150 151 152 153 154 | } {1 {database MAIN is already in use}} do_test attach-1.18 { catchsql { ATTACH 'test.db' as db10; ATTACH 'test.db' as db11; } } {0 {}} | > | | | | | | | | > > | | | | | | | | > | 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | } {1 {database MAIN is already in use}} do_test attach-1.18 { catchsql { ATTACH 'test.db' as db10; ATTACH 'test.db' as db11; } } {0 {}} if {$SQLITE_MAX_ATTACHED==10} { do_test attach-1.19 { catchsql { ATTACH 'test.db' as db12; } } {1 {too many attached databases - max 10}} do_test attach-1.19.1 { db errorcode } {1} } do_test attach-1.20.1 { execsql { DETACH db5; } } {} ifcapable schema_pragmas { do_test attach-1.20.2 { db_list db } {0 main 2 db2 3 db3 4 db4 5 db6 6 db7 7 db8 8 db9 9 db10 10 db11} } ;# ifcapable schema_pragmas integrity_check attach-1.20.3 ifcapable tempdb { execsql {select * from sqlite_temp_master} } do_test attach-1.21 { catchsql { ATTACH 'test.db' as db12; } } {0 {}} if {$SQLITE_MAX_ATTACHED==10} { do_test attach-1.22 { catchsql { ATTACH 'test.db' as db13; } } {1 {too many attached databases - max 10}} do_test attach-1.22.1 { db errorcode } {1} } do_test attach-1.23 { catchsql { DETACH "db14"; } } {1 {no such database: db14}} do_test attach-1.24 { catchsql { |
︙ | ︙ |