/ Check-in [8e885dde]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Pull the latest changes from trunk (and hence from schema-parse-refactor) into the apple-osx branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | apple-osx
Files: files | file ages | folders
SHA1: 8e885ddea0fc5d4c4256025c127e5d41d63c47a5
User & Date: drh 2011-04-05 13:38:12
Context
2011-04-05
22:10
Merge the latest trunk changes into the apple-osx branch. check-in: c77a767c user: drh tags: apple-osx
13:38
Pull the latest changes from trunk (and hence from schema-parse-refactor) into the apple-osx branch. check-in: 8e885dde user: drh tags: apple-osx
13:12
Merge the scheme-parse-refactor changes into trunk: (1) added sqlite3SchemaMutexHeld() asserts, (2) Use -1 instead of 0 to mean "all" in sqlite3ResetInternalSchema(), and other cosmetic changes. check-in: 5db4511d user: drh tags: trunk
2011-04-04
13:11
Merge in the latest changes from trunk. check-in: 6d78a25d user: drh tags: apple-osx
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/analyze.c.

   145    145     if( memcmp(pTab->zName, "sqlite_", 7)==0 ){
   146    146       /* Do not gather statistics on system tables */
   147    147       return;
   148    148     }
   149    149     assert( sqlite3BtreeHoldsAllMutexes(db) );
   150    150     iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
   151    151     assert( iDb>=0 );
          152  +  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
   152    153   #ifndef SQLITE_OMIT_AUTHORIZATION
   153    154     if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0,
   154    155         db->aDb[iDb].zName ) ){
   155    156       return;
   156    157     }
   157    158   #endif
   158    159   
................................................................................
   386    387     int iMem;
   387    388   
   388    389     sqlite3BeginWriteOperation(pParse, 0, iDb);
   389    390     iStatCur = pParse->nTab;
   390    391     pParse->nTab += 2;
   391    392     openStatTable(pParse, iDb, iStatCur, 0, 0);
   392    393     iMem = pParse->nMem+1;
          394  +  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
   393    395     for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
   394    396       Table *pTab = (Table*)sqliteHashData(k);
   395    397       analyzeOneTable(pParse, pTab, 0, iStatCur, iMem);
   396    398     }
   397    399     loadAnalysis(pParse, iDb);
   398    400   }
   399    401   
................................................................................
   596    598     analysisInfo sInfo;
   597    599     HashElem *i;
   598    600     char *zSql;
   599    601     int rc;
   600    602   
   601    603     assert( iDb>=0 && iDb<db->nDb );
   602    604     assert( db->aDb[iDb].pBt!=0 );
   603         -  assert( sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) );
   604    605   
   605    606     /* Clear any prior statistics */
          607  +  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
   606    608     for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
   607    609       Index *pIdx = sqliteHashData(i);
   608    610       sqlite3DefaultRowEst(pIdx);
   609    611       sqlite3DeleteIndexSamples(db, pIdx);
   610    612       pIdx->aSample = 0;
   611    613     }
   612    614   

Changes to src/attach.c.

   196    196       int iDb = db->nDb - 1;
   197    197       assert( iDb>=2 );
   198    198       if( db->aDb[iDb].pBt ){
   199    199         sqlite3BtreeClose(db->aDb[iDb].pBt);
   200    200         db->aDb[iDb].pBt = 0;
   201    201         db->aDb[iDb].pSchema = 0;
   202    202       }
   203         -    sqlite3ResetInternalSchema(db, 0);
          203  +    sqlite3ResetInternalSchema(db, -1);
   204    204       db->nDb = iDb;
   205    205       if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
   206    206         db->mallocFailed = 1;
   207    207         sqlite3DbFree(db, zErrDyn);
   208    208         zErrDyn = sqlite3MPrintf(db, "out of memory");
   209    209       }else if( zErrDyn==0 ){
   210    210         zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile);
