aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordan <dan@noemail.net>2020-03-21 15:41:55 +0000
committerdan <dan@noemail.net>2020-03-21 15:41:55 +0000
commit31f170f396b6eaad5a222dd854ca08247ebb7692 (patch)
tree861dbc4e50690e5a57045b39c2c179159b2a2d25 /src
parent2c3629e1c994a96042ac8ddd0c16c328ed225007 (diff)
parent465c2b89646c60aebf2ebf7ce0deb92d812f7178 (diff)
downloadsqlite-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.c37
-rw-r--r--src/build.c4
-rw-r--r--src/dbstat.c1
-rw-r--r--src/resolve.c6
-rw-r--r--src/sqliteInt.h1
-rw-r--r--src/trigger.c2
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;