1 /* 2 ** 2003 April 6 3 ** 4 ** The author disclaims copyright to this source code. In place of 5 ** a legal notice, here is a blessing: 6 ** 7 ** May you do good and not evil. 8 ** May you find forgiveness for yourself and forgive others. 9 ** May you share freely, never taking more than you give. 10 ** 11 ************************************************************************* 12 ** This file contains code used to implement the ATTACH and DETACH commands. 13 ** 14 ** $Id: attach.c,v 1.14 2004/06/09 12:30:05 danielk1977 Exp $ 15 */ 16 #include "sqliteInt.h" 17 18 /* 19 ** This routine is called by the parser to process an ATTACH statement: 20 ** 21 ** ATTACH DATABASE filename AS dbname 22 ** 23 ** The pFilename and pDbname arguments are the tokens that define the 24 ** filename and dbname in the ATTACH statement. 25 */ 26 void sqlite3Attach(Parse *pParse, Token *pFilename, Token *pDbname, Token *pKey){ 27 Db *aNew; 28 int rc, i; 29 char *zFile, *zName; 30 sqlite *db; 31 Vdbe *v; 32 33 v = sqlite3GetVdbe(pParse); 34 sqlite3VdbeAddOp(v, OP_Halt, 0, 0); 35 if( pParse->explain ) return; 36 db = pParse->db; 37 if( db->nDb>=MAX_ATTACHED+2 ){ 38 sqlite3ErrorMsg(pParse, "too many attached databases - max %d", 39 MAX_ATTACHED); 40 pParse->rc = SQLITE_ERROR; 41 return; 42 } 43 44 zFile = 0; 45 sqlite3SetNString(&zFile, pFilename->z, pFilename->n, 0); 46 if( zFile==0 ) return; 47 sqlite3Dequote(zFile); 48 #ifndef SQLITE_OMIT_AUTHORIZATION 49 if( sqlite3AuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){ 50 sqliteFree(zFile); 51 return; 52 } 53 #endif /* SQLITE_OMIT_AUTHORIZATION */ 54 55 zName = 0; 56 sqlite3SetNString(&zName, pDbname->z, pDbname->n, 0); 57 if( zName==0 ) return; 58 sqlite3Dequote(zName); 59 for(i=0; i<db->nDb; i++){ 60 if( db->aDb[i].zName && sqlite3StrICmp(db->aDb[i].zName, zName)==0 ){ 61 sqlite3ErrorMsg(pParse, "database %z is already in use", zName); 62 pParse->rc = SQLITE_ERROR; 63 sqliteFree(zFile); 64 return; 65 } 66 } 67 68 if( db->aDb==db->aDbStatic ){ 69 aNew = sqliteMalloc( sizeof(db->aDb[0])*3 ); 70 if( aNew==0 ) return; 71 memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); 72 }else{ 73 aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); 74 if( aNew==0 ) return; 75 } 76 db->aDb = aNew; 77 aNew = &db->aDb[db->nDb++]; 78 memset(aNew, 0, sizeof(*aNew)); 79 sqlite3HashInit(&aNew->tblHash, SQLITE_HASH_STRING, 0); 80 sqlite3HashInit(&aNew->idxHash, SQLITE_HASH_STRING, 0); 81 sqlite3HashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0); 82 sqlite3HashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1); 83 aNew->zName = zName; 84 rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt); 85 if( rc ){ 86 sqlite3ErrorMsg(pParse, "unable to open database: %s", zFile); 87 } 88 #if SQLITE_HAS_CODEC 89 { 90 extern int sqliteCodecAttach(sqlite*, int, void*, int); 91 char *zKey = 0; 92 int nKey; 93 if( pKey && pKey->z && pKey->n ){ 94 sqlite3SetNString(&zKey, pKey->z, pKey->n, 0); 95 sqlite3Dequote(zKey); 96 nKey = strlen(zKey); 97 }else{ 98 zKey = 0; 99 nKey = 0; 100 } 101 sqliteCodecAttach(db, db->nDb-1, zKey, nKey); 102 } 103 #endif 104 sqliteFree(zFile); 105 db->flags &= ~SQLITE_Initialized; 106 if( pParse->nErr ) return; 107 if( rc==SQLITE_OK ){ 108 rc = sqlite3ReadSchema(pParse->db, &pParse->zErrMsg); 109 } 110 if( rc ){ 111 int i = db->nDb - 1; 112 assert( i>=2 ); 113 if( db->aDb[i].pBt ){ 114 sqlite3BtreeClose(db->aDb[i].pBt); 115 db->aDb[i].pBt = 0; 116 } 117 sqlite3ResetInternalSchema(db, 0); 118 pParse->nErr++; 119 pParse->rc = SQLITE_ERROR; 120 } 121 } 122 123 /* 124 ** This routine is called by the parser to process a DETACH statement: 125 ** 126 ** DETACH DATABASE dbname 127 ** 128 ** The pDbname argument is the name of the database in the DETACH statement. 129 */ 130 void sqlite3Detach(Parse *pParse, Token *pDbname){ 131 int i; 132 sqlite *db; 133 Vdbe *v; 134 135 v = sqlite3GetVdbe(pParse); 136 sqlite3VdbeAddOp(v, OP_Halt, 0, 0); 137 if( pParse->explain ) return; 138 db = pParse->db; 139 for(i=0; i<db->nDb; i++){ 140 if( db->aDb[i].pBt==0 || db->aDb[i].zName==0 ) continue; 141 if( strlen(db->aDb[i].zName)!=pDbname->n ) continue; 142 if( sqlite3StrNICmp(db->aDb[i].zName, pDbname->z, pDbname->n)==0 ) break; 143 } 144 if( i>=db->nDb ){ 145 sqlite3ErrorMsg(pParse, "no such database: %T", pDbname); 146 return; 147 } 148 if( i<2 ){ 149 sqlite3ErrorMsg(pParse, "cannot detach database %T", pDbname); 150 return; 151 } 152 #ifndef SQLITE_OMIT_AUTHORIZATION 153 if( sqlite3AuthCheck(pParse,SQLITE_DETACH,db->aDb[i].zName,0,0)!=SQLITE_OK ){ 154 return; 155 } 156 #endif /* SQLITE_OMIT_AUTHORIZATION */ 157 sqlite3BtreeClose(db->aDb[i].pBt); 158 db->aDb[i].pBt = 0; 159 sqliteFree(db->aDb[i].zName); 160 sqlite3ResetInternalSchema(db, i); 161 db->nDb--; 162 if( i<db->nDb ){ 163 db->aDb[i] = db->aDb[db->nDb]; 164 memset(&db->aDb[db->nDb], 0, sizeof(db->aDb[0])); 165 sqlite3ResetInternalSchema(db, i); 166 } 167 } 168 169 /* 170 ** Initialize a DbFixer structure. This routine must be called prior 171 ** to passing the structure to one of the sqliteFixAAAA() routines below. 172 ** 173 ** The return value indicates whether or not fixation is required. TRUE 174 ** means we do need to fix the database references, FALSE means we do not. 175 */ 176 int sqlite3FixInit( 177 DbFixer *pFix, /* The fixer to be initialized */ 178 Parse *pParse, /* Error messages will be written here */ 179 int iDb, /* This is the database that must must be used */ 180 const char *zType, /* "view", "trigger", or "index" */ 181 const Token *pName /* Name of the view, trigger, or index */ 182 ){ 183 sqlite *db; 184 185 if( iDb<0 || iDb==1 ) return 0; 186 db = pParse->db; 187 assert( db->nDb>iDb ); 188 pFix->pParse = pParse; 189 pFix->zDb = db->aDb[iDb].zName; 190 pFix->zType = zType; 191 pFix->pName = pName; 192 return 1; 193 } 194 195 /* 196 ** The following set of routines walk through the parse tree and assign 197 ** a specific database to all table references where the database name 198 ** was left unspecified in the original SQL statement. The pFix structure 199 ** must have been initialized by a prior call to sqlite3FixInit(). 200 ** 201 ** These routines are used to make sure that an index, trigger, or 202 ** view in one database does not refer to objects in a different database. 203 ** (Exception: indices, triggers, and views in the TEMP database are 204 ** allowed to refer to anything.) If a reference is explicitly made 205 ** to an object in a different database, an error message is added to 206 ** pParse->zErrMsg and these routines return non-zero. If everything 207 ** checks out, these routines return 0. 208 */ 209 int sqlite3FixSrcList( 210 DbFixer *pFix, /* Context of the fixation */ 211 SrcList *pList /* The Source list to check and modify */ 212 ){ 213 int i; 214 const char *zDb; 215 216 if( pList==0 ) return 0; 217 zDb = pFix->zDb; 218 for(i=0; i<pList->nSrc; i++){ 219 if( pList->a[i].zDatabase==0 ){ 220 pList->a[i].zDatabase = sqliteStrDup(zDb); 221 }else if( sqlite3StrICmp(pList->a[i].zDatabase,zDb)!=0 ){ 222 sqlite3ErrorMsg(pFix->pParse, 223 "%s %z cannot reference objects in database %s", 224 pFix->zType, sqliteStrNDup(pFix->pName->z, pFix->pName->n), 225 pList->a[i].zDatabase); 226 return 1; 227 } 228 if( sqlite3FixSelect(pFix, pList->a[i].pSelect) ) return 1; 229 if( sqlite3FixExpr(pFix, pList->a[i].pOn) ) return 1; 230 } 231 return 0; 232 } 233 int sqlite3FixSelect( 234 DbFixer *pFix, /* Context of the fixation */ 235 Select *pSelect /* The SELECT statement to be fixed to one database */ 236 ){ 237 while( pSelect ){ 238 if( sqlite3FixExprList(pFix, pSelect->pEList) ){ 239 return 1; 240 } 241 if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){ 242 return 1; 243 } 244 if( sqlite3FixExpr(pFix, pSelect->pWhere) ){ 245 return 1; 246 } 247 if( sqlite3FixExpr(pFix, pSelect->pHaving) ){ 248 return 1; 249 } 250 pSelect = pSelect->pPrior; 251 } 252 return 0; 253 } 254 int sqlite3FixExpr( 255 DbFixer *pFix, /* Context of the fixation */ 256 Expr *pExpr /* The expression to be fixed to one database */ 257 ){ 258 while( pExpr ){ 259 if( sqlite3FixSelect(pFix, pExpr->pSelect) ){ 260 return 1; 261 } 262 if( sqlite3FixExprList(pFix, pExpr->pList) ){ 263 return 1; 264 } 265 if( sqlite3FixExpr(pFix, pExpr->pRight) ){ 266 return 1; 267 } 268 pExpr = pExpr->pLeft; 269 } 270 return 0; 271 } 272 int sqlite3FixExprList( 273 DbFixer *pFix, /* Context of the fixation */ 274 ExprList *pList /* The expression to be fixed to one database */ 275 ){ 276 int i; 277 if( pList==0 ) return 0; 278 for(i=0; i<pList->nExpr; i++){ 279 if( sqlite3FixExpr(pFix, pList->a[i].pExpr) ){ 280 return 1; 281 } 282 } 283 return 0; 284 } 285 int sqlite3FixTriggerStep( 286 DbFixer *pFix, /* Context of the fixation */ 287 TriggerStep *pStep /* The trigger step be fixed to one database */ 288 ){ 289 while( pStep ){ 290 if( sqlite3FixSelect(pFix, pStep->pSelect) ){ 291 return 1; 292 } 293 if( sqlite3FixExpr(pFix, pStep->pWhere) ){ 294 return 1; 295 } 296 if( sqlite3FixExprList(pFix, pStep->pExprList) ){ 297 return 1; 298 } 299 pStep = pStep->pNext; 300 } 301 return 0; 302 } 303 304 305 306