................................................................................
   268    268       sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
   269    269       goto detach_error;
   270    270     }
   271    271   
   272    272     sqlite3BtreeClose(pDb->pBt);
   273    273     pDb->pBt = 0;
   274    274     pDb->pSchema = 0;
   275         -  sqlite3ResetInternalSchema(db, 0);
          275  +  sqlite3ResetInternalSchema(db, -1);
   276    276     return;
   277    277   
   278    278   detach_error:
   279    279     sqlite3_result_error(context, zErr, -1);
   280    280   }
   281    281   
   282    282   /*

Changes to src/backup.c.

   397    397       */
   398    398       if( rc==SQLITE_DONE 
   399    399        && (rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1))==SQLITE_OK
   400    400       ){
   401    401         int nDestTruncate;
   402    402     
   403    403         if( p->pDestDb ){
   404         -        sqlite3ResetInternalSchema(p->pDestDb, 0);
          404  +        sqlite3ResetInternalSchema(p->pDestDb, -1);
   405    405         }
   406    406   
   407    407         /* Set nDestTruncate to the final number of pages in the destination
   408    408         ** database. The complication here is that the destination page
   409    409         ** size may be different to the source page size. 
   410    410         **
   411    411         ** If the source page size is smaller than the destination page size, 

Changes to src/btmutex.c.

   284    284         return 0;
   285    285       }
   286    286     }
   287    287     return 1;
   288    288   }
   289    289   #endif /* NDEBUG */
   290    290   
          291  +#ifndef NDEBUG
          292  +/*
          293  +** Return true if the correct mutexes are held for accessing the
          294  +** db->aDb[iDb].pSchema structure.  The mutexes required for schema
          295  +** access are:
          296  +**
          297  +**   (1) The mutex on db
          298  +**   (2) if iDb!=1, then the mutex on db->aDb[iDb].pBt.
          299  +**
          300  +** If pSchema is not NULL, then iDb is computed from pSchema and
          301  +** db using sqlite3SchemaToIndex().
          302  +*/
          303  +int sqlite3SchemaMutexHeld(sqlite3 *db, int iDb, Schema *pSchema){
          304  +  Btree *p;
          305  +  assert( db!=0 );
          306  +  if( pSchema ) iDb = sqlite3SchemaToIndex(db, pSchema);
          307  +  assert( iDb>=0 && iDb<db->nDb );
          308  +  if( !sqlite3_mutex_held(db->mutex) ) return 0;
          309  +  if( iDb==1 ) return 1;
          310  +  p = db->aDb[iDb].pBt;
          311  +  assert( p!=0 );
          312  +  return p->sharable==0 || p->locked==1;
          313  +}
          314  +#endif /* NDEBUG */
          315  +
   291    316   #else /* SQLITE_THREADSAFE>0 above.  SQLITE_THREADSAFE==0 below */
   292    317   /*
   293    318   ** The following are special cases for mutex enter routines for use
   294    319   ** in single threaded applications that use shared cache.  Except for
   295    320   ** these two routines, all mutex operations are no-ops in that case and
   296    321   ** are null #defines in btree.h.
   297    322   **

Changes to src/btree.h.

   216    216     void sqlite3BtreeEnterCursor(BtCursor*);
   217    217     void sqlite3BtreeLeaveCursor(BtCursor*);
   218    218     void sqlite3BtreeLeaveAll(sqlite3*);
   219    219   #ifndef NDEBUG
   220    220     /* These routines are used inside assert() statements only. */
   221    221     int sqlite3BtreeHoldsMutex(Btree*);
   222    222     int sqlite3BtreeHoldsAllMutexes(sqlite3*);
          223  +  int sqlite3SchemaMutexHeld(sqlite3*,int,Schema*);
   223    224     u32 sqlite3BtreeMutexCounter(Btree*);
   224    225   #endif
   225    226   #else
   226    227   
   227    228   # define sqlite3BtreeLeave(X)
   228    229   # define sqlite3BtreeMutexCounter(X) 0
   229    230   # define sqlite3BtreeEnterCursor(X)
   230    231   # define sqlite3BtreeLeaveCursor(X)
   231    232   # define sqlite3BtreeLeaveAll(X)
   232    233   
   233    234   # define sqlite3BtreeHoldsMutex(X) 1
   234    235   # define sqlite3BtreeHoldsAllMutexes(X) 1
          236  +# define sqlite3BtreeSchemaMutexHeld(X,Y) 1
   235    237   #endif
   236    238   
   237    239   
   238    240   #endif /* _BTREE_H_ */

Changes to src/build.c.

   152    152         int iDb;
   153    153         sqlite3VdbeJumpHere(v, pParse->cookieGoto-1);
   154    154         for(iDb=0, mask=1; iDb<db->nDb; mask<<=1, iDb++){
   155    155           if( (mask & pParse->cookieMask)==0 ) continue;
   156    156           sqlite3VdbeUsesBtree(v, iDb);
   157    157           sqlite3VdbeAddOp2(v,OP_Transaction, iDb, (mask & pParse->writeMask)!=0);
   158    158           if( db->init.busy==0 ){
          159  +          assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
   159    160             sqlite3VdbeAddOp3(v, OP_VerifyCookie,
   160    161                               iDb, pParse->cookieValue[iDb],
   161    162                               db->aDb[iDb].pSchema->iGeneration);
   162    163           }
   163    164         }
   164    165   #ifndef SQLITE_OMIT_VIRTUALTABLE
   165    166         {
................................................................................
   267    268   */
   268    269   Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
   269    270     Table *p = 0;
   270    271     int i;
   271    272     int nName;
   272    273     assert( zName!=0 );
   273    274     nName = sqlite3Strlen30(zName);
          275  +  /* All mutexes are required for schema access.  Make sure we hold them. */
          276  +  assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) );
   274    277     for(i=OMIT_TEMPDB; i<db->nDb; i++){
   275    278       int j = (i<2) ? i^1 : i;   /* Search TEMP before MAIN */
   276    279       if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue;
          280  +    assert( sqlite3SchemaMutexHeld(db, j, 0) );
   277    281       p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName, nName);
   278    282       if( p ) break;
   279    283     }
   280    284     return p;
   281    285   }
   282    286   
   283    287   /*
................................................................................
   329    333   ** TEMP first, then MAIN, then any auxiliary databases added
   330    334   ** using the ATTACH command.
   331    335   */
   332    336   Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){
   333    337     Index *p = 0;
   334    338     int i;
   335    339     int nName = sqlite3Strlen30(zName);
          340  +  /* All mutexes are required for schema access.  Make sure we hold them. */
          341  +  assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
   336    342     for(i=OMIT_TEMPDB; i<db->nDb; i++){
   337    343       int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
   338    344       Schema *pSchema = db->aDb[j].pSchema;
   339    345       assert( pSchema );
   340    346       if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;
          347  +    assert( sqlite3SchemaMutexHeld(db, j, 0) );
   341    348       p = sqlite3HashFind(&pSchema->idxHash, zName, nName);
   342    349       if( p ) break;
   343    350     }
   344    351     return p;
   345    352   }
   346    353   
   347    354   /*
................................................................................
   360    367   ** unlike that index from its Table then remove the index from
   361    368   ** the index hash table and free all memory structures associated
   362    369   ** with the index.
   363    370   */
   364    371   void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){
   365    372     Index *pIndex;
   366    373     int len;
   367         -  Hash *pHash = &db->aDb[iDb].pSchema->idxHash;
          374  +  Hash *pHash;
   368    375   
          376  +  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
          377  +  pHash = &db->aDb[iDb].pSchema->idxHash;
   369    378     len = sqlite3Strlen30(zIdxName);
   370    379     pIndex = sqlite3HashInsert(pHash, zIdxName, len, 0);
   371    380     if( ALWAYS(pIndex) ){
   372    381       if( pIndex->pTable->pIndex==pIndex ){
   373    382         pIndex->pTable->pIndex = pIndex->pNext;
   374    383       }else{
   375    384         Index *p;
................................................................................
   389    398   /*
   390    399   ** Erase all schema information from the in-memory hash tables of
   391    400   ** a single database.  This routine is called to reclaim memory
   392    401   ** before the database closes.  It is also called during a rollback
   393    402   ** if there were schema changes during the transaction or if a
   394    403   ** schema-cookie mismatch occurs.
   395    404   **
   396         -** If iDb==0 then reset the internal schema tables for all database
   397         -** files.  If iDb>=1 then reset the internal schema for only the
          405  +** If iDb<0 then reset the internal schema tables for all database
          406  +** files.  If iDb>=0 then reset the internal schema for only the
   398    407   ** single file indicated.
   399    408   */
   400    409   void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){
   401    410     int i, j;
   402         -  assert( iDb>=0 && iDb<db->nDb );
          411  +  assert( iDb<db->nDb );
   403    412   
   404         -  if( iDb==0 ){
   405         -    sqlite3BtreeEnterAll(db);
          413  +  if( iDb>=0 ){
          414  +    /* Case 1:  Reset the single schema identified by iDb */
          415  +    Db *pDb = &db->aDb[iDb];
          416  +    assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
          417  +    if( ALWAYS(pDb->pSchema) ){
          418  +      sqlite3SchemaClear(pDb->pSchema);
          419  +    }
          420  +    /* If any database other than TEMP is reset, then also reset TEMP
          421  +    ** since TEMP might be holding triggers that reference tables in the
          422  +    ** other database.
          423  +    */
          424  +    if( iDb!=1 && (pDb = &db->aDb[1])!=0 && ALWAYS(pDb->pSchema) ){
          425  +      sqlite3SchemaClear(pDb->pSchema);
          426  +    }
          427  +    return;
   406    428     }
   407         -  for(i=iDb; i<db->nDb; i++){
          429  +  /* Case 2 (from here to the end): Reset all schemas for all attached
          430  +  ** databases. */
          431  +  assert( iDb<0 );
          432  +  sqlite3BtreeEnterAll(db);
          433  +  for(i=0; i<db->nDb; i++){
   408    434       Db *pDb = &db->aDb[i];
   409    435       if( pDb->pSchema ){
   410         -      assert(i==1 || (pDb->pBt && sqlite3BtreeHoldsMutex(pDb->pBt)));
   411         -      sqlite3SchemaFree(pDb->pSchema);
          436  +      sqlite3SchemaClear(pDb->pSchema);
   412    437       }
   413         -    if( iDb>0 ) return;
   414    438     }
   415         -  assert( iDb==0 );
   416    439     db->flags &= ~SQLITE_InternChanges;
   417    440     sqlite3VtabUnlockList(db);
   418    441     sqlite3BtreeLeaveAll(db);
   419    442   
   420    443     /* If one or more of the auxiliary database files has been closed,
   421    444     ** then remove them from the auxiliary database list.  We take the
   422    445     ** opportunity to do this here since we have just deleted all of the
................................................................................
   494    517       pNext = pIndex->pNext;
   495    518       assert( pIndex->pSchema==pTable->pSchema );
   496    519       if( !db || db->pnBytesFreed==0 ){
   497    520         char *zName = pIndex->zName; 
   498    521         TESTONLY ( Index *pOld = ) sqlite3HashInsert(
   499    522   	  &pIndex->pSchema->idxHash, zName, sqlite3Strlen30(zName), 0
   500    523         );
          524  +      assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
   501    525         assert( pOld==pIndex || pOld==0 );
   502    526       }
   503    527       freeIndex(db, pIndex);
   504    528     }
   505    529   
   506    530     /* Delete any foreign keys attached to this table. */
   507    531     sqlite3FkDelete(db, pTable);
................................................................................
   528    552   void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){
   529    553     Table *p;
   530    554     Db *pDb;
   531    555   
   532    556     assert( db!=0 );
   533    557     assert( iDb>=0 && iDb<db->nDb );
   534    558     assert( zTabName );
          559  +  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
   535    560     testcase( zTabName[0]==0 );  /* Zero-length table names are allowed */
   536    561     pDb = &db->aDb[iDb];
   537    562     p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName,
   538    563                           sqlite3Strlen30(zTabName),0);
   539    564     sqlite3DeleteTable(db, p);
   540    565     db->flags |= SQLITE_InternChanges;
   541    566   }
................................................................................
   812    837   
   813    838     /* If this is the magic sqlite_sequence table used by autoincrement,
   814    839     ** then record a pointer to this table in the main database structure
   815    840     ** so that INSERT can find the table easily.
   816    841     */
   817    842   #ifndef SQLITE_OMIT_AUTOINCREMENT
   818    843     if( !pParse->nested && strcmp(zName, "sqlite_sequence")==0 ){
          844  +    assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
   819    845       pTable->pSchema->pSeqTab = pTable;
   820    846     }
   821    847   #endif
   822    848   
   823    849     /* Begin generating the code that will insert the table record into
   824    850     ** the SQLITE_MASTER table.  Note in particular that we must go ahead
   825    851     ** and allocate the record number for the table entry now.  Before any
................................................................................
  1272   1298   ** and the probability of hitting the same cookie value is only
  1273   1299   ** 1 chance in 2^32.  So we're safe enough.
  1274   1300   */
  1275   1301   void sqlite3ChangeCookie(Parse *pParse, int iDb){
  1276   1302     int r1 = sqlite3GetTempReg(pParse);
  1277   1303     sqlite3 *db = pParse->db;
  1278   1304     Vdbe *v = pParse->pVdbe;
         1305  +  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  1279   1306     sqlite3VdbeAddOp2(v, OP_Integer, db->aDb[iDb].pSchema->schema_cookie+1, r1);
  1280   1307     sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, r1);
  1281   1308     sqlite3ReleaseTempReg(pParse, r1);
  1282   1309   }
  1283   1310   
  1284   1311   /*
  1285   1312   ** Measure the number of characters needed to output the given
................................................................................
  1574   1601   
  1575   1602   #ifndef SQLITE_OMIT_AUTOINCREMENT
  1576   1603       /* Check to see if we need to create an sqlite_sequence table for
  1577   1604       ** keeping track of autoincrement keys.
  1578   1605       */
  1579   1606       if( p->tabFlags & TF_Autoincrement ){
  1580   1607         Db *pDb = &db->aDb[iDb];
         1608  +      assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  1581   1609         if( pDb->pSchema->pSeqTab==0 ){
  1582   1610           sqlite3NestedParse(pParse,
  1583   1611             "CREATE TABLE %Q.sqlite_sequence(name,seq)",
  1584   1612             pDb->zName
  1585   1613           );
  1586   1614         }
  1587   1615       }
................................................................................
  1594   1622   
  1595   1623   
  1596   1624     /* Add the table to the in-memory representation of the database.
  1597   1625     */
  1598   1626     if( db->init.busy ){
  1599   1627       Table *pOld;
  1600   1628       Schema *pSchema = p->pSchema;
         1629  +    assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  1601   1630       pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName,
  1602   1631                                sqlite3Strlen30(p->zName),p);
  1603   1632       if( pOld ){
  1604   1633         assert( p==pOld );  /* Malloc must have failed inside HashInsert() */
  1605   1634         db->mallocFailed = 1;
  1606   1635         return;
  1607   1636       }
................................................................................
  1778   1807       if( pSelTab ){
  1779   1808         assert( pTable->aCol==0 );
  1780   1809         pTable->nCol = pSelTab->nCol;
  1781   1810         pTable->aCol = pSelTab->aCol;
  1782   1811         pSelTab->nCol = 0;
  1783   1812         pSelTab->aCol = 0;
  1784   1813         sqlite3DeleteTable(db, pSelTab);
         1814  +      assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) );
  1785   1815         pTable->pSchema->flags |= DB_UnresetViews;
  1786   1816       }else{
  1787   1817         pTable->nCol = 0;
  1788   1818         nErr++;
  1789   1819       }
  1790   1820       sqlite3SelectDelete(db, pSel);
  1791   1821     } else {
................................................................................
  1798   1828   
  1799   1829   #ifndef SQLITE_OMIT_VIEW
  1800   1830   /*
  1801   1831   ** Clear the column names from every VIEW in database idx.
  1802   1832   */
  1803   1833   static void sqliteViewResetAll(sqlite3 *db, int idx){
  1804   1834     HashElem *i;
         1835  +  assert( sqlite3SchemaMutexHeld(db, idx, 0) );
  1805   1836     if( !DbHasProperty(db, idx, DB_UnresetViews) ) return;
  1806   1837     for(i=sqliteHashFirst(&db->aDb[idx].pSchema->tblHash); i;i=sqliteHashNext(i)){
  1807   1838       Table *pTab = sqliteHashData(i);
  1808   1839       if( pTab->pSelect ){
  1809   1840         sqliteDeleteColumnNames(db, pTab);
  1810   1841         pTab->aCol = 0;
  1811   1842         pTab->nCol = 0;
................................................................................
  1831   1862   ** because the first match might be for one of the deleted indices
  1832   1863   ** or tables and not the table/index that is actually being moved.
  1833   1864   ** We must continue looping until all tables and indices with
  1834   1865   ** rootpage==iFrom have been converted to have a rootpage of iTo
  1835   1866   ** in order to be certain that we got the right one.
  1836   1867   */
  1837   1868   #ifndef SQLITE_OMIT_AUTOVACUUM
  1838         -void sqlite3RootPageMoved(Db *pDb, int iFrom, int iTo){
         1869  +void sqlite3RootPageMoved(sqlite3 *db, int iDb, int iFrom, int iTo){
  1839   1870     HashElem *pElem;
  1840   1871     Hash *pHash;
         1872  +  Db *pDb;
  1841   1873   
         1874  +  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
         1875  +  pDb = &db->aDb[iDb];
  1842   1876     pHash = &pDb->pSchema->tblHash;
  1843   1877     for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){
  1844   1878       Table *pTab = sqliteHashData(pElem);
  1845   1879       if( pTab->tnum==iFrom ){
  1846   1880         pTab->tnum = iTo;
  1847   1881       }
  1848   1882     }
................................................................................
  2208   2242         z += n+1;
  2209   2243       }
  2210   2244     }
  2211   2245     pFKey->isDeferred = 0;
  2212   2246     pFKey->aAction[0] = (u8)(flags & 0xff);            /* ON DELETE action */
  2213   2247     pFKey->aAction[1] = (u8)((flags >> 8 ) & 0xff);    /* ON UPDATE action */
  2214   2248   
         2249  +  assert( sqlite3SchemaMutexHeld(db, 0, p->pSchema) );
  2215   2250     pNextTo = (FKey *)sqlite3HashInsert(&p->pSchema->fkeyHash, 
  2216   2251         pFKey->zTo, sqlite3Strlen30(pFKey->zTo), (void *)pFKey
  2217   2252     );
  2218   2253     if( pNextTo==pFKey ){
  2219   2254       db->mallocFailed = 1;
  2220   2255       goto fk_end;
  2221   2256     }
................................................................................
  2563   2598     zExtra = (char *)(&pIndex->zName[nName+1]);
  2564   2599     memcpy(pIndex->zName, zName, nName+1);
  2565   2600     pIndex->pTable = pTab;
  2566   2601     pIndex->nColumn = pList->nExpr;
  2567   2602     pIndex->onError = (u8)onError;
  2568   2603     pIndex->autoIndex = (u8)(pName==0);
  2569   2604     pIndex->pSchema = db->aDb[iDb].pSchema;
         2605  +  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  2570   2606   
  2571   2607     /* Check to see if we should honor DESC requests on index columns
  2572   2608     */
  2573   2609     if( pDb->pSchema->file_format>=4 ){
  2574   2610       sortOrderMask = -1;   /* Honor DESC */
  2575   2611     }else{
  2576   2612       sortOrderMask = 0;    /* Ignore DESC */
................................................................................
  2692   2728     }
  2693   2729   
  2694   2730     /* Link the new Index structure to its table and to the other
  2695   2731     ** in-memory database structures. 
  2696   2732     */
  2697   2733     if( db->init.busy ){
  2698   2734       Index *p;
         2735  +    assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
  2699   2736       p = sqlite3HashInsert(&pIndex->pSchema->idxHash, 
  2700   2737                             pIndex->zName, sqlite3Strlen30(pIndex->zName),
  2701   2738                             pIndex);
  2702   2739       if( p ){
  2703   2740         assert( p==pIndex );  /* Malloc must have failed */
  2704   2741         db->mallocFailed = 1;
  2705   2742         goto exit_create_index;
................................................................................
  3445   3482     if( iDb>=0 ){
  3446   3483       sqlite3 *db = pToplevel->db;
  3447   3484       yDbMask mask;
  3448   3485   
  3449   3486       assert( iDb<db->nDb );
  3450   3487       assert( db->aDb[iDb].pBt!=0 || iDb==1 );
  3451   3488       assert( iDb<SQLITE_MAX_ATTACHED+2 );
         3489  +    assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  3452   3490       mask = ((yDbMask)1)<<iDb;
  3453   3491       if( (pToplevel->cookieMask & mask)==0 ){
  3454   3492         pToplevel->cookieMask |= mask;
  3455   3493         pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie;
  3456   3494         if( !OMIT_TEMPDB && iDb==1 ){
  3457   3495           sqlite3OpenTempDatabase(pToplevel);
  3458   3496         }
................................................................................
  3572   3610   static void reindexDatabases(Parse *pParse, char const *zColl){
  3573   3611     Db *pDb;                    /* A single database */
  3574   3612     int iDb;                    /* The database index number */
  3575   3613     sqlite3 *db = pParse->db;   /* The database connection */
  3576   3614     HashElem *k;                /* For looping over tables in pDb */
  3577   3615     Table *pTab;                /* A table in the database */
  3578   3616   
         3617  +  assert( sqlite3BtreeHoldsAllMutexes(db) );  /* Needed for schema access */
  3579   3618     for(iDb=0, pDb=db->aDb; iDb<db->nDb; iDb++, pDb++){
  3580   3619       assert( pDb!=0 );
  3581   3620       for(k=sqliteHashFirst(&pDb->pSchema->tblHash);  k; k=sqliteHashNext(k)){
  3582   3621         pTab = (Table*)sqliteHashData(k);
  3583   3622         reindexTable(pParse, pTab, zColl);
  3584   3623       }
  3585   3624     }

Changes to src/callback.c.

   396    396     }
   397    397     return 0;
   398    398   }
   399    399   
   400    400   /*
   401    401   ** Free all resources held by the schema structure. The void* argument points
   402    402   ** at a Schema struct. This function does not call sqlite3DbFree(db, ) on the 
   403         -** pointer itself, it just cleans up subsiduary resources (i.e. the contents
          403  +** pointer itself, it just cleans up subsidiary resources (i.e. the contents
   404    404   ** of the schema hash tables).
   405    405   **
   406    406   ** The Schema.cache_size variable is not cleared.
   407    407   */
   408         -void sqlite3SchemaFree(void *p){
          408  +void sqlite3SchemaClear(void *p){
   409    409     Hash temp1;
   410    410     Hash temp2;
   411    411     HashElem *pElem;
   412    412     Schema *pSchema = (Schema *)p;
   413    413   
   414    414     temp1 = pSchema->tblHash;
   415    415     temp2 = pSchema->trigHash;
................................................................................
   436    436   /*
   437    437   ** Find and return the schema associated with a BTree.  Create
   438    438   ** a new one if necessary.
   439    439   */
   440    440   Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){
   441    441     Schema * p;
   442    442     if( pBt ){
   443         -    p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaFree);
          443  +    p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaClear);
   444    444     }else{
   445    445       p = (Schema *)sqlite3DbMallocZero(0, sizeof(Schema));
   446    446     }
   447    447     if( !p ){
   448    448       db->mallocFailed = 1;
   449    449     }else if ( 0==p->file_format ){
   450    450       sqlite3HashInit(&p->tblHash);

Changes to src/delete.c.

    11     11   *************************************************************************
    12     12   ** This file contains C code routines that are called by the parser
    13     13   ** in order to generate code for DELETE FROM statements.
    14     14   */
    15     15   #include "sqliteInt.h"
    16     16   
    17     17   /*
    18         -** Look up every table that is named in pSrc.  If any table is not found,
    19         -** add an error message to pParse->zErrMsg and return NULL.  If all tables
    20         -** are found, return a pointer to the last table.
           18  +** While a SrcList can in general represent multiple tables and subqueries
           19  +** (as in the FROM clause of a SELECT statement) in this case it contains
           20  +** the name of a single table, as one might find in an INSERT, DELETE,
           21  +** or UPDATE statement.  Look up that table in the symbol table and
           22  +** return a pointer.  Set an error message and return NULL if the table 
           23  +** name is not found or if any other error occurs.
           24  +**
           25  +** The following fields are initialized appropriate in pSrc:
           26  +**
           27  +**    pSrc->a[0].pTab       Pointer to the Table object
           28  +**    pSrc->a[0].pIndex     Pointer to the INDEXED BY index, if there is one
           29  +**
    21     30   */
    22     31   Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){
    23     32     struct SrcList_item *pItem = pSrc->a;
    24     33     Table *pTab;
    25     34     assert( pItem && pSrc->nSrc==1 );
    26     35     pTab = sqlite3LocateTable(pParse, 0, pItem->zName, pItem->zDatabase);
    27     36     sqlite3DeleteTable(pParse->db, pItem->pTab);
................................................................................
   532    541     /* Delete the index and table entries. Skip this step if pTab is really
   533    542     ** a view (in which case the only effect of the DELETE statement is to
   534    543     ** fire the INSTEAD OF triggers).  */ 
   535    544     if( pTab->pSelect==0 ){
   536    545       sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, 0);
   537    546       sqlite3VdbeAddOp2(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0));
   538    547       if( count ){
   539         -      sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC);
          548  +      sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
   540    549       }
   541    550     }
   542    551   
   543    552     /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
   544    553     ** handle rows (possibly in other tables) that refer via a foreign key
   545    554     ** to the row just deleted. */ 
   546    555     sqlite3FkActions(pParse, pTab, 0, iOld);
................................................................................
   623    632       }else{
   624    633         sqlite3VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j);
   625    634         sqlite3ColumnDefault(v, pTab, idx, -1);
   626    635       }
   627    636     }
   628    637     if( doMakeRec ){
   629    638       sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut);
   630         -    sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), 0);
          639  +    sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT);
   631    640     }
   632    641     sqlite3ReleaseTempRange(pParse, regBase, nCol+1);
   633    642     return regBase;
   634    643   }

