diff options
author | dan <dan@noemail.net> | 2020-03-21 15:41:55 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2020-03-21 15:41:55 +0000 |
commit | 31f170f396b6eaad5a222dd854ca08247ebb7692 (patch) | |
tree | 861dbc4e50690e5a57045b39c2c179159b2a2d25 /src | |
parent | 2c3629e1c994a96042ac8ddd0c16c328ed225007 (diff) | |
parent | 465c2b89646c60aebf2ebf7ce0deb92d812f7178 (diff) | |
download | sqlite-31f170f396b6eaad5a222dd854ca08247ebb7692.tar.gz sqlite-31f170f396b6eaad5a222dd854ca08247ebb7692.zip |
Ensure that "main" can always be used to refer to the main database, even if it has been renamed using SQLITE_DBCONFIG_MAINDBNAME.
FossilOrigin-Name: 682b426f5658254e63dff02c960b557fb33cb3e944fdd14faa0aa9988af7269a
Diffstat (limited to 'src')
-rw-r--r-- | src/attach.c | 37 | ||||
-rw-r--r-- | src/build.c | 4 | ||||
-rw-r--r-- | src/dbstat.c | 1 | ||||
-rw-r--r-- | src/resolve.c | 6 | ||||
-rw-r--r-- | src/sqliteInt.h | 1 | ||||
-rw-r--r-- | src/trigger.c | 2 |
6 files changed, 43 insertions, 8 deletions
diff --git a/src/attach.c b/src/attach.c index e7d31e3b9..a7fe8f9c5 100644 --- a/src/attach.c +++ b/src/attach.c @@ -46,6 +46,17 @@ static int resolveAttachExpr(NameContext *pName, Expr *pExpr) } /* +** Return true if zName points to a name that may be used to refer to +** database iDb attached to handle db. +*/ +int sqlite3DbIsNamed(sqlite3 *db, int iDb, const char *zName){ + return ( + sqlite3StrICmp(db->aDb[iDb].zDbSName, zName)==0 + || (iDb==0 && sqlite3StrICmp("main", zName)==0) + ); +} + +/* ** An SQL user-function registered to do the work of an ATTACH statement. The ** three arguments to the function come directly from an attach statement: ** @@ -117,9 +128,8 @@ static void attachFunc( goto attach_error; } for(i=0; i<db->nDb; i++){ - char *z = db->aDb[i].zDbSName; - assert( z && zName ); - if( sqlite3StrICmp(z, zName)==0 ){ + assert( zName ); + if( sqlite3DbIsNamed(db, i, zName) ){ zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName); goto attach_error; } @@ -272,7 +282,7 @@ static void detachFunc( for(i=0; i<db->nDb; i++){ pDb = &db->aDb[i]; if( pDb->pBt==0 ) continue; - if( sqlite3StrICmp(pDb->zDbSName, zName)==0 ) break; + if( sqlite3DbIsNamed(db, i, zName) ) break; } if( i>=db->nDb ){ @@ -465,12 +475,29 @@ int sqlite3FixSrcList( int i; const char *zDb; struct SrcList_item *pItem; + sqlite3 *db = pFix->pParse->db; + const char *zAlt = 0; if( NEVER(pList==0) ) return 0; + + /* If zDb refers to the main database and the main database has been + ** renamed using DBCONFIG_MAINDBNAME, then items in pList may be + ** qualified using "main" or the new name as the database name. Set + ** zAlt to point to the alternative (alternative to zDb) name in this + ** case. */ zDb = pFix->zDb; + if( sqlite3StrICmp(db->aDb[0].zDbSName, zDb)==0 ){ + zAlt = "main"; + }else if( sqlite3StrICmp("main", zDb)==0 ){ + zAlt = db->aDb[0].zDbSName; + } + for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ if( pFix->bTemp==0 ){ - if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){ + if( pItem->zDatabase + && sqlite3StrICmp(pItem->zDatabase, zDb) + && sqlite3_stricmp(pItem->zDatabase, zAlt) + ){ sqlite3ErrorMsg(pFix->pParse, "%s %T cannot reference objects in database %s", pFix->zType, pFix->pName, pItem->zDatabase); diff --git a/src/build.c b/src/build.c index 73e4cea7c..dcd035e99 100644 --- a/src/build.c +++ b/src/build.c @@ -315,7 +315,7 @@ Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){ while(1){ for(i=OMIT_TEMPDB; i<db->nDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ - if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){ + if( zDatabase==0 || sqlite3DbIsNamed(db, j, zDatabase) ){ assert( sqlite3SchemaMutexHeld(db, j, 0) ); p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName); if( p ) return p; @@ -437,7 +437,7 @@ Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ Schema *pSchema = db->aDb[j].pSchema; assert( pSchema ); - if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zDbSName) ) continue; + if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue; assert( sqlite3SchemaMutexHeld(db, j, 0) ); p = sqlite3HashFind(&pSchema->idxHash, zName); if( p ) break; diff --git a/src/dbstat.c b/src/dbstat.c index 2931024e1..bddde79ce 100644 --- a/src/dbstat.c +++ b/src/dbstat.c @@ -238,6 +238,7 @@ static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ i = 0; if( iSchema>=0 ){ pIdxInfo->aConstraintUsage[iSchema].argvIndex = ++i; + pIdxInfo->aConstraintUsage[iSchema].omit = 1; pIdxInfo->idxNum |= 0x01; } if( iName>=0 ){ diff --git a/src/resolve.c b/src/resolve.c index 05ef0c06e..0364407d4 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -252,6 +252,12 @@ static int lookupName( break; } } + if( i==db->nDb && sqlite3StrICmp("main", zDb)==0 ){ + /* This branch is taken when the main database has been renamed + ** using SQLITE_DBCONFIG_MAINDBNAME. */ + pSchema = db->aDb[0].pSchema; + zDb = db->aDb[0].zDbSName; + } } } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 0a013f332..02ad6bfce 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4395,6 +4395,7 @@ void sqlite3DeferForeignKey(Parse*, int); # define sqlite3AuthContextPush(a,b,c) # define sqlite3AuthContextPop(a) ((void)(a)) #endif +int sqlite3DbIsNamed(sqlite3 *db, int iDb, const char *zName); void sqlite3Attach(Parse*, Expr*, Expr*, Expr*); void sqlite3Detach(Parse*, Expr*); void sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*); diff --git a/src/trigger.c b/src/trigger.c index 458aa2996..646d6942d 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -580,7 +580,7 @@ void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){ assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); for(i=OMIT_TEMPDB; i<db->nDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ - if( zDb && sqlite3StrICmp(db->aDb[j].zDbSName, zDb) ) continue; + if( zDb && sqlite3DbIsNamed(db, j, zDb)==0 ) continue; assert( sqlite3SchemaMutexHeld(db, j, 0) ); pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName); if( pTrigger ) break; |