/ Check-in [88cbf54e]
Login

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

Overview
Comment:Ensure that creating temp schema items does not cause an OPEN_SHARABLE_SCHEMA connection to load all schemas into memory.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | reuse-schema
Files: files | file ages | folders
SHA3-256:88cbf54eee7845f9e40e6879fc38eb98a80e81c987b7edeb39f3058590003347
User & Date: dan 2019-02-18 18:16:05
Wiki:reuse-schema
Context
2019-02-19
18:00
Improve error messages caused by corrupt database schemas in OPEN_SHARED_SCHEMA mode. check-in: 8ac75b8a user: dan tags: reuse-schema
2019-02-18
18:16
Ensure that creating temp schema items does not cause an OPEN_SHARABLE_SCHEMA connection to load all schemas into memory. check-in: 88cbf54e user: dan tags: reuse-schema
2019-02-15
19:36
Enhance the virtual table in test_schemapool.c so that it can be used to check that SHARED_SCHEMA connections are not allocating and freeing schemas when they should not be. check-in: cb236cb9 user: dan tags: reuse-schema
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to src/alter.c.

   120    120     /* Get a NULL terminated version of the new table name. */
   121    121     zName = sqlite3NameFromToken(db, pName);
   122    122     if( !zName ) goto exit_rename_table;
   123    123   
   124    124     /* Check that a table or index named 'zName' does not already exist
   125    125     ** in database iDb. If so, this is an error.
   126    126     */
   127         -  if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){
          127  +  if( sqlite3FindTable(0, db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){
   128    128       sqlite3ErrorMsg(pParse, 
   129    129           "there is already another table or index with this name: %s", zName);
   130    130       goto exit_rename_table;
   131    131     }
   132    132   
   133    133     /* Make sure it is not a system table being altered, or a reserved name
   134    134     ** that the table is being renamed to.
................................................................................
   207    207         nTabName, zTabName
   208    208     );
   209    209   
   210    210   #ifndef SQLITE_OMIT_AUTOINCREMENT
   211    211     /* If the sqlite_sequence table exists in this database, then update 
   212    212     ** it with the new table name.
   213    213     */
   214         -  if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){
          214  +  if( sqlite3FindTable(0, db, "sqlite_sequence", zDb) ){
   215    215       sqlite3NestedParse(pParse,
   216    216           "UPDATE \"%w\".sqlite_sequence set name = %Q WHERE name = %Q",
   217    217           zDb, zName, pTab->zName);
   218    218     }
   219    219   #endif
   220    220   
   221    221     /* If the table being renamed is not itself part of the temp database,
................................................................................
   284    284   
   285    285     assert( sqlite3BtreeHoldsAllMutexes(db) );
   286    286     iDb = sqlite3SchemaToIndex(db, pNew->pSchema);
   287    287     zDb = db->aDb[iDb].zDbSName;
   288    288     zTab = &pNew->zName[16];  /* Skip the "sqlite_altertab_" prefix on the name */
   289    289     pCol = &pNew->aCol[pNew->nCol-1];
   290    290     pDflt = pCol->pDflt;
   291         -  pTab = sqlite3FindTable(db, zTab, zDb);
          291  +  pTab = sqlite3FindTable(0, db, zTab, zDb);
   292    292     assert( pTab );
   293    293   
   294    294   #ifndef SQLITE_OMIT_AUTHORIZATION
   295    295     /* Invoke the authorization callback. */
   296    296     if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
   297    297       return;
   298    298     }
................................................................................
  1082   1082     TriggerStep *pStep;
  1083   1083     NameContext sNC;
  1084   1084     int rc = SQLITE_OK;
  1085   1085   
  1086   1086     memset(&sNC, 0, sizeof(sNC));
  1087   1087     sNC.pParse = pParse;
  1088   1088     assert( pNew->pTabSchema );
  1089         -  pParse->pTriggerTab = sqlite3FindTable(db, pNew->table, 
         1089  +  pParse->pTriggerTab = sqlite3FindTable(0, db, pNew->table, 
  1090   1090         db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName
  1091   1091     );
  1092   1092     pParse->eTriggerOp = pNew->op;
  1093   1093     /* ALWAYS() because if the table of the trigger does not exist, the
  1094   1094     ** error would have been hit before this point */
  1095   1095     if( ALWAYS(pParse->pTriggerTab) ){
  1096   1096       rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab);
................................................................................
  1246   1246   
  1247   1247     UNUSED_PARAMETER(NotUsed);
  1248   1248     if( zSql==0 ) return;
  1249   1249     if( zTable==0 ) return;
  1250   1250     if( zNew==0 ) return;
  1251   1251     if( iCol<0 ) return;
  1252   1252     sqlite3BtreeEnterAll(db);
  1253         -  pTab = sqlite3FindTable(db, zTable, zDb);
         1253  +  pTab = sqlite3FindTable(0, db, zTable, zDb);
  1254   1254     if( pTab==0 || iCol>=pTab->nCol ){
  1255   1255       sqlite3BtreeLeaveAll(db);
  1256   1256       return;
  1257   1257     }
  1258   1258     zOld = pTab->aCol[iCol].zName;
  1259   1259     memset(&sCtx, 0, sizeof(sCtx));
  1260   1260     sCtx.iCol = ((iCol==pTab->iPKey) ? -1 : iCol);
................................................................................
  1448   1448       sqlite3_xauth xAuth = db->xAuth;
  1449   1449       db->xAuth = 0;
  1450   1450   #endif
  1451   1451   
  1452   1452       sqlite3BtreeEnterAll(db);
  1453   1453   
  1454   1454       memset(&sCtx, 0, sizeof(RenameCtx));
  1455         -    sCtx.pTab = sqlite3FindTable(db, zOld, zDb);
         1455  +    sCtx.pTab = sqlite3FindTable(0, db, zOld, zDb);
  1456   1456       memset(&sWalker, 0, sizeof(Walker));
  1457   1457       sWalker.pParse = &sParse;
  1458   1458       sWalker.xExprCallback = renameTableExprCb;
  1459   1459       sWalker.xSelectCallback = renameTableSelectCb;
  1460   1460       sWalker.u.pRename = &sCtx;
  1461   1461   
  1462   1462       rc = renameParseSql(&sParse, zDb, 1, db, zInput, bTemp);

Changes to src/analyze.c.

   206    206   
   207    207     /* Create new statistic tables if they do not exist, or clear them
   208    208     ** if they do already exist.
   209    209     */
   210    210     for(i=0; i<ArraySize(aTable); i++){
   211    211       const char *zTab = aTable[i].zName;
   212    212       Table *pStat;
   213         -    if( (pStat = sqlite3FindTable(db, zTab, pDb->zDbSName))==0 ){
          213  +    if( (pStat = sqlite3FindTable(0, db, zTab, pDb->zDbSName))==0 ){
   214    214         if( aTable[i].zCols ){
   215    215           /* The sqlite_statN table does not exist. Create it. Note that a 
   216    216           ** side-effect of the CREATE TABLE statement is to leave the rootpage 
   217    217           ** of the new table in register pParse->regRoot. This is important 
   218    218           ** because the OpenWrite opcode below will be needing it. */
   219    219           sqlite3SchemaWritable(pParse, iDb);
   220    220           sqlite3NestedParse(pParse,
................................................................................
  1532   1532   
  1533   1533     assert( argc==3 );
  1534   1534     UNUSED_PARAMETER2(NotUsed, argc);
  1535   1535   
  1536   1536     if( argv==0 || argv[0]==0 || argv[2]==0 ){
  1537   1537       return 0;
  1538   1538     }
  1539         -  pTable = sqlite3FindTable(pInfo->db, argv[0], pInfo->zDatabase);
         1539  +  pTable = sqlite3FindTable(0, pInfo->db, argv[0], pInfo->zDatabase);
  1540   1540     if( pTable==0 ){
  1541   1541       return 0;
  1542   1542     }
  1543   1543     if( argv[1]==0 ){
  1544   1544       pIndex = 0;
  1545   1545     }else if( sqlite3_stricmp(argv[0],argv[1])==0 ){
  1546   1546       pIndex = sqlite3PrimaryKeyIndex(pTable);
................................................................................
  1674   1674   static Index *findIndexOrPrimaryKey(
  1675   1675     sqlite3 *db,
  1676   1676     const char *zName,
  1677   1677     const char *zDb
  1678   1678   ){
  1679   1679     Index *pIdx = sqlite3FindIndex(db, zName, zDb);
  1680   1680     if( pIdx==0 ){
  1681         -    Table *pTab = sqlite3FindTable(db, zName, zDb);
         1681  +    Table *pTab = sqlite3FindTable(0, db, zName, zDb);
  1682   1682       if( pTab && !HasRowid(pTab) ) pIdx = sqlite3PrimaryKeyIndex(pTab);
  1683   1683     }
  1684   1684     return pIdx;
  1685   1685   }
  1686   1686   
  1687   1687   /*
  1688   1688   ** Load the content from either the sqlite_stat4 or sqlite_stat3 table 
................................................................................
  1823   1823   ** Load content from the sqlite_stat4 and sqlite_stat3 tables into 
  1824   1824   ** the Index.aSample[] arrays of all indices.
  1825   1825   */
  1826   1826   static int loadStat4(sqlite3 *db, const char *zDb){
  1827   1827     int rc = SQLITE_OK;             /* Result codes from subroutines */
  1828   1828   
  1829   1829     assert( db->lookaside.bDisable );
  1830         -  if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){
         1830  +  if( sqlite3FindTable(0, db, "sqlite_stat4", zDb) ){
  1831   1831       rc = loadStatTbl(db, 0,
  1832   1832         "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", 
  1833   1833         "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4",
  1834   1834         zDb
  1835   1835       );
  1836   1836     }
  1837   1837   
  1838         -  if( rc==SQLITE_OK && sqlite3FindTable(db, "sqlite_stat3", zDb) ){
         1838  +  if( rc==SQLITE_OK && sqlite3FindTable(0, db, "sqlite_stat3", zDb) ){
  1839   1839       rc = loadStatTbl(db, 1,
  1840   1840         "SELECT idx,count(*) FROM %Q.sqlite_stat3 GROUP BY idx", 
  1841   1841         "SELECT idx,neq,nlt,ndlt,sqlite_record(sample) FROM %Q.sqlite_stat3",
  1842   1842         zDb
  1843   1843       );
  1844   1844     }
  1845   1845   
................................................................................
  1891   1891       pIdx->aSample = 0;
  1892   1892   #endif
  1893   1893     }
  1894   1894   
  1895   1895     /* Load new statistics out of the sqlite_stat1 table */
  1896   1896     sInfo.db = db;
  1897   1897     sInfo.zDatabase = db->aDb[iDb].zDbSName;
  1898         -  if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)!=0 ){
         1898  +  if( sqlite3FindTable(0, db, "sqlite_stat1", sInfo.zDatabase)!=0 ){
  1899   1899       zSql = sqlite3MPrintf(db, 
  1900   1900           "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
  1901   1901       if( zSql==0 ){
  1902   1902         rc = SQLITE_NOMEM_BKPT;
  1903   1903       }else{
  1904   1904         rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
  1905   1905         sqlite3DbFree(db, zSql);

Changes to src/build.c.

   290    290   **
   291    291   ** If the database handle was not opened with SQLITE_OPEN_SHARED_SCHEMA, or
   292    292   ** if the schema for database iDb is already loaded, this function is a no-op.
   293    293   **
   294    294   ** Non-zero is returned if a schema is loaded, or zero if it was already 
   295    295   ** loaded when this function was called..
   296    296   */
   297         -int sqlite3SchemaLoad(sqlite3 *db, int iDb){
          297  +int sqlite3SchemaLoad(sqlite3 *db, int iDb, int *pbUnload, char **pzErr){
          298  +  int rc = SQLITE_OK;
   298    299     if( IsReuseSchema(db) 
   299    300      && DbHasProperty(db, iDb, DB_SchemaLoaded)==0 
   300    301      && (db->init.busy==0 || (iDb!=1 && db->init.iDb==1))
   301    302     ){
   302         -    char *zDummy = 0;
   303    303       struct sqlite3InitInfo sv = db->init;
   304    304       memset(&db->init, 0, sizeof(struct sqlite3InitInfo));
   305         -    sqlite3InitOne(db, iDb, &zDummy, 0);
   306         -    sqlite3_free(zDummy);
          305  +    rc = sqlite3InitOne(db, iDb, pzErr, 0);
   307    306       db->init = sv;
   308         -    return (iDb!=1);
          307  +    *pbUnload = (iDb!=1);
   309    308     }
   310         -  return 0;
          309  +  return rc;
   311    310   }
   312    311   
   313    312   /*
   314    313   ** Locate the in-memory structure that describes a particular database
   315    314   ** table given the name of that table and (optionally) the name of the
   316    315   ** database containing the table.  Return NULL if not found.
   317    316   **
................................................................................
   318    317   ** If zDatabase is 0, all databases are searched for the table and the
   319    318   ** first matching table is returned.  (No checking for duplicate table
   320    319   ** names is done.)  The search order is TEMP first, then MAIN, then any
   321    320   ** auxiliary databases added using the ATTACH command.
   322    321   **
   323    322   ** See also sqlite3LocateTable().
   324    323   */
   325         -Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
          324  +Table *sqlite3FindTable(
          325  +  Parse *pParse, 
          326  +  sqlite3 *db, 
          327  +  const char *zName, 
          328  +  const char *zDatabase
          329  +){
   326    330     Table *p = 0;
   327    331     int i;
   328    332   
   329    333     /* All mutexes are required for schema access.  Make sure we hold them. */
   330    334     assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) );
   331    335   #if SQLITE_USER_AUTHENTICATION
   332    336     /* Only the admin user is allowed to know that the sqlite_user table
................................................................................
   335    339       return 0;
   336    340     }
   337    341   #endif
   338    342     while(1){
   339    343       for(i=OMIT_TEMPDB; i<db->nDb; i++){
   340    344         int j = (i<2) ? i^1 : i;   /* Search TEMP before MAIN */
   341    345         if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){
   342         -        int bUnload;
          346  +        int bUnload = 0;
   343    347           assert( sqlite3SchemaMutexHeld(db, j, 0) );
   344         -        bUnload = sqlite3SchemaLoad(db, j);
          348  +        if( IsReuseSchema(db) && pParse && pParse->nErr==0 ){
          349  +          pParse->rc = sqlite3SchemaLoad(db, j, &bUnload, &pParse->zErrMsg);
          350  +          if( pParse->rc ) pParse->nErr++;
          351  +        }
   345    352           p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName);
   346    353           if( p ) return p;
   347    354           if( bUnload ){
   348    355             sqlite3SchemaRelease(db, j);
   349    356           }
   350    357         }
   351    358       }
................................................................................
   382    389     if( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 
   383    390      && !IsReuseSchema(db)
   384    391      && SQLITE_OK!=sqlite3ReadSchema(pParse)
   385    392     ){
   386    393       return 0;
   387    394     }
   388    395   
   389         -  p = sqlite3FindTable(db, zName, zDbase);
          396  +  p = sqlite3FindTable(pParse, db, zName, zDbase);
   390    397     if( p==0 ){
   391    398   #ifndef SQLITE_OMIT_VIRTUALTABLE
   392    399       /* If zName is the not the name of a table in the schema created using
   393    400       ** CREATE, then check to see if it is the name of an virtual table that
   394    401       ** can be an eponymous virtual table. */
   395    402       if( pParse->disableVtab==0 ){
   396    403         Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
   397    404         if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
   398    405           pMod = sqlite3PragmaVtabRegister(db, zName);
   399    406         }
   400    407         if( pMod ){
   401         -        sqlite3SchemaLoad(db, 0);
          408  +        if( IsReuseSchema(db) && pParse->nErr==0 ){
          409  +          int bDummy = 0;
          410  +          pParse->rc = sqlite3SchemaLoad(db, 0, &bDummy, &pParse->zErrMsg);
          411  +          if( pParse->rc ) pParse->nErr++;
          412  +        }
   402    413           if( sqlite3VtabEponymousTableInit(pParse, pMod) ){
   403    414             Table *pEpoTab = pMod->pEpoTab;
   404    415             assert( IsReuseSchema(db) || pEpoTab->pSchema==db->aDb[0].pSchema );
   405    416             pEpoTab->pSchema = db->aDb[0].pSchema;  /* For SHARED_SCHEMA mode */
   406    417             return pEpoTab;
   407    418           }
   408    419         }
................................................................................
   977    988     ** it does. The exception is if the statement being parsed was passed
   978    989     ** to an sqlite3_declare_vtab() call. In that case only the column names
   979    990     ** and types will be used, so there is no need to test for namespace
   980    991     ** collisions.
   981    992     */
   982    993     if( !IN_SPECIAL_PARSE ){
   983    994       char *zDb = db->aDb[iDb].zDbSName;
   984         -    if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
          995  +    if( !IsReuseSchema(db) && SQLITE_OK!=sqlite3ReadSchema(pParse) ){
   985    996         goto begin_table_error;
   986    997       }
   987         -    pTable = sqlite3FindTable(db, zName, zDb);
          998  +    pTable = sqlite3FindTable(pParse, db, zName, zDb);
   988    999       if( pTable ){
   989   1000         if( !noErr ){
   990   1001           sqlite3ErrorMsg(pParse, "table %T already exists", pName);
   991   1002         }else{
   992   1003           assert( !db->init.busy || CORRUPT_DB );
   993   1004           sqlite3CodeVerifySchema(pParse, iDb);
   994   1005         }
................................................................................
  1952   1963     char *zTail;                  /* Pointer to the last "_" in zName */
  1953   1964     Table *pTab;                  /* Table that zName is a shadow of */
  1954   1965     Module *pMod;                 /* Module for the virtual table */
  1955   1966   
  1956   1967     zTail = strrchr(zName, '_');
  1957   1968     if( zTail==0 ) return 0;
  1958   1969     *zTail = 0;
  1959         -  pTab = sqlite3FindTable(db, zName, 0);
         1970  +  pTab = sqlite3FindTable(0, db, zName, 0);
  1960   1971     *zTail = '_';
  1961   1972     if( pTab==0 ) return 0;
  1962   1973     if( !IsVirtual(pTab) ) return 0;
  1963   1974     pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]);
  1964   1975     if( pMod==0 ) return 0;
  1965   1976     if( pMod->pModule->iVersion<3 ) return 0;
  1966   1977     if( pMod->pModule->xShadowName==0 ) return 0;
................................................................................
  2602   2613     const char *zName      /* Name of index or table */
  2603   2614   ){
  2604   2615     int i;
  2605   2616     const char *zDbName = pParse->db->aDb[iDb].zDbSName;
  2606   2617     for(i=1; i<=4; i++){
  2607   2618       char zTab[24];
  2608   2619       sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i);
  2609         -    if( sqlite3FindTable(pParse->db, zTab, zDbName) ){
         2620  +    if( sqlite3FindTable(0, pParse->db, zTab, zDbName) ){
  2610   2621         sqlite3NestedParse(pParse,
  2611   2622           "DELETE FROM %Q.%s WHERE %s=%Q",
  2612   2623           zDbName, zTab, zType, zName
  2613   2624         );
  2614   2625       }
  2615   2626     }
  2616   2627   }
................................................................................
  2697   2708     int iDb;
  2698   2709   
  2699   2710     if( db->mallocFailed ){
  2700   2711       goto exit_drop_table;
  2701   2712     }
  2702   2713     assert( pParse->nErr==0 );
  2703   2714     assert( pName->nSrc==1 );
  2704         -  if( sqlite3ReadSchema(pParse) ) goto exit_drop_table;
         2715  +  if( !IsReuseSchema(db) && sqlite3ReadSchema(pParse) ) goto exit_drop_table;
  2705   2716     if( noErr ) db->suppressErr++;
  2706   2717     assert( isView==0 || isView==LOCATE_VIEW );
  2707   2718     pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
  2708   2719     if( noErr ) db->suppressErr--;
  2709   2720   
  2710   2721     if( pTab==0 ){
  2711   2722       if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase);
................................................................................
  3121   3132   
  3122   3133     if( db->mallocFailed || pParse->nErr>0 ){
  3123   3134       goto exit_create_index;
  3124   3135     }
  3125   3136     if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){
  3126   3137       goto exit_create_index;
  3127   3138     }
  3128         -  if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
         3139  +  if( !IsReuseSchema(db) && SQLITE_OK!=sqlite3ReadSchema(pParse) ){
  3129   3140       goto exit_create_index;
  3130   3141     }
  3131   3142   
  3132   3143     /*
  3133   3144     ** Find the table that is to be indexed.  Return early if not found.
  3134   3145     */
  3135   3146     if( pTblName!=0 ){
................................................................................
  3227   3238       if( zName==0 ) goto exit_create_index;
  3228   3239       assert( pName->z!=0 );
  3229   3240       if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
  3230   3241         goto exit_create_index;
  3231   3242       }
  3232   3243       if( !IN_RENAME_OBJECT ){
  3233   3244         if( !db->init.busy ){
  3234         -        if( sqlite3FindTable(db, zName, 0)!=0 ){
         3245  +        if( sqlite3FindTable(0, db, zName, 0)!=0 ){
  3235   3246             sqlite3ErrorMsg(pParse, "there is already a table named %s", zName);
  3236   3247             goto exit_create_index;
  3237   3248           }
  3238   3249         }
  3239   3250         if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){
  3240   3251           if( !ifNotExist ){
  3241   3252             sqlite3ErrorMsg(pParse, "index %s already exists", zName);
................................................................................
  4581   4592       sqlite3DbFree(db, zColl);
  4582   4593     }
  4583   4594     iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName);
  4584   4595     if( iDb<0 ) return;
  4585   4596     z = sqlite3NameFromToken(db, pObjName);
  4586   4597     if( z==0 ) return;
  4587   4598     zDb = db->aDb[iDb].zDbSName;
  4588         -  pTab = sqlite3FindTable(db, z, zDb);
         4599  +  pTab = sqlite3FindTable(0, db, z, zDb);
  4589   4600     if( pTab ){
  4590   4601       reindexTable(pParse, pTab, 0);
  4591   4602       sqlite3DbFree(db, z);
  4592   4603       return;
  4593   4604     }
  4594   4605     pIndex = sqlite3FindIndex(db, z, zDb);
  4595   4606     sqlite3DbFree(db, z);

Changes to src/fkey.c.

   904    904       }
   905    905   
   906    906       /* Find the parent table of this foreign key. Also find a unique index 
   907    907       ** on the parent key columns in the parent table. If either of these 
   908    908       ** schema items cannot be located, set an error in pParse and return 
   909    909       ** early.  */
   910    910       if( pParse->disableTriggers ){
   911         -      pTo = sqlite3FindTable(db, pFKey->zTo, zDb);
          911  +      pTo = sqlite3FindTable(0, db, pFKey->zTo, zDb);
   912    912       }else{
   913    913         pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb);
   914    914       }
   915    915       if( !pTo || sqlite3FkLocateIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){
   916    916         assert( isIgnoreErrors==0 || (regOld!=0 && regNew==0) );
   917    917         if( !isIgnoreErrors || db->mallocFailed ) return;
   918    918         if( pTo==0 ){

Changes to src/main.c.

  3612   3612     char const *zDataType = 0;
  3613   3613     char const *zCollSeq = 0;
  3614   3614     int notnull = 0;
  3615   3615     int primarykey = 0;
  3616   3616     int autoinc = 0;
  3617   3617     int bUnlock;
  3618   3618   
  3619         -
  3620   3619   #ifdef SQLITE_ENABLE_API_ARMOR
  3621   3620     if( !sqlite3SafetyCheckOk(db) || zTableName==0 ){
  3622   3621       return SQLITE_MISUSE_BKPT;
  3623   3622     }
  3624   3623   #endif
  3625   3624   
  3626   3625     /* Ensure the database schema has been loaded */
  3627   3626     sqlite3_mutex_enter(db->mutex);
  3628   3627     bUnlock = sqlite3LockReusableSchema(db);
  3629   3628     sqlite3BtreeEnterAll(db);
  3630   3629     if( IsReuseSchema(db)==0 ){
  3631   3630       rc = sqlite3Init(db, &zErrMsg);
  3632   3631     }
  3633         -  if( SQLITE_OK!=rc ){
  3634         -    goto error_out;
  3635         -  }
  3636         -
  3637   3632   
  3638   3633     /* Locate the table in question */
  3639         -  pTab = sqlite3FindTable(db, zTableName, zDbName);
         3634  +  if( rc==SQLITE_OK ){
         3635  +    Parse sParse;                   /* Fake Parse object for FindTable */
         3636  +    memset(&sParse, 0, sizeof(sParse));
         3637  +    pTab = sqlite3FindTable(&sParse, db, zTableName, zDbName);
         3638  +    sqlite3_free(sParse.zErrMsg);
         3639  +    rc = sParse.rc;
         3640  +  }
         3641  +  if( SQLITE_OK!=rc ) goto error_out;
         3642  +
  3640   3643     if( !pTab || pTab->pSelect ){
  3641   3644       pTab = 0;
  3642   3645       goto error_out;
  3643   3646     }
  3644   3647   
  3645   3648     /* Find the column for which info is requested */
  3646   3649     if( zColumnName==0 ){

Changes to src/pragma.c.

  1184   1184     }
  1185   1185     break;
  1186   1186   
  1187   1187     case PragTyp_INDEX_LIST: if( zRight ){
  1188   1188       Index *pIdx;
  1189   1189       Table *pTab;
  1190   1190       int i;
  1191         -    pTab = sqlite3FindTable(db, zRight, zDb);
         1191  +    pTab = sqlite3FindTable(0, db, zRight, zDb);
  1192   1192       if( pTab ){
  1193   1193         int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  1194   1194         pParse->nMem = 5;
  1195   1195         sqlite3CodeVerifySchema(pParse, iTabDb);
  1196   1196         for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){
  1197   1197           const char *azOrigin[] = { "c", "u", "pk" };
  1198   1198           sqlite3VdbeMultiLoad(v, 1, "isisi",
................................................................................
  1273   1273   
  1274   1274   #endif /* SQLITE_OMIT_SCHEMA_PRAGMAS */
  1275   1275   
  1276   1276   #ifndef SQLITE_OMIT_FOREIGN_KEY
  1277   1277     case PragTyp_FOREIGN_KEY_LIST: if( zRight ){
  1278   1278       FKey *pFK;
  1279   1279       Table *pTab;
  1280         -    pTab = sqlite3FindTable(db, zRight, zDb);
         1280  +    pTab = sqlite3FindTable(0, db, zRight, zDb);
  1281   1281       if( pTab ){
  1282   1282         pFK = pTab->pFKey;
  1283   1283         if( pFK ){
  1284   1284           int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  1285   1285           int i = 0; 
  1286   1286           pParse->nMem = 8;
  1287   1287           sqlite3CodeVerifySchema(pParse, iTabDb);
................................................................................
  1343   1343         iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
  1344   1344         sqlite3CodeVerifySchema(pParse, iTabDb);
  1345   1345         sqlite3TableLock(pParse, iTabDb, pTab->tnum, 0, pTab->zName);
  1346   1346         if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
  1347   1347         sqlite3OpenTable(pParse, 0, iTabDb, pTab, OP_OpenRead);
  1348   1348         sqlite3VdbeLoadString(v, regResult, pTab->zName);
  1349   1349         for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
  1350         -        pParent = sqlite3FindTable(db, pFK->zTo, zDb);
         1350  +        pParent = sqlite3FindTable(0, db, pFK->zTo, zDb);
  1351   1351           if( pParent==0 ) continue;
  1352   1352           pIdx = 0;
  1353   1353           sqlite3TableLock(pParse, iTabDb, pParent->tnum, 0, pParent->zName);
  1354   1354           x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0);
  1355   1355           if( x==0 ){
  1356   1356             if( pIdx==0 ){
  1357   1357               sqlite3OpenTable(pParse, i, iTabDb, pParent, OP_OpenRead);
................................................................................
  1365   1365           }
  1366   1366         }
  1367   1367         assert( pParse->nErr>0 || pFK==0 );
  1368   1368         if( pFK ) break;
  1369   1369         if( pParse->nTab<i ) pParse->nTab = i;
  1370   1370         addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); VdbeCoverage(v);
  1371   1371         for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){
  1372         -        pParent = sqlite3FindTable(db, pFK->zTo, zDb);
         1372  +        pParent = sqlite3FindTable(0, db, pFK->zTo, zDb);
  1373   1373           pIdx = 0;
  1374   1374           aiCols = 0;
  1375   1375           if( pParent ){
  1376   1376             x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols);
  1377   1377             assert( x==0 );
  1378   1378           }
  1379   1379           addrOk = sqlite3VdbeMakeLabel(pParse);

Changes to src/sqliteInt.h.

  4009   4009   #define SQLITE_ECEL_DUP      0x01  /* Deep, not shallow copies */
  4010   4010   #define SQLITE_ECEL_FACTOR   0x02  /* Factor out constant terms */
  4011   4011   #define SQLITE_ECEL_REF      0x04  /* Use ExprList.u.x.iOrderByCol */
  4012   4012   #define SQLITE_ECEL_OMITREF  0x08  /* Omit if ExprList.u.x.iOrderByCol */
  4013   4013   void sqlite3ExprIfTrue(Parse*, Expr*, int, int);
  4014   4014   void sqlite3ExprIfFalse(Parse*, Expr*, int, int);
  4015   4015   void sqlite3ExprIfFalseDup(Parse*, Expr*, int, int);
  4016         -Table *sqlite3FindTable(sqlite3*,const char*, const char*);
         4016  +Table *sqlite3FindTable(Parse*,sqlite3*,const char*, const char*);
  4017   4017   #define LOCATE_VIEW    0x01
  4018   4018   #define LOCATE_NOERR   0x02
  4019   4019   Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*);
  4020   4020   Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_item *);
  4021   4021   Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
  4022   4022   void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
  4023   4023   void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
................................................................................
  4322   4322   void sqlite3RegisterLikeFunctions(sqlite3*, int);
  4323   4323   int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
  4324   4324   void sqlite3SchemaClear(void *);
  4325   4325   int sqlite3SchemaConnect(sqlite3*, int, u64);
  4326   4326   int sqlite3SchemaDisconnect(sqlite3 *, int, int);
  4327   4327   void sqlite3SchemaClearOrDisconnect(sqlite3*, int);
  4328   4328   Schema *sqlite3SchemaExtract(SchemaPool*);
  4329         -int sqlite3SchemaLoad(sqlite3*, int);
         4329  +int sqlite3SchemaLoad(sqlite3*, int, int*, char**);
  4330   4330   void sqlite3SchemaReleaseAll(sqlite3*);
  4331   4331   void sqlite3SchemaRelease(sqlite3*, int);
  4332   4332   void sqlite3SchemaAdjustUsed(sqlite3*, int, int, int*);
  4333   4333   void sqlite3SchemaWritable(Parse*, int);
  4334   4334   Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
  4335   4335   int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
  4336   4336   KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int);

Changes to src/status.c.

   281    281         bReleaseSchema = sqlite3LockReusableSchema(db);
   282    282         db->pnBytesFreed = &nByte;
   283    283         for(i=0; i<db->nDb; i++){
   284    284           int bUnload = 0;
   285    285           int nUsed = nByte;
   286    286           Schema *pSchema;
   287    287           if( db->aDb[i].pSPool ){
   288         -          bUnload = sqlite3SchemaLoad(db, i);
          288  +          char *zDummy = 0;
          289  +          rc = sqlite3SchemaLoad(db, i, &bUnload, &zDummy);
          290  +          sqlite3_free(zDummy);
          291  +          if( rc ) break;
   289    292           }
   290    293           pSchema = db->aDb[i].pSchema;
   291    294           if( ALWAYS(pSchema!=0) ){
   292    295             HashElem *p;
   293    296   
   294    297             nByte += sqlite3GlobalConfig.m.xRoundup(sizeof(HashElem)) * (
   295    298                 pSchema->tblHash.count 

Changes to src/vtab.c.

   715    715   */
   716    716   int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){
   717    717     int rc = SQLITE_OK;
   718    718     Table *pTab;
   719    719     Module *pMod;
   720    720     const char *zMod;
   721    721   
   722         -  pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
          722  +  pTab = sqlite3FindTable(0, db, zTab, db->aDb[iDb].zDbSName);
   723    723     assert( pTab && IsVirtual(pTab) && !pTab->pVTable );
   724    724   
   725    725     /* Locate the required virtual table module */
   726    726     zMod = pTab->azModuleArg[0];
   727    727     pMod = (Module*)sqlite3HashFind(&db->aModule, zMod);
   728    728   
   729    729     /* If the module has been registered and includes a Create method, 
................................................................................
   839    839   **
   840    840   ** This call is a no-op if zTab is not a virtual table.
   841    841   */
   842    842   int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
   843    843     int rc = SQLITE_OK;
   844    844     Table *pTab;
   845    845   
   846         -  pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
          846  +  pTab = sqlite3FindTable(0, db, zTab, db->aDb[iDb].zDbSName);
   847    847     if( pTab!=0 && ALWAYS(pTab->pVTable!=0) ){
   848    848       VTable *p;
   849    849       int (*xDestroy)(sqlite3_vtab *);
   850    850       for(p=pTab->pVTable; p; p=p->pNext){
   851    851         assert( p->pVtab );
   852    852         if( p->pVtab->nRef>0 ){
   853    853           return SQLITE_LOCKED;

Changes to test/reuse2.test.

   174    174   } {nref=2 nschema=1 ndelete=0}
   175    175   do_execsql_test -db db2 4.1.7 {
   176    176     SELECT * FROM x1
   177    177   }
   178    178   do_execsql_test 4.1.8 {
   179    179     SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
   180    180     FROM schemapool;
   181         -} {nref=6 nschema=1 ndelete=0}
          181  +} {nref=3 nschema=1 ndelete=0}
   182    182   
   183    183   do_test 4.2.1 {
   184    184     catchsql { SELECT * FROM abc } db2
   185    185   } {1 {no such table: abc}}
   186    186   do_execsql_test 4.2.2 {
   187    187     SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete
   188    188     FROM schemapool;

Changes to test/reuse3.test.

   125    125   
   126    126   catch { db1 close }
   127    127   catch { db2 close }
   128    128   catch { db3 close }
   129    129   catch { db4 close }
   130    130   
   131    131   #-------------------------------------------------------------------------
   132         -# Test the REINDEX command.
          132  +# 4.1 Test the REINDEX command.
          133  +# 4.2 Test CREATE TEMP ... commands.
          134  +#
   133    135   reset_db
   134    136   do_execsql_test 4.1.0 {
   135    137     CREATE TABLE x1(a, b, c);
   136    138     CREATE INDEX x1a ON x1(a);
   137    139     CREATE INDEX x1b ON x1(b);
   138    140     CREATE INDEX x1c ON x1(c);
   139    141   }
................................................................................
   158    160     set {} {}
   159    161     execsql { 
   160    162       SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete 
   161    163       FROM schemapool 
   162    164     }
   163    165   } {nref=5 nschema=1 ndelete=0}
   164    166   
   165         -breakpoint
   166    167   do_execsql_test 4.1.3 {
   167    168     REINDEX  x1;
   168    169     REINDEX  x1a;
   169    170     REINDEX  x1b;
   170    171     REINDEX  x1c;
   171    172     REINDEX  db1.x1a;
   172    173     REINDEX  db2.x1b;
................................................................................
   173    174     REINDEX  db3.x1c;
   174    175   }
   175    176   
   176    177   do_execsql_test 4.1.4 {
   177    178     SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete 
   178    179       FROM schemapool 
   179    180   } {nref=5 nschema=1 ndelete=28}
          181  +
          182  +#-------------------------------------------------------------------------
          183  +db close
          184  +sqlite3 db test.db -shared-schema 1
          185  +register_schemapool_module db
          186  +do_execsql_test 4.2.0 {
          187  +  ATTACH 'test.db1' AS db1;
          188  +  ATTACH 'test.db2' AS db2;
          189  +  ATTACH 'test.db3' AS db3;
          190  +  ATTACH 'test.db4' AS db4;
          191  +
          192  +  SELECT * FROM db1.x1;
          193  +  SELECT * FROM db2.x1;
          194  +  SELECT * FROM db3.x1;
          195  +  SELECT * FROM db4.x1;
          196  +}
          197  +
          198  +do_execsql_test 4.2.1 {
          199  +  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete 
          200  +    FROM schemapool; 
          201  +} {nref=5 nschema=1 ndelete=0}
          202  +
          203  +do_execsql_test 4.2.2 {
          204  +  CREATE TEMP TABLE t1(a, b, c);
          205  +  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete 
          206  +    FROM schemapool; 
          207  +} {nref=5 nschema=1 ndelete=0}
          208  +
          209  +do_execsql_test 4.2.3 {
          210  +  CREATE INDEX t1a ON t1(a);
          211  +  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete 
          212  +    FROM schemapool; 
          213  +} {nref=5 nschema=1 ndelete=0}
          214  +
          215  +do_execsql_test 4.2.4 {
          216  +  CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN
          217  +    SELECT 1,2,3,4;
          218  +  END;
          219  +  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete 
          220  +    FROM schemapool; 
          221  +} {nref=5 nschema=1 ndelete=0}
          222  +
          223  +do_execsql_test 4.2.5 {
          224  +  DROP TABLE t1;
          225  +  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete 
          226  +    FROM schemapool; 
          227  +} {nref=5 nschema=1 ndelete=0}
          228  +
          229  +do_execsql_test 4.2.6 {
          230  +  CREATE TEMP TRIGGER tr1 AFTER INSERT ON db2.x1 BEGIN
          231  +    SELECT 1,2,3,4;
          232  +  END;
          233  +  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete 
          234  +    FROM schemapool; 
          235  +} {nref=5 nschema=1 ndelete=0}
          236  +
          237  +do_execsql_test 4.2.7 {
          238  +  DROP TRIGGER tr1;
          239  +  SELECT 'nref=' || nRef, 'nschema=' || nSchema, 'ndelete=' || nDelete 
          240  +    FROM schemapool; 
          241  +} {nref=5 nschema=1 ndelete=4}
          242  +
   180    243   
   181    244   finish_test
   182    245   

Changes to tool/cg_anno.tcl.

     1         -#!/usr/bin/tclsh
     2         -#
            1  +#!/bin/sh
            2  +# \
            3  +exec tclsh  "$0" ${1+"$@"}
     3      4   # A wrapper around cg_annotate that sets appropriate command-line options
     4      5   # and rearranges the output so that annotated files occur in a consistent
     5      6   # sorted order.  Used by the speed-check.tcl script.
     6      7   #
     7      8   
     8      9   set in [open "|cg_annotate --show=Ir --auto=yes --context=40 $argv" r]
     9     10   set dest !