Changes to src/expr.c.

  2341   2341   #endif
  2342   2342       case TK_VARIABLE: {
  2343   2343         assert( !ExprHasProperty(pExpr, EP_IntValue) );
  2344   2344         assert( pExpr->u.zToken!=0 );
  2345   2345         assert( pExpr->u.zToken[0]!=0 );
  2346   2346         sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target);
  2347   2347         if( pExpr->u.zToken[1]!=0 ){
  2348         -        sqlite3VdbeChangeP4(v, -1, pExpr->u.zToken, 0);
         2348  +        sqlite3VdbeChangeP4(v, -1, pExpr->u.zToken, P4_TRANSIENT);
  2349   2349         }
  2350   2350         break;
  2351   2351       }
  2352   2352       case TK_REGISTER: {
  2353   2353         inReg = pExpr->iTable;
  2354   2354         break;
  2355   2355       }

Changes to src/fkey.c.

   394    394             int iParent = pIdx->aiColumn[i]+1+regData;
   395    395             sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent);
   396    396           }
   397    397           sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk);
   398    398         }
   399    399     
   400    400         sqlite3VdbeAddOp3(v, OP_MakeRecord, regTemp, nCol, regRec);
   401         -      sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), 0);
          401  +      sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v,pIdx), P4_TRANSIENT);
   402    402         sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0);
   403    403     
   404    404         sqlite3ReleaseTempReg(pParse, regRec);
   405    405         sqlite3ReleaseTempRange(pParse, regTemp, nCol);
   406    406       }
   407    407     }
   408    408   
................................................................................
  1150   1150   ** table pTab. Remove the deleted foreign keys from the Schema.fkeyHash
  1151   1151   ** hash table.
  1152   1152   */
  1153   1153   void sqlite3FkDelete(sqlite3 *db, Table *pTab){
  1154   1154     FKey *pFKey;                    /* Iterator variable */
  1155   1155     FKey *pNext;                    /* Copy of pFKey->pNextFrom */
  1156   1156   
         1157  +  assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) );
  1157   1158     for(pFKey=pTab->pFKey; pFKey; pFKey=pNext){
  1158   1159   
  1159   1160       /* Remove the FK from the fkeyHash hash table. */
  1160   1161       if( !db || db->pnBytesFreed==0 ){
  1161   1162         if( pFKey->pPrevTo ){
  1162   1163           pFKey->pPrevTo->pNextTo = pFKey->pNextTo;
  1163   1164         }else{

Changes to src/insert.c.

   119    119         zColAff[i] = pTab->aCol[i].affinity;
   120    120       }
   121    121       zColAff[pTab->nCol] = '\0';
   122    122   
   123    123       pTab->zColAff = zColAff;
   124    124     }
   125    125   
   126         -  sqlite3VdbeChangeP4(v, -1, pTab->zColAff, 0);
          126  +  sqlite3VdbeChangeP4(v, -1, pTab->zColAff, P4_TRANSIENT);
   127    127   }
   128    128   
   129    129   /*
   130    130   ** Return non-zero if the table pTab in database iDb or any of its indices
   131    131   ** have been opened at any point in the VDBE program beginning at location
   132    132   ** iStartAddr throught the end of the program.  This is used to see if 
   133    133   ** a statement of the form  "INSERT INTO <iDb, pTab> SELECT ..." can 
................................................................................
   233    233     assert( pParse->pTriggerTab==0 );
   234    234     assert( pParse==sqlite3ParseToplevel(pParse) );
   235    235   
   236    236     assert( v );   /* We failed long ago if this is not so */
   237    237     for(p = pParse->pAinc; p; p = p->pNext){
   238    238       pDb = &db->aDb[p->iDb];
   239    239       memId = p->regCtr;
          240  +    assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) );
   240    241       sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead);
   241    242       addr = sqlite3VdbeCurrentAddr(v);
   242    243       sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, p->pTab->zName, 0);
   243    244       sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9);
   244    245       sqlite3VdbeAddOp3(v, OP_Column, 0, 0, memId);
   245    246       sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId);
   246    247       sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
................................................................................
   283    284     for(p = pParse->pAinc; p; p = p->pNext){
   284    285       Db *pDb = &db->aDb[p->iDb];
   285    286       int j1, j2, j3, j4, j5;
   286    287       int iRec;
   287    288       int memId = p->regCtr;
   288    289   
   289    290       iRec = sqlite3GetTempReg(pParse);
          291  +    assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) );
   290    292       sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
   291    293       j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1);
   292    294       j2 = sqlite3VdbeAddOp0(v, OP_Rewind);
   293    295       j3 = sqlite3VdbeAddOp3(v, OP_Column, 0, 0, iRec);
   294    296       j4 = sqlite3VdbeAddOp3(v, OP_Eq, memId-1, 0, iRec);
   295    297       sqlite3VdbeAddOp2(v, OP_Next, 0, j3);
   296    298       sqlite3VdbeJumpHere(v, j2);
................................................................................
  1323   1325           sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
  1324   1326         }else{
  1325   1327           sqlite3VdbeAddOp2(v, OP_SCopy, regData+idx, regIdx+i);
  1326   1328         }
  1327   1329       }
  1328   1330       sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i);
  1329   1331       sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]);
  1330         -    sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), 0);
         1332  +    sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), P4_TRANSIENT);
  1331   1333       sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1);
  1332   1334   
  1333   1335   #ifdef SQLITE_OMIT_UNIQUE_ENFORCEMENT
  1334   1336       sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
  1335   1337       continue;  /* Treat pIdx as if it is not a UNIQUE index */
  1336   1338   #else
  1337   1339   
................................................................................
  1469   1471       pik_flags |= OPFLAG_APPEND;
  1470   1472     }
  1471   1473     if( useSeekResult ){
  1472   1474       pik_flags |= OPFLAG_USESEEKRESULT;
  1473   1475     }
  1474   1476     sqlite3VdbeAddOp3(v, OP_Insert, baseCur, regRec, regRowid);
  1475   1477     if( !pParse->nested ){
  1476         -    sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC);
         1478  +    sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
  1477   1479     }
  1478   1480     sqlite3VdbeChangeP5(v, pik_flags);
  1479   1481   }
  1480   1482   
  1481   1483   /*
  1482   1484   ** Generate code that will open cursors for a table and for all
  1483   1485   ** indices of that table.  The "baseCur" parameter is the cursor number used

Changes to src/main.c.

   686    686       return SQLITE_OK;
   687    687     }
   688    688     if( !sqlite3SafetyCheckSickOrOk(db) ){
   689    689       return SQLITE_MISUSE_BKPT;
   690    690     }
   691    691     sqlite3_mutex_enter(db->mutex);
   692    692   
   693         -  sqlite3ResetInternalSchema(db, 0);
          693  +  /* Force xDestroy calls on all virtual tables */
          694  +  sqlite3ResetInternalSchema(db, -1);
   694    695   
   695    696     /* If a transaction is open, the ResetInternalSchema() call above
   696    697     ** will not have called the xDisconnect() method on any virtual
   697    698     ** tables in the db->aVTrans[] array. The following sqlite3VtabRollback()
   698    699     ** call will do so. We need to do this before the check for active
   699    700     ** SQL statements below, as the v-table implementation may be storing
   700    701     ** some prepared statements internally.
................................................................................
   729    730         sqlite3BtreeClose(pDb->pBt);
   730    731         pDb->pBt = 0;
   731    732         if( j!=1 ){
   732    733           pDb->pSchema = 0;
   733    734         }
   734    735       }
   735    736     }
   736         -  sqlite3ResetInternalSchema(db, 0);
          737  +  sqlite3ResetInternalSchema(db, -1);
   737    738   
   738    739     /* Tell the code in notify.c that the connection no longer holds any
   739    740     ** locks and does not require any further unlock-notify callbacks.
   740    741     */
   741    742     sqlite3ConnectionClosed(db);
   742    743   
   743    744     assert( db->nDb<=2 );
................................................................................
   824    825       }
   825    826     }
   826    827     sqlite3VtabRollback(db);
   827    828     sqlite3EndBenignMalloc();
   828    829   
   829    830     if( db->flags&SQLITE_InternChanges ){
   830    831       sqlite3ExpirePreparedStatements(db);
   831         -    sqlite3ResetInternalSchema(db, 0);
          832  +    sqlite3ResetInternalSchema(db, -1);
   832    833     }
   833    834   
   834    835     /* Any deferred constraint violations have now been resolved. */
   835    836     db->nDeferredCons = 0;
   836    837   
   837    838     /* If one has been configured, invoke the rollback-hook callback */
   838    839     if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){

Changes to src/pragma.c.

   111    111       if( !db->autoCommit || sqlite3BtreeIsInReadTrans(db->aDb[1].pBt) ){
   112    112         sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
   113    113           "from within a transaction");
   114    114         return SQLITE_ERROR;
   115    115       }
   116    116       sqlite3BtreeClose(db->aDb[1].pBt);
   117    117       db->aDb[1].pBt = 0;
   118         -    sqlite3ResetInternalSchema(db, 0);
          118  +    sqlite3ResetInternalSchema(db, -1);
   119    119     }
   120    120     return SQLITE_OK;
   121    121   }
   122    122   #endif /* SQLITE_PAGER_PRAGMAS */
   123    123   
   124    124   #ifndef SQLITE_OMIT_PAGER_PRAGMAS
   125    125   /*
................................................................................
   385    385         sqlite3VdbeChangeP1(v, addr+1, iDb);
   386    386         sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE);
   387    387       }else{
   388    388         int size = sqlite3AbsInt32(sqlite3Atoi(zRight));
   389    389         sqlite3BeginWriteOperation(pParse, 0, iDb);
   390    390         sqlite3VdbeAddOp2(v, OP_Integer, size, 1);
   391    391         sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, 1);
          392  +      assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
   392    393         pDb->pSchema->cache_size = size;
   393    394         sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
   394    395       }
   395    396     }else
   396    397   
   397    398     /*
   398    399     **  PRAGMA [database.]page_size
................................................................................
   687    688     ** page cache size value.  It does not change the persistent
   688    689     ** cache size stored on the disk so the cache size will revert
   689    690     ** to its default value when the database is closed and reopened.
   690    691     ** N should be a positive integer.
   691    692     */
   692    693     if( sqlite3StrICmp(zLeft,"cache_size")==0 ){
   693    694       if( sqlite3ReadSchema(pParse) ) goto pragma_out;
          695  +    assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
   694    696       if( !zRight ){
   695    697         i64 cacheSize = pDb->pSchema->cache_size;
   696    698         returnSingleInt(pParse, "cache_size", &cacheSize);
   697    699       }else{
   698    700         int size = sqlite3AbsInt32(sqlite3Atoi(zRight));
   699    701         pDb->pSchema->cache_size = size;
   700    702         sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
................................................................................
  1110   1112         sqlite3VdbeJumpHere(v, addr);
  1111   1113   
  1112   1114         /* Do an integrity check of the B-Tree
  1113   1115         **
  1114   1116         ** Begin by filling registers 2, 3, ... with the root pages numbers
  1115   1117         ** for all tables and indices in the database.
  1116   1118         */
         1119  +      assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  1117   1120         pTbls = &db->aDb[i].pSchema->tblHash;
  1118   1121         for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
  1119   1122           Table *pTab = sqliteHashData(x);
  1120   1123           Index *pIdx;
  1121   1124           sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 2+cnt);
  1122   1125           cnt++;
  1123   1126           for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
................................................................................
  1175   1178               { OP_Halt,        0,  0,  0},
  1176   1179             };
  1177   1180             r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0);
  1178   1181             jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nColumn+1);
  1179   1182             addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
  1180   1183             sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC);
  1181   1184             sqlite3VdbeChangeP4(v, addr+3, " missing from index ", P4_STATIC);
  1182         -          sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_STATIC);
         1185  +          sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_TRANSIENT);
  1183   1186             sqlite3VdbeJumpHere(v, addr+9);
  1184   1187             sqlite3VdbeJumpHere(v, jmp2);
  1185   1188           }
  1186   1189           sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop+1);
  1187   1190           sqlite3VdbeJumpHere(v, loopTop);
  1188   1191           for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
  1189   1192             static const VdbeOpList cntIdx[] = {
................................................................................
  1205   1208             sqlite3VdbeChangeP1(v, addr+1, j+2);
  1206   1209             sqlite3VdbeChangeP2(v, addr+1, addr+4);
  1207   1210             sqlite3VdbeChangeP1(v, addr+3, j+2);
  1208   1211             sqlite3VdbeChangeP2(v, addr+3, addr+2);
  1209   1212             sqlite3VdbeJumpHere(v, addr+4);
  1210   1213             sqlite3VdbeChangeP4(v, addr+6, 
  1211   1214                        "wrong # of entries in index ", P4_STATIC);
  1212         -          sqlite3VdbeChangeP4(v, addr+7, pIdx->zName, P4_STATIC);
         1215  +          sqlite3VdbeChangeP4(v, addr+7, pIdx->zName, P4_TRANSIENT);
  1213   1216           }
  1214   1217         } 
  1215   1218       }
  1216   1219       addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
  1217   1220       sqlite3VdbeChangeP2(v, addr, -mxErr);
  1218   1221       sqlite3VdbeJumpHere(v, addr+1);
  1219   1222       sqlite3VdbeChangeP4(v, addr+2, "ok", P4_STATIC);

Changes to src/prepare.c.

   337    337       if( rc==SQLITE_OK ){
   338    338         sqlite3AnalysisLoad(db, iDb);
   339    339       }
   340    340   #endif
   341    341     }
   342    342     if( db->mallocFailed ){
   343    343       rc = SQLITE_NOMEM;
   344         -    sqlite3ResetInternalSchema(db, 0);
          344  +    sqlite3ResetInternalSchema(db, -1);
   345    345     }
   346    346     if( rc==SQLITE_OK || (db->flags&SQLITE_RecoveryMode)){
   347    347       /* Black magic: If the SQLITE_RecoveryMode flag is set, then consider
   348    348       ** the schema loaded, even if errors occurred. In this situation the 
   349    349       ** current sqlite3_prepare() operation will fail, but the following one
   350    350       ** will attempt to compile the supplied statement against whatever subset
   351    351       ** of the schema was loaded before the error occurred. The primary
................................................................................
   469    469         openedTransaction = 1;
   470    470       }
   471    471   
   472    472       /* Read the schema cookie from the database. If it does not match the 
   473    473       ** value stored as part of the in-memory schema representation,
   474    474       ** set Parse.rc to SQLITE_SCHEMA. */
   475    475       sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie);
          476  +    assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
   476    477       if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){
          478  +      sqlite3ResetInternalSchema(db, iDb);
   477    479         pParse->rc = SQLITE_SCHEMA;
   478    480       }
   479    481   
   480    482       /* Close the transaction, if one was opened. */
   481    483       if( openedTransaction ){
   482    484         sqlite3BtreeCommit(pBt);
   483    485       }
................................................................................
   611    613     if( db->mallocFailed ){
   612    614       pParse->rc = SQLITE_NOMEM;
   613    615     }
   614    616     if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK;
   615    617     if( pParse->checkSchema ){
   616    618       schemaIsValid(pParse);
   617    619     }
   618         -  if( pParse->rc==SQLITE_SCHEMA ){
   619         -    sqlite3ResetInternalSchema(db, 0);
   620         -  }
   621    620     if( db->mallocFailed ){
   622    621       pParse->rc = SQLITE_NOMEM;
   623    622     }
   624    623     if( pzTail ){
   625    624       *pzTail = pParse->zTail;
   626    625     }
   627    626     rc = pParse->rc;

Changes to src/sqliteInt.h.

   664    664     u8 inTrans;          /* 0: not writable.  1: Transaction.  2: Checkpoint */
   665    665     u8 safety_level;     /* How aggressive at syncing data to disk */
   666    666     Schema *pSchema;     /* Pointer to database schema (possibly shared) */
   667    667   };
   668    668   
   669    669   /*
   670    670   ** An instance of the following structure stores a database schema.
          671  +**
          672  +** Most Schema objects are associated with a Btree.  The exception is
          673  +** the Schema for the TEMP databaes (sqlite3.aDb[1]) which is free-standing.
          674  +** In shared cache mode, a single Schema object can be shared by multiple
          675  +** Btrees that refer to the same underlying BtShared object.
          676  +** 
          677  +** Schema objects are automatically deallocated when the last Btree that
          678  +** references them is destroyed.   The TEMP Schema is manually freed by
          679  +** sqlite3_close().
          680  +*
          681  +** A thread must be holding a mutex on the corresponding Btree in order
          682  +** to access Schema content.  This implies that the thread must also be
          683  +** holding a mutex on the sqlite3 connection pointer that owns the Btree.
          684  +** For a TEMP Schema, on the connection mutex is required.
   671    685   */
   672    686   struct Schema {
   673    687     int schema_cookie;   /* Database schema version number for this file */
   674    688     int iGeneration;     /* Generation counter.  Incremented with each change */
   675    689     Hash tblHash;        /* All tables indexed by name */
   676    690     Hash idxHash;        /* All (named) indices indexed by name */
   677    691     Hash trigHash;       /* All triggers indexed by name */
................................................................................
  1180   1194   ** schema. This is because each database connection requires its own unique
  1181   1195   ** instance of the sqlite3_vtab* handle used to access the virtual table 
  1182   1196   ** implementation. sqlite3_vtab* handles can not be shared between 
  1183   1197   ** database connections, even when the rest of the in-memory database 
  1184   1198   ** schema is shared, as the implementation often stores the database
  1185   1199   ** connection handle passed to it via the xConnect() or xCreate() method
  1186   1200   ** during initialization internally. This database connection handle may
  1187         -** then used by the virtual table implementation to access real tables 
         1201  +** then be used by the virtual table implementation to access real tables 
  1188   1202   ** within the database. So that they appear as part of the callers 
  1189   1203   ** transaction, these accesses need to be made via the same database 
  1190   1204   ** connection as that used to execute SQL operations on the virtual table.
  1191   1205   **
  1192   1206   ** All VTable objects that correspond to a single table in a shared
  1193   1207   ** database schema are initially stored in a linked-list pointed to by
  1194   1208   ** the Table.pVTable member variable of the corresponding Table object.
................................................................................
  2938   2952   extern const Token sqlite3IntTokens[];
  2939   2953   extern SQLITE_WSD struct Sqlite3Config sqlite3Config;
  2940   2954   extern SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
  2941   2955   #ifndef SQLITE_OMIT_WSD
  2942   2956   extern int sqlite3PendingByte;
  2943   2957   #endif
  2944   2958   #endif
  2945         -void sqlite3RootPageMoved(Db*, int, int);
         2959  +void sqlite3RootPageMoved(sqlite3*, int, int, int);
  2946   2960   void sqlite3Reindex(Parse*, Token*, Token*);
  2947   2961   void sqlite3AlterFunctions(void);
  2948   2962   void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
  2949   2963   int sqlite3GetToken(const unsigned char *, int *);
  2950   2964   void sqlite3NestedParse(Parse*, const char*, ...);
  2951   2965   void sqlite3ExpirePreparedStatements(sqlite3*);
  2952   2966   int sqlite3CodeSubselect(Parse *, Expr *, int, int);
................................................................................
  2965   2979   int sqlite3FindDbName(sqlite3 *, const char *);
  2966   2980   int sqlite3AnalysisLoad(sqlite3*,int iDB);
  2967   2981   void sqlite3DeleteIndexSamples(sqlite3*,Index*);
  2968   2982   void sqlite3DefaultRowEst(Index*);
  2969   2983   void sqlite3RegisterLikeFunctions(sqlite3*, int);
  2970   2984   int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
  2971   2985   void sqlite3MinimumFileFormat(Parse*, int, int);
  2972         -void sqlite3SchemaFree(void *);
         2986  +void sqlite3SchemaClear(void *);
  2973   2987   Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
  2974   2988   int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
  2975   2989   KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);
  2976   2990   int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, 
  2977   2991     void (*)(sqlite3_context*,int,sqlite3_value **),
  2978   2992     void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*),
  2979   2993     FuncDestructor *pDestructor

Changes to src/status.c.

   159    159       ** to store the schema for all databases (main, temp, and any ATTACHed
   160    160       ** databases.  *pHighwater is set to zero.
   161    161       */
   162    162       case SQLITE_DBSTATUS_SCHEMA_USED: {
   163    163         int i;                      /* Used to iterate through schemas */
   164    164         int nByte = 0;              /* Used to accumulate return value */
   165    165   
          166  +      sqlite3BtreeEnterAll(db);
   166    167         db->pnBytesFreed = &nByte;
   167    168         for(i=0; i<db->nDb; i++){
   168    169           Schema *pSchema = db->aDb[i].pSchema;
   169    170           if( ALWAYS(pSchema!=0) ){
   170    171             HashElem *p;
   171    172   
   172    173             nByte += sqlite3GlobalConfig.m.xRoundup(sizeof(HashElem)) * (
................................................................................
   185    186             }
   186    187             for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){
   187    188               sqlite3DeleteTable(db, (Table *)sqliteHashData(p));
   188    189             }
   189    190           }
   190    191         }
   191    192         db->pnBytesFreed = 0;
          193  +      sqlite3BtreeLeaveAll(db);
   192    194   
   193    195         *pHighwater = 0;
   194    196         *pCurrent = nByte;
   195    197         break;
   196    198       }
   197    199   
   198    200       /*

Changes to src/test4.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Code for testing the the SQLite library in a multithreaded environment.
    13     13   */
    14     14   #include "sqliteInt.h"
    15     15   #include "tcl.h"
    16         -#if defined(SQLITE_OS_UNIX) && OS_UNIX==1 && SQLITE_THREADSAFE
           16  +#if SQLITE_OS_UNIX && SQLITE_THREADSAFE
    17     17   #include <stdlib.h>
    18     18   #include <string.h>
    19     19   #include <pthread.h>
    20     20   #include <sched.h>
    21     21   #include <ctype.h>
    22     22   
    23     23   /*

Changes to src/test7.c.

    16     16   #include "tcl.h"
    17     17   
    18     18   /*
    19     19   ** This test only works on UNIX with a SQLITE_THREADSAFE build that includes
    20     20   ** the SQLITE_SERVER option.
    21     21   */
    22     22   #if defined(SQLITE_SERVER) && !defined(SQLITE_OMIT_SHARED_CACHE) && \
    23         -    defined(SQLITE_OS_UNIX) && OS_UNIX && SQLITE_THREADSAFE
           23  +    SQLITE_OS_UNIX && SQLITE_THREADSAFE
    24     24   
    25     25   #include <stdlib.h>
    26     26   #include <string.h>
    27     27   #include <pthread.h>
    28     28   #include <sched.h>
    29     29   #include <ctype.h>
    30     30   

Changes to src/test_demovfs.c.

   111    111   **                        0             12
   112    112   **             ++++++++++++SYNC+++++++++++
   113    113   **
   114    114   **   Much more efficient if the underlying OS is not caching write 
   115    115   **   operations.
   116    116   */
   117    117   
   118         -#if !defined(SQLITE_TEST) || defined(SQLITE_OS_UNIX)
          118  +#if !defined(SQLITE_TEST) || SQLITE_OS_UNIX
   119    119   
   120    120   #include <sqlite3.h>
   121    121   
   122    122   #include <assert.h>
   123    123   #include <string.h>
   124    124   #include <sys/types.h>
   125    125   #include <sys/stat.h>
................................................................................
   633    633       demoRandomness,               /* xRandomness */
   634    634       demoSleep,                    /* xSleep */
   635    635       demoCurrentTime,              /* xCurrentTime */
   636    636     };
   637    637     return &demovfs;
   638    638   }
   639    639   
   640         -#endif /* !defined(SQLITE_TEST) || defined(SQLITE_OS_UNIX) */
          640  +#endif /* !defined(SQLITE_TEST) || SQLITE_OS_UNIX */
   641    641   
   642    642   
   643    643   #ifdef SQLITE_TEST
   644    644   
   645    645   #include <tcl.h>
   646    646   
   647         -#ifdef SQLITE_OS_UNIX
          647  +#if SQLITE_OS_UNIX
   648    648   static int register_demovfs(
   649    649     ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
   650    650     Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
   651    651     int objc,              /* Number of arguments */
   652    652     Tcl_Obj *CONST objv[]  /* Command arguments */
   653    653   ){
   654    654     sqlite3_vfs_register(sqlite3_demovfs(), 1);

Changes to src/test_osinst.c.

   209    209     vfslogDeviceCharacteristics,    /* xDeviceCharacteristics */
   210    210     vfslogShmMap,                   /* xShmMap */
   211    211     vfslogShmLock,                  /* xShmLock */
   212    212     vfslogShmBarrier,               /* xShmBarrier */
   213    213     vfslogShmUnmap                  /* xShmUnmap */
   214    214   };
   215    215   
   216         -#if defined(SQLITE_OS_UNIX) && !defined(NO_GETTOD)
          216  +#if SQLITE_OS_UNIX && !defined(NO_GETTOD)
   217    217   #include <sys/time.h>
   218    218   static sqlite3_uint64 vfslog_time(){
   219    219     struct timeval sTime;
   220    220     gettimeofday(&sTime, 0);
   221    221     return sTime.tv_usec + (sqlite3_uint64)sTime.tv_sec * 1000000;
   222    222   }
   223         -#elif defined(SQLITE_OS_WIN)
          223  +#elif SQLITE_OS_WIN
   224    224   #include <windows.h>
   225    225   #include <time.h>
   226    226   static sqlite3_uint64 vfslog_time(){
   227    227     FILETIME ft;
   228    228     sqlite3_uint64 u64time = 0;
   229    229    
   230    230     GetSystemTimeAsFileTime(&ft);

Changes to src/test_server.c.

   202    202   #include "sqliteInt.h"
   203    203   
   204    204   /*
   205    205   ** Only compile the code in this file on UNIX with a SQLITE_THREADSAFE build
   206    206   ** and only if the SQLITE_SERVER macro is defined.
   207    207   */
   208    208   #if defined(SQLITE_SERVER) && !defined(SQLITE_OMIT_SHARED_CACHE)
   209         -#if defined(SQLITE_OS_UNIX) && OS_UNIX && SQLITE_THREADSAFE
          209  +#if SQLITE_OS_UNIX && SQLITE_THREADSAFE
   210    210   
   211    211   /*
   212    212   ** We require only pthreads and the public interface of SQLite.
   213    213   */
   214    214   #include <pthread.h>
   215    215   #include "sqlite3.h"
   216    216   
................................................................................
   483    483   void sqlite3_server_stop(void){
   484    484     g.serverHalt = 1;
   485    485     pthread_cond_broadcast(&g.serverWakeup);
   486    486     pthread_mutex_lock(&g.serverMutex);
   487    487     pthread_mutex_unlock(&g.serverMutex);
   488    488   }
   489    489   
   490         -#endif /* defined(SQLITE_OS_UNIX) && OS_UNIX && SQLITE_THREADSAFE */
          490  +#endif /* SQLITE_OS_UNIX && SQLITE_THREADSAFE */
   491    491   #endif /* defined(SQLITE_SERVER) */

Changes to src/test_syscall.c.

    71     71   
    72     72   #include "sqlite3.h"
    73     73   #include "tcl.h"
    74     74   #include <stdlib.h>
    75     75   #include <string.h>
    76     76   #include <assert.h>
    77     77   
    78         -#ifdef SQLITE_OS_UNIX
           78  +#include "sqliteInt.h"
           79  +#if SQLITE_OS_UNIX
    79     80   
    80     81   /* From test1.c */
    81     82   extern const char *sqlite3TestErrorName(int);
    82     83   
    83     84   #include <sys/types.h>
    84     85   #include <errno.h>
    85     86   

Changes to src/test_thread.c.

    49     49     Tcl_Event base;          /* Base class of type Tcl_Event */
    50     50     char *zScript;           /* The script to execute. */
    51     51     Tcl_Interp *interp;      /* The interpreter to execute it in. */
    52     52   };
    53     53   
    54     54   static Tcl_ObjCmdProc sqlthread_proc;
    55     55   static Tcl_ObjCmdProc clock_seconds_proc;
    56         -#if defined(SQLITE_OS_UNIX) && defined(SQLITE_ENABLE_UNLOCK_NOTIFY)
           56  +#if SQLITE_OS_UNIX && defined(SQLITE_ENABLE_UNLOCK_NOTIFY)
    57     57   static Tcl_ObjCmdProc blocking_step_proc;
    58     58   static Tcl_ObjCmdProc blocking_prepare_v2_proc;
    59     59   #endif
    60     60   int Sqlitetest1_Init(Tcl_Interp *);
    61     61   int Sqlite3_Init(Tcl_Interp *);
    62     62   
    63     63   /* Functions from test1.c */
................................................................................
   112    112     int rc;
   113    113     SqlThread *p = (SqlThread *)pSqlThread;
   114    114     extern int Sqlitetest_mutex_Init(Tcl_Interp*);
   115    115   
   116    116     interp = Tcl_CreateInterp();
   117    117     Tcl_CreateObjCommand(interp, "clock_seconds", clock_seconds_proc, 0, 0);
   118    118     Tcl_CreateObjCommand(interp, "sqlthread", sqlthread_proc, pSqlThread, 0);
   119         -#if defined(SQLITE_OS_UNIX) && defined(SQLITE_ENABLE_UNLOCK_NOTIFY)
          119  +#if SQLITE_OS_UNIX && defined(SQLITE_ENABLE_UNLOCK_NOTIFY)
   120    120     Tcl_CreateObjCommand(interp, "sqlite3_blocking_step", blocking_step_proc,0,0);
   121    121     Tcl_CreateObjCommand(interp, 
   122    122         "sqlite3_blocking_prepare_v2", blocking_prepare_v2_proc, (void *)1, 0);
   123    123     Tcl_CreateObjCommand(interp, 
   124    124         "sqlite3_nonblocking_prepare_v2", blocking_prepare_v2_proc, 0, 0);
   125    125   #endif
   126    126     Sqlitetest1_Init(interp);
................................................................................
   388    388   ** The source code for the C functions sqlite3_blocking_step(),
   389    389   ** blocking_step_notify() and the structure UnlockNotification is
   390    390   ** automatically extracted from this file and used as part of the
   391    391   ** documentation for the sqlite3_unlock_notify() API function. This
   392    392   ** should be considered if these functions are to be extended (i.e. to 
   393    393   ** support windows) in the future.
   394    394   */ 
   395         -#if defined(SQLITE_OS_UNIX) && defined(SQLITE_ENABLE_UNLOCK_NOTIFY)
          395  +#if SQLITE_OS_UNIX && defined(SQLITE_ENABLE_UNLOCK_NOTIFY)
   396    396   
   397    397   /* BEGIN_SQLITE_BLOCKING_STEP */
   398    398   /* This example uses the pthreads API */
   399    399   #include <pthread.h>
   400    400   
   401    401   /*
   402    402   ** A pointer to an instance of this structure is passed as the user-context
................................................................................
   610    610   
   611    611   /*
   612    612   ** Register commands with the TCL interpreter.
   613    613   */
   614    614   int SqlitetestThread_Init(Tcl_Interp *interp){
   615    615     Tcl_CreateObjCommand(interp, "sqlthread", sqlthread_proc, 0, 0);
   616    616     Tcl_CreateObjCommand(interp, "clock_seconds", clock_seconds_proc, 0, 0);
   617         -#if defined(SQLITE_OS_UNIX) && defined(SQLITE_ENABLE_UNLOCK_NOTIFY)
          617  +#if SQLITE_OS_UNIX && defined(SQLITE_ENABLE_UNLOCK_NOTIFY)
   618    618     Tcl_CreateObjCommand(interp, "sqlite3_blocking_step", blocking_step_proc,0,0);
   619    619     Tcl_CreateObjCommand(interp, 
   620    620         "sqlite3_blocking_prepare_v2", blocking_prepare_v2_proc, (void *)1, 0);
   621    621     Tcl_CreateObjCommand(interp, 
   622    622         "sqlite3_nonblocking_prepare_v2", blocking_prepare_v2_proc, 0, 0);
   623    623   #endif
   624    624     return TCL_OK;
   625    625   }
   626    626   #else
   627    627   int SqlitetestThread_Init(Tcl_Interp *interp){
   628    628     return TCL_OK;
   629    629   }
   630    630   #endif

Changes to src/trigger.c.

    50     50   
    51     51     if( pParse->disableTriggers ){
    52     52       return 0;
    53     53     }
    54     54   
    55     55     if( pTmpSchema!=pTab->pSchema ){
    56     56       HashElem *p;
           57  +    assert( sqlite3SchemaMutexHeld(pParse->db, 0, pTmpSchema) );
    57     58       for(p=sqliteHashFirst(&pTmpSchema->trigHash); p; p=sqliteHashNext(p)){
    58     59         Trigger *pTrig = (Trigger *)sqliteHashData(p);
    59     60         if( pTrig->pTabSchema==pTab->pSchema
    60     61          && 0==sqlite3StrICmp(pTrig->table, pTab->zName) 
    61     62         ){
    62     63           pTrig->pNext = (pList ? pList : pTab->pTrigger);
    63     64           pList = pTrig;
................................................................................
   161    162   
   162    163     /* Check that the trigger name is not reserved and that no trigger of the
   163    164     ** specified name exists */
   164    165     zName = sqlite3NameFromToken(db, pName);
   165    166     if( !zName || SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
   166    167       goto trigger_cleanup;
   167    168     }
          169  +  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
   168    170     if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),
   169    171                         zName, sqlite3Strlen30(zName)) ){
   170    172       if( !noErr ){
   171    173         sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
   172    174       }
   173    175       goto trigger_cleanup;
   174    176     }
................................................................................
   300    302           db, "type='trigger' AND name='%q'", zName), P4_DYNAMIC
   301    303       );
   302    304     }
   303    305   
   304    306     if( db->init.busy ){
   305    307       Trigger *pLink = pTrig;
   306    308       Hash *pHash = &db->aDb[iDb].pSchema->trigHash;
          309  +    assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
   307    310       pTrig = sqlite3HashInsert(pHash, zName, sqlite3Strlen30(zName), pTrig);
   308    311       if( pTrig ){
   309    312         db->mallocFailed = 1;
   310    313       }else if( pLink->pSchema==pLink->pTabSchema ){
   311    314         Table *pTab;
   312    315         int n = sqlite3Strlen30(pLink->table);
   313    316         pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table, n);
................................................................................
   481    484       goto drop_trigger_cleanup;
   482    485     }
   483    486   
   484    487     assert( pName->nSrc==1 );
   485    488     zDb = pName->a[0].zDatabase;
   486    489     zName = pName->a[0].zName;
   487    490     nName = sqlite3Strlen30(zName);
          491  +  assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
   488    492     for(i=OMIT_TEMPDB; i<db->nDb; i++){
   489    493       int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
   490    494       if( zDb && sqlite3StrICmp(db->aDb[j].zName, zDb) ) continue;
          495  +    assert( sqlite3SchemaMutexHeld(db, j, 0) );
   491    496       pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName, nName);
   492    497       if( pTrigger ) break;
   493    498     }
   494    499     if( !pTrigger ){
   495    500       if( !noErr ){
   496    501         sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0);
   497    502       }
................................................................................
   557    562         { OP_Delete,     0, 0,        0},
   558    563         { OP_Next,       0, ADDR(1),  0}, /* 8 */
   559    564       };
   560    565   
   561    566       sqlite3BeginWriteOperation(pParse, 0, iDb);
   562    567       sqlite3OpenMasterTable(pParse, iDb);
   563    568       base = sqlite3VdbeAddOpList(v,  ArraySize(dropTrigger), dropTrigger);
   564         -    sqlite3VdbeChangeP4(v, base+1, pTrigger->zName, 0);
          569  +    sqlite3VdbeChangeP4(v, base+1, pTrigger->zName, P4_TRANSIENT);
   565    570       sqlite3VdbeChangeP4(v, base+4, "trigger", P4_STATIC);
   566    571       sqlite3ChangeCookie(pParse, iDb);
   567    572       sqlite3VdbeAddOp2(v, OP_Close, 0, 0);
   568    573       sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0);
   569    574       if( pParse->nMem<3 ){
   570    575         pParse->nMem = 3;
   571    576       }
................................................................................
   572    577     }
   573    578   }
   574    579   
   575    580   /*
   576    581   ** Remove a trigger from the hash tables of the sqlite* pointer.
   577    582   */
   578    583   void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){
   579         -  Hash *pHash = &(db->aDb[iDb].pSchema->trigHash);
   580    584     Trigger *pTrigger;
          585  +  Hash *pHash;
          586  +
          587  +  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
          588  +  pHash = &(db->aDb[iDb].pSchema->trigHash);
   581    589     pTrigger = sqlite3HashInsert(pHash, zName, sqlite3Strlen30(zName), 0);
   582    590     if( ALWAYS(pTrigger) ){
   583    591       if( pTrigger->pSchema==pTrigger->pTabSchema ){
   584    592         Table *pTab = tableOfTrigger(pTrigger);
   585    593         Trigger **pp;
   586    594         for(pp=&pTab->pTrigger; *pp!=pTrigger; pp=&((*pp)->pNext));
   587    595         *pp = (*pp)->pNext;

Changes to src/vacuum.c.

   331    331   
   332    332     if( pDb ){
   333    333       sqlite3BtreeClose(pDb->pBt);
   334    334       pDb->pBt = 0;
   335    335       pDb->pSchema = 0;
   336    336     }
   337    337   
   338         -  sqlite3ResetInternalSchema(db, 0);
          338  +  /* This both clears the schemas and reduces the size of the db->aDb[]
          339  +  ** array. */ 
          340  +  sqlite3ResetInternalSchema(db, -1);
   339    341   
   340    342     return rc;
   341    343   }
          344  +
   342    345   #endif  /* SQLITE_OMIT_VACUUM && SQLITE_OMIT_ATTACH */

Changes to src/vdbe.c.

   547    547     Vdbe *p                    /* The VDBE */
   548    548   ){
   549    549     int pc=0;                  /* The program counter */
   550    550     Op *aOp = p->aOp;          /* Copy of p->aOp */
   551    551     Op *pOp;                   /* Current operation */
   552    552     int rc = SQLITE_OK;        /* Value to return */
   553    553     sqlite3 *db = p->db;       /* The database */
   554         -  u8 resetSchemaOnFault = 0; /* Reset schema after an error if true */
          554  +  u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
   555    555     u8 encoding = ENC(db);     /* The database encoding */
   556    556   #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
   557    557     int checkProgress;         /* True if progress callbacks are enabled */
   558    558     int nProgressOps = 0;      /* Opcodes executed since progress callback. */
   559    559   #endif
   560    560     Mem *aMem = p->aMem;       /* Copy of p->aMem */
   561    561     Mem *pIn1 = 0;             /* 1st input operand */
................................................................................
  2655   2655             rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint);
  2656   2656             if( rc!=SQLITE_OK ){
  2657   2657               goto abort_due_to_error;
  2658   2658             }
  2659   2659           }
  2660   2660           if( p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
  2661   2661             sqlite3ExpirePreparedStatements(db);
  2662         -          sqlite3ResetInternalSchema(db, 0);
         2662  +          sqlite3ResetInternalSchema(db, -1);
  2663   2663             sqlite3VdbeMutexResync(p);
  2664   2664             db->flags = (db->flags | SQLITE_InternChanges);
  2665   2665           }
  2666   2666         }
  2667   2667     
  2668   2668         /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all 
  2669   2669         ** savepoints nested inside of the savepoint being operated on. */
................................................................................
  2876   2876   case OP_SetCookie: {       /* in3 */
  2877   2877     Db *pDb;
  2878   2878     assert( pOp->p2<SQLITE_N_BTREE_META );
  2879   2879     assert( pOp->p1>=0 && pOp->p1<db->nDb );
  2880   2880     assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
  2881   2881     pDb = &db->aDb[pOp->p1];
  2882   2882     assert( pDb->pBt!=0 );
         2883  +  assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
  2883   2884     pIn3 = &aMem[pOp->p3];
  2884   2885     sqlite3VdbeMemIntegerify(pIn3);
  2885   2886     /* See note about index shifting on OP_ReadCookie */
  2886   2887     rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, (int)pIn3->u.i);
  2887   2888     if( pOp->p2==BTREE_SCHEMA_VERSION ){
  2888   2889       /* When the schema cookie changes, record the new cookie internally */
  2889   2890       pDb->pSchema->schema_cookie = (int)pIn3->u.i;
................................................................................
  2922   2923   case OP_VerifyCookie: {
  2923   2924     int iMeta;
  2924   2925     int iGen;
  2925   2926     Btree *pBt;
  2926   2927   
  2927   2928     assert( pOp->p1>=0 && pOp->p1<db->nDb );
  2928   2929     assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
         2930  +  assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
  2929   2931     pBt = db->aDb[pOp->p1].pBt;
  2930   2932     if( pBt ){
  2931   2933       sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta);
  2932   2934       iGen = db->aDb[pOp->p1].pSchema->iGeneration;
  2933   2935     }else{
  2934   2936       iMeta = 0;
  2935   2937     }
................................................................................
  2947   2949       ** discard the database schema, as the user code implementing the
  2948   2950       ** v-table would have to be ready for the sqlite3_vtab structure itself
  2949   2951       ** to be invalidated whenever sqlite3_step() is called from within 
  2950   2952       ** a v-table method.
  2951   2953       */
  2952   2954       if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){
  2953   2955         sqlite3ResetInternalSchema(db, pOp->p1);
  2954         -      sqlite3VdbeMutexResync(p);
  2955   2956       }
  2956   2957   
  2957   2958       p->expired = 1;
  2958   2959       rc = SQLITE_SCHEMA;
  2959   2960     }
  2960   2961     break;
  2961   2962   }
................................................................................
  3032   3033     assert( iDb>=0 && iDb<db->nDb );
  3033   3034     assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 );
  3034   3035     pDb = &db->aDb[iDb];
  3035   3036     pX = pDb->pBt;
  3036   3037     assert( pX!=0 );
  3037   3038     if( pOp->opcode==OP_OpenWrite ){
  3038   3039       wrFlag = 1;
         3040  +    assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  3039   3041       if( pDb->pSchema->file_format < p->minWriteFileFormat ){
  3040   3042         p->minWriteFileFormat = pDb->pSchema->file_format;
  3041   3043       }
  3042   3044     }else{
  3043   3045       wrFlag = 0;
  3044   3046     }
  3045   3047     if( pOp->p5 ){
................................................................................
  4527   4529       assert( iCnt==1 );
  4528   4530       assert( (p->btreeMask & (((yDbMask)1)<<iDb))!=0 );
  4529   4531       rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved);
  4530   4532       pOut->flags = MEM_Int;
  4531   4533       pOut->u.i = iMoved;
  4532   4534   #ifndef SQLITE_OMIT_AUTOVACUUM
  4533   4535       if( rc==SQLITE_OK && iMoved!=0 ){
  4534         -      sqlite3RootPageMoved(&db->aDb[iDb], iMoved, pOp->p1);
  4535         -      resetSchemaOnFault = 1;
         4536  +      sqlite3RootPageMoved(db, iDb, iMoved, pOp->p1);
         4537  +      /* All OP_Destroy operations occur on the same btree */
         4538  +      assert( resetSchemaOnFault==0 || resetSchemaOnFault==iDb+1 );
         4539  +      resetSchemaOnFault = iDb+1;
  4536   4540       }
  4537   4541   #endif
  4538   4542     }
  4539   4543     break;
  4540   4544   }
  4541   4545   
  4542   4546   /* Opcode: Clear P1 P2 P3
................................................................................
  5962   5966     p->rc = rc;
  5963   5967     testcase( sqlite3GlobalConfig.xLog!=0 );
  5964   5968     sqlite3_log(rc, "statement aborts at %d: [%s] %s", 
  5965   5969                      pc, p->zSql, p->zErrMsg);
  5966   5970     sqlite3VdbeHalt(p);
  5967   5971     if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
  5968   5972     rc = SQLITE_ERROR;
  5969         -  if( resetSchemaOnFault ){
  5970         -    sqlite3ResetInternalSchema(db, 0);
  5971         -    sqlite3VdbeMutexResync(p);
         5973  +  if( resetSchemaOnFault>0 ){
         5974  +    sqlite3ResetInternalSchema(db, resetSchemaOnFault-1);
  5972   5975     }
  5973   5976   
  5974   5977     /* This is the only way out of this procedure.  We have to
  5975   5978     ** release the mutexes on btrees that were acquired at the
  5976   5979     ** top. */
  5977   5980   vdbe_return:
  5978   5981     sqlite3VdbeLeave(p);

Changes to src/vdbe.h.

   104    104   #define P4_DYNAMIC  (-1)  /* Pointer to a string obtained from sqliteMalloc() */
   105    105   #define P4_STATIC   (-2)  /* Pointer to a static string */
   106    106   #define P4_COLLSEQ  (-4)  /* P4 is a pointer to a CollSeq structure */
   107    107   #define P4_FUNCDEF  (-5)  /* P4 is a pointer to a FuncDef structure */
   108    108   #define P4_KEYINFO  (-6)  /* P4 is a pointer to a KeyInfo structure */
   109    109   #define P4_VDBEFUNC (-7)  /* P4 is a pointer to a VdbeFunc structure */
   110    110   #define P4_MEM      (-8)  /* P4 is a pointer to a Mem*    structure */
   111         -#define P4_TRANSIENT (-9) /* P4 is a pointer to a transient string */
          111  +#define P4_TRANSIENT  0   /* P4 is a pointer to a transient string */
   112    112   #define P4_VTAB     (-10) /* P4 is a pointer to an sqlite3_vtab structure */
   113    113   #define P4_MPRINTF  (-11) /* P4 is a string obtained from sqlite3_mprintf() */
   114    114   #define P4_REAL     (-12) /* P4 is a 64-bit floating point value */
   115    115   #define P4_INT64    (-13) /* P4 is a 64-bit signed integer */
   116    116   #define P4_INT32    (-14) /* P4 is a 32-bit signed integer */
   117    117   #define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
   118    118   #define P4_SUBPROGRAM  (-18) /* P4 is a pointer to a SubProgram structure */

Changes to src/vdbeaux.c.

  2274   2274           sqlite3VdbeSetChanges(db, 0);
  2275   2275         }
  2276   2276         p->nChange = 0;
  2277   2277       }
  2278   2278     
  2279   2279       /* Rollback or commit any schema changes that occurred. */
  2280   2280       if( p->rc!=SQLITE_OK && db->flags&SQLITE_InternChanges ){
  2281         -      sqlite3ResetInternalSchema(db, 0);
         2281  +      sqlite3ResetInternalSchema(db, -1);
  2282   2282         db->flags = (db->flags | SQLITE_InternChanges);
  2283   2283       }
  2284   2284   
  2285   2285       /* Release the locks */
  2286   2286       sqlite3VdbeMutexResync(p);
  2287   2287       sqlite3VdbeLeave(p);
  2288   2288     }

Changes to src/vtab.c.

    44     44       if( pDel && pDel->xDestroy ){
    45     45         pDel->xDestroy(pDel->pAux);
    46     46       }
    47     47       sqlite3DbFree(db, pDel);
    48     48       if( pDel==pMod ){
    49     49         db->mallocFailed = 1;
    50     50       }
    51         -    sqlite3ResetInternalSchema(db, 0);
           51  +    sqlite3ResetInternalSchema(db, -1);
    52     52     }else if( xDestroy ){
    53     53       xDestroy(pAux);
    54     54     }
    55     55     rc = sqlite3ApiExit(db, SQLITE_OK);
    56     56     sqlite3_mutex_leave(db->mutex);
    57     57     return rc;
    58     58   }
................................................................................
   141    141     VTable *pVTable = p->pVTable;
   142    142     p->pVTable = 0;
   143    143   
   144    144     /* Assert that the mutex (if any) associated with the BtShared database 
   145    145     ** that contains table p is held by the caller. See header comments 
   146    146     ** above function sqlite3VtabUnlockList() for an explanation of why
   147    147     ** this makes it safe to access the sqlite3.pDisconnect list of any
   148         -  ** database connection that may have an entry in the p->pVTable list.  */
   149         -  assert( db==0 ||
   150         -    sqlite3BtreeHoldsMutex(db->aDb[sqlite3SchemaToIndex(db, p->pSchema)].pBt) 
   151         -  );
          148  +  ** database connection that may have an entry in the p->pVTable list.
          149  +  */
          150  +  assert( db==0 || sqlite3SchemaMutexHeld(db, 0, p->pSchema) );
   152    151   
   153    152     while( pVTable ){
   154    153       sqlite3 *db2 = pVTable->db;
   155    154       VTable *pNext = pVTable->pNext;
   156    155       assert( db2 );
   157    156       if( db2==db ){
   158    157         pRet = pVTable;
................................................................................
   383    382     ** allows a schema that contains virtual tables to be loaded before
   384    383     ** the required virtual table implementations are registered.  */
   385    384     else {
   386    385       Table *pOld;
   387    386       Schema *pSchema = pTab->pSchema;
   388    387       const char *zName = pTab->zName;
   389    388       int nName = sqlite3Strlen30(zName);
          389  +    assert( sqlite3SchemaMutexHeld(db, 0, pSchema) );
   390    390       pOld = sqlite3HashInsert(&pSchema->tblHash, zName, nName, pTab);
   391    391       if( pOld ){
   392    392         db->mallocFailed = 1;
   393    393         assert( pTab==pOld );  /* Malloc must have failed inside HashInsert() */
   394    394         return;
   395    395       }
   396    396       pParse->pNewTable = 0;

Changes to test/e_expr.test.

  1440   1440   # interpreting the resulting byte sequence as a BLOB instead of as TEXT.
  1441   1441   #
  1442   1442   do_qexpr_test e_expr-27.4.1 { CAST('ghi' AS blob) } X'676869'
  1443   1443   do_qexpr_test e_expr-27.4.2 { CAST(456 AS blob) }   X'343536'
  1444   1444   do_qexpr_test e_expr-27.4.3 { CAST(1.78 AS blob) }  X'312E3738'
  1445   1445   rename db db2
  1446   1446   sqlite3 db :memory:
         1447  +ifcapable {utf16} {
  1447   1448   db eval { PRAGMA encoding = 'utf-16le' }
  1448   1449   do_qexpr_test e_expr-27.4.4 { CAST('ghi' AS blob) } X'670068006900'
  1449   1450   do_qexpr_test e_expr-27.4.5 { CAST(456 AS blob) }   X'340035003600'
  1450   1451   do_qexpr_test e_expr-27.4.6 { CAST(1.78 AS blob) }  X'31002E0037003800'
         1452  +}
  1451   1453   db close
  1452   1454   sqlite3 db :memory:
  1453   1455   db eval { PRAGMA encoding = 'utf-16be' }
         1456  +ifcapable {utf16} {
  1454   1457   do_qexpr_test e_expr-27.4.7 { CAST('ghi' AS blob) } X'006700680069'
  1455   1458   do_qexpr_test e_expr-27.4.8 { CAST(456 AS blob) }   X'003400350036'
  1456   1459   do_qexpr_test e_expr-27.4.9 { CAST(1.78 AS blob) }  X'0031002E00370038'
         1460  +}
  1457   1461   db close
  1458   1462   rename db2 db
  1459   1463   
  1460   1464   # EVIDENCE-OF: R-04207-37981 To cast a BLOB value to TEXT, the sequence
  1461   1465   # of bytes that make up the BLOB is interpreted as text encoded using
  1462   1466   # the database encoding.
  1463   1467   #
  1464   1468   do_expr_test e_expr-28.1.1 { CAST (X'676869' AS text) } text ghi
  1465   1469   do_expr_test e_expr-28.1.2 { CAST (X'670068006900' AS text) } text g
  1466   1470   rename db db2
  1467   1471   sqlite3 db :memory:
  1468   1472   db eval { PRAGMA encoding = 'utf-16le' }
         1473  +ifcapable {utf16} {
  1469   1474   do_expr_test e_expr-28.1.3 { CAST (X'676869' AS text) == 'ghi' } integer 0
  1470   1475   do_expr_test e_expr-28.1.4 { CAST (X'670068006900' AS text) } text ghi
         1476  +}
  1471   1477   db close
  1472   1478   rename db2 db
  1473   1479   
  1474   1480   # EVIDENCE-OF: R-22235-47006 Casting an INTEGER or REAL value into TEXT
  1475   1481   # renders the value as if via sqlite3_snprintf() except that the
  1476   1482   # resulting TEXT uses the encoding of the database connection.
  1477   1483   #
................................................................................
  1489   1495   #
  1490   1496   do_expr_test e_expr-29.1.1 { CAST (X'312E3233' AS REAL) } real 1.23
  1491   1497   do_expr_test e_expr-29.1.2 { CAST (X'3233302E30' AS REAL) } real 230.0
  1492   1498   do_expr_test e_expr-29.1.3 { CAST (X'2D392E3837' AS REAL) } real -9.87
  1493   1499   do_expr_test e_expr-29.1.4 { CAST (X'302E30303031' AS REAL) } real 0.0001
  1494   1500   rename db db2
  1495   1501   sqlite3 db :memory:
         1502  +ifcapable {utf16} {
  1496   1503   db eval { PRAGMA encoding = 'utf-16le' }
  1497   1504   do_expr_test e_expr-29.1.5 { 
  1498   1505       CAST (X'31002E0032003300' AS REAL) } real 1.23
  1499   1506   do_expr_test e_expr-29.1.6 { 
  1500   1507       CAST (X'3200330030002E003000' AS REAL) } real 230.0
  1501   1508   do_expr_test e_expr-29.1.7 { 
  1502   1509       CAST (X'2D0039002E0038003700' AS REAL) } real -9.87
  1503   1510   do_expr_test e_expr-29.1.8 { 
  1504   1511       CAST (X'30002E003000300030003100' AS REAL) } real 0.0001
         1512  +}
  1505   1513   db close
  1506   1514   rename db2 db
  1507   1515   
  1508   1516   # EVIDENCE-OF: R-54898-34554 When casting a TEXT value to REAL, the
  1509   1517   # longest possible prefix of the value that can be interpreted as a real
  1510   1518   # number is extracted from the TEXT value and the remainder ignored.
  1511   1519   #
................................................................................
  1539   1547   } integer 1000000
  1540   1548   do_expr_test e_expr-30.1.4 { 
  1541   1549     CAST(X'2D31313235383939393036383432363234' AS INTEGER) 
  1542   1550   } integer -1125899906842624
  1543   1551   
  1544   1552   rename db db2
  1545   1553   sqlite3 db :memory:
         1554  +ifcapable {utf16} {
  1546   1555   execsql { PRAGMA encoding = 'utf-16be' }
  1547   1556   do_expr_test e_expr-30.1.5 { CAST(X'003100320033' AS INTEGER) } integer 123
  1548   1557   do_expr_test e_expr-30.1.6 { CAST(X'002D003600370038' AS INTEGER) } integer -678
  1549   1558   do_expr_test e_expr-30.1.7 { 
  1550   1559     CAST(X'0031003000300030003000300030' AS INTEGER) 
  1551   1560   } integer 1000000
  1552   1561   do_expr_test e_expr-30.1.8 { 
  1553   1562     CAST(X'002D0031003100320035003800390039003900300036003800340032003600320034' AS INTEGER) 
  1554   1563   } integer -1125899906842624
         1564  +}
  1555   1565   db close
  1556   1566   rename db2 db
  1557   1567   
  1558   1568   # EVIDENCE-OF: R-47612-45842 When casting a TEXT value to INTEGER, the
  1559   1569   # longest possible prefix of the value that can be interpreted as an
  1560   1570   # integer number is extracted from the TEXT value and the remainder
  1561   1571   # ignored.
................................................................................
  1628   1638   } integer 9223372036854775807
  1629   1639   
  1630   1640   # EVIDENCE-OF: R-64550-29191 Note that the result from casting any
  1631   1641   # non-BLOB value into a BLOB and the result from casting any BLOB value
  1632   1642   # into a non-BLOB value may be different depending on whether the
  1633   1643   # database encoding is UTF-8, UTF-16be, or UTF-16le.
  1634   1644   #
         1645  +ifcapable {utf16} {
  1635   1646   sqlite3 db1 :memory: ; db1 eval { PRAGMA encoding = 'utf-8' }
  1636   1647   sqlite3 db2 :memory: ; db2 eval { PRAGMA encoding = 'utf-16le' }
  1637   1648   sqlite3 db3 :memory: ; db3 eval { PRAGMA encoding = 'utf-16be' }
  1638   1649   foreach {tn castexpr differs} {
  1639   1650     1 { CAST(123 AS BLOB)    } 1
  1640   1651     2 { CAST('' AS BLOB)     } 0
  1641   1652     3 { CAST('abcd' AS BLOB) } 1
................................................................................
  1654   1665     }
  1655   1666   
  1656   1667     do_test e_expr-33.1.$tn {set res} 1
  1657   1668   }
  1658   1669   db1 close
  1659   1670   db2 close
  1660   1671   db3 close
         1672  +}
  1661   1673   
  1662   1674   #-------------------------------------------------------------------------
  1663   1675   # Test statements related to the EXISTS and NOT EXISTS operators.
  1664   1676   #
  1665   1677   catch { db close }
  1666   1678   file delete -force test.db
  1667   1679   sqlite3 db test.db

Changes to test/e_vacuum.test.

   171    171     execsql VACUUM
   172    172     execsql { PRAGMA page_size ; PRAGMA auto_vacuum }
   173    173   } {2048 0}
   174    174   
   175    175   # EVIDENCE-OF: R-48521-51450 When in write-ahead log mode, only the
   176    176   # auto_vacuum support property can be changed using VACUUM.
   177    177   #
          178  +ifcapable wal {
   178    179   do_test e_vacuum-1.3.3.1 {
   179    180     execsql { PRAGMA journal_mode = wal }
   180    181     execsql { PRAGMA page_size ; PRAGMA auto_vacuum }
   181    182   } {2048 0}
   182    183   do_test e_vacuum-1.3.3.2 {
   183    184     execsql { PRAGMA page_size = 1024 }
   184    185     execsql { PRAGMA auto_vacuum = FULL }
   185    186     execsql VACUUM
   186    187     execsql { PRAGMA page_size ; PRAGMA auto_vacuum }
   187    188   } {2048 1}
          189  +}
   188    190   
   189    191   # EVIDENCE-OF: R-38001-03952 VACUUM only works on the main database. It
   190    192   # is not possible to VACUUM an attached database file.
   191    193   forcedelete test.db2
   192    194   create_db { PRAGMA auto_vacuum = NONE }
   193    195   do_execsql_test e_vacuum-2.1.1 {
   194    196     ATTACH 'test.db2' AS aux;

Changes to test/malloc.test.

   863    863         execsql {INSERT INTO t1 VALUES(3, 4)} db2
   864    864       } {}
   865    865       db2 close
   866    866     }
   867    867     catch { db2 close }
   868    868   }
   869    869   
   870         -ifcapable stat2 {
          870  +ifcapable stat2&&utf16 {
   871    871     do_malloc_test 38 -tclprep {
   872    872       add_test_collate db 0 0 1
   873    873       execsql {
   874    874         ANALYZE;
   875    875         CREATE TABLE t4(x COLLATE test_collate);
   876    876         CREATE INDEX t4x ON t4(x);
   877    877         INSERT INTO sqlite_stat2 VALUES('t4', 't4x', 0, 'aaa');

Changes to test/releasetest.tcl.

    60     60     "Default" {
    61     61       -O2
    62     62     }
    63     63     "Unlock-Notify" {
    64     64       -O2
    65     65       -DSQLITE_ENABLE_UNLOCK_NOTIFY
    66     66       -DSQLITE_THREADSAFE
    67         -    -DOS_UNIX
    68     67       -DSQLITE_TCL_DEFAULT_FULLMUTEX=1
    69     68     }
    70     69     "Secure-Delete" {
    71     70       -O2
    72     71       -DSQLITE_SECURE_DELETE=1
    73     72       -DSQLITE_SOUNDEX=1
    74     73     }

Changes to test/tester.tcl.

   150    150     #   --pause
   151    151     #   --soft-heap-limit=NN
   152    152     #   --maxerror=NN
   153    153     #   --malloctrace=N
   154    154     #   --backtrace=N
   155    155     #   --binarylog=N
   156    156     #   --soak=N
          157  +  #   --start=[$permutation:]$testfile
   157    158     #
   158    159     set cmdlinearg(soft-heap-limit)    0
   159    160     set cmdlinearg(maxerror)        1000
   160    161     set cmdlinearg(malloctrace)        0
   161    162     set cmdlinearg(backtrace)         10
   162    163     set cmdlinearg(binarylog)          0
   163    164     set cmdlinearg(soak)               0
          165  +  set cmdlinearg(start)             "" 
   164    166   
   165    167     set leftover [list]
   166    168     foreach a $argv {
   167    169       switch -regexp -- $a {
   168    170         {^-+pause$} {
   169    171           # Wait for user input before continuing. This is to give the user an 
   170    172           # opportunity to connect profiling tools to the process.
................................................................................
   191    193         {^-+binarylog=.+$} {
   192    194           foreach {dummy cmdlinearg(binarylog)} [split $a =] break
   193    195         }
   194    196         {^-+soak=.+$} {
   195    197           foreach {dummy cmdlinearg(soak)} [split $a =] break
   196    198           set ::G(issoak) $cmdlinearg(soak)
   197    199         }
          200  +      {^-+start=.+$} {
          201  +        foreach {dummy cmdlinearg(start)} [split $a =] break
          202  +
          203  +        set ::G(start:file) $cmdlinearg(start)
          204  +        if {[regexp {(.*):(.*)} $cmdlinearg(start) -> s.perm s.file]} {
          205  +          set ::G(start:permutation) ${s.perm}
          206  +          set ::G(start:file)        ${s.file}
          207  +        }
          208  +        if {$::G(start:file) == ""} {unset ::G(start:file)}
          209  +      }
   198    210         default {
   199    211           lappend leftover $a
   200    212         }
   201    213       }
   202    214     }
   203    215     set argv $leftover
   204    216   
................................................................................
  1353   1365   
  1354   1366     # Delete the interpreter used to run the test script.
  1355   1367     interp delete tinterp
  1356   1368   }
  1357   1369   
  1358   1370   proc slave_test_file {zFile} {
  1359   1371     set tail [file tail $zFile]
         1372  +
         1373  +  if {[info exists ::G(start:permutation)]} {
         1374  +    if {[permutation] != $::G(start:permutation)} return
         1375  +    unset ::G(start:permutation)
         1376  +  }
         1377  +  if {[info exists ::G(start:file)]} {
         1378  +    if {$tail != $::G(start:file) && $tail!="$::G(start:file).test"} return
         1379  +    unset ::G(start:file)
         1380  +  }
  1360   1381   
  1361   1382     # Remember the value of the shared-cache setting. So that it is possible
  1362   1383     # to check afterwards that it was not modified by the test script.
  1363   1384     #
  1364   1385     ifcapable shared_cache { set scs [sqlite3_enable_shared_cache] }
  1365   1386   
  1366   1387     # Run the test script in a slave interpreter.