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.33 2005/03/16 12:15:21 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( 27 Parse *pParse, /* The parser context */ 28 Token *pFilename, /* Name of database file */ 29 Token *pDbname, /* Name of the database to use internally */ 30 int keyType, /* 0: no key. 1: TEXT, 2: BLOB */ 31 Token *pKey /* Text of the key for keytype 1 and 2 */ 32 ){ 33 Db *aNew; 34 int rc, i; 35 char *zFile = 0; 36 char *zName = 0; 37 sqlite3 *db; 38 Vdbe *v; 39 40 v = sqlite3GetVdbe(pParse); 41 if( !v ) return; 42 sqlite3VdbeAddOp(v, OP_Expire, 1, 0); 43 sqlite3VdbeAddOp(v, OP_Halt, 0, 0); 44 if( pParse->explain ) return; 45 db = pParse->db; 46 if( db->nDb>=MAX_ATTACHED+2 ){ 47 sqlite3ErrorMsg(pParse, "too many attached databases - max %d", 48 MAX_ATTACHED); 49 pParse->rc = SQLITE_ERROR; 50 return; 51 } 52 53 if( !db->autoCommit ){ 54 sqlite3ErrorMsg(pParse, "cannot ATTACH database within transaction"); 55 pParse->rc = SQLITE_ERROR; 56 return; 57 } 58 59 zFile = sqlite3NameFromToken(pFilename); 60 if( zFile==0 ){ 61 goto attach_end; 62 } 63 #ifndef SQLITE_OMIT_AUTHORIZATION 64 if( sqlite3AuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){ 65 goto attach_end; 66 } 67 #endif /* SQLITE_OMIT_AUTHORIZATION */ 68 69 zName = sqlite3NameFromToken(pDbname); 70 if( zName==0 ){ 71 goto attach_end; 72 } 73 for(i=0; i<db->nDb; i++){ 74 char *z = db->aDb[i].zName; 75 if( z && sqlite3StrICmp(z, zName)==0 ){ 76 sqlite3ErrorMsg(pParse, "database %s is already in use", zName); 77 pParse->rc = SQLITE_ERROR; 78 goto attach_end; 79 } 80 } 81 82 if( db->aDb==db->aDbStatic ){ 83 aNew = sqliteMalloc( sizeof(db->aDb[0])*3 ); 84 if( aNew==0 ){ 85 goto attach_end; 86 } 87 memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); 88 }else{ 89 aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); 90 if( aNew==0 ){ 91 goto attach_end; 92 } 93 } 94 db->aDb = aNew; 95 aNew = &db->aDb[db->nDb++]; 96 memset(aNew, 0, sizeof(*aNew)); 97 sqlite3HashInit(&aNew->tblHash, SQLITE_HASH_STRING, 0); 98 sqlite3HashInit(&aNew->idxHash, SQLITE_HASH_STRING, 0); 99 sqlite3HashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0); 100 sqlite3HashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1); 101 aNew->zName = zName; 102 zName = 0; 103 aNew->safety_level = 3; 104 rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt); 105 if( rc ){ 106 sqlite3ErrorMsg(pParse, "unable to open database: %s", zFile); 107 } 108 #if SQLITE_HAS_CODEC 109 { 110 extern int sqlite3CodecAttach(sqlite3*, int, void*, int); 111 char *zKey; 112 int nKey; 113 if( keyType==0 ){ 114 /* No key specified. Use the key from the main database */ 115 extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*); 116 sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); 117 }else if( keyType==1 ){ 118 /* Key specified as text */ 119 zKey = sqlite3NameFromToken(pKey); 120 nKey = strlen(zKey); 121 }else{ 122 /* Key specified as a BLOB */ 123 char *zTemp; 124 assert( keyType==2 ); 125 pKey->z++; 126 pKey->n--; 127 zTemp = sqlite3NameFromToken(pKey); 128 zKey = sqlite3HexToBlob(zTemp); 129 sqliteFree(zTemp); 130 } 131 sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); 132 if( keyType ){ 133 sqliteFree(zKey); 134 } 135 } 136 #endif 137 db->flags &= ~SQLITE_Initialized; 138 if( pParse->nErr==0 && rc==SQLITE_OK ){ 139 rc = sqlite3ReadSchema(pParse); 140 } 141 if( rc ){ 142 int i = db->nDb - 1; 143 assert( i>=2 ); 144 if( db->aDb[i].pBt ){ 145 sqlite3BtreeClose(db->aDb[i].pBt); 146 db->aDb[i].pBt = 0; 147 } 148 sqlite3ResetInternalSchema(db, 0); 149 if( 0==pParse->nErr ){ 150 pParse->nErr++; 151 pParse->rc = SQLITE_ERROR; 152 } 153 } 154 155 attach_end: 156 sqliteFree(zFile); 157 sqliteFree(zName); 158 } 159 160 /* 161 ** This routine is called by the parser to process a DETACH statement: 162 ** 163 ** DETACH DATABASE dbname 164 ** 165 ** The pDbname argument is the name of the database in the DETACH statement. 166 */ 167 void sqlite3Detach(Parse *pParse, Token *pDbname){ 168 int i; 169 sqlite3 *db; 170 Vdbe *v; 171 Db *pDb = 0; 172 char *zName; 173 174 v = sqlite3GetVdbe(pParse); 175 if( !v ) return; 176 sqlite3VdbeAddOp(v, OP_Expire, 0, 0); 177 sqlite3VdbeAddOp(v, OP_Halt, 0, 0); 178 if( pParse->explain ) return; 179 db = pParse->db; 180 zName = sqlite3NameFromToken(pDbname); 181 if( zName==0 ) return; 182 for(i=0; i<db->nDb; i++){ 183 pDb = &db->aDb[i]; 184 if( pDb->pBt==0 ) continue; 185 if( sqlite3StrICmp(pDb->zName, zName)==0 ) break; 186 } 187 if( i>=db->nDb ){ 188 sqlite3ErrorMsg(pParse, "no such database: %z", zName); 189 return; 190 } 191 if( i<2 ){ 192 sqlite3ErrorMsg(pParse, "cannot detach database %z", zName); 193 return; 194 } 195 sqliteFree(zName); 196 if( !db->autoCommit ){ 197 sqlite3ErrorMsg(pParse, "cannot DETACH database within transaction"); 198 pParse->rc = SQLITE_ERROR; 199 return; 200 } 201 #ifndef SQLITE_OMIT_AUTHORIZATION 202 if( sqlite3AuthCheck(pParse,SQLITE_DETACH,db->aDb[i].zName,0,0)!=SQLITE_OK ){ 203 return; 204 } 205 #endif /* SQLITE_OMIT_AUTHORIZATION */ 206 sqlite3BtreeClose(pDb->pBt); 207 pDb->pBt = 0; 208 sqlite3ResetInternalSchema(db, 0); 209 } 210 211 /* 212 ** Initialize a DbFixer structure. This routine must be called prior 213 ** to passing the structure to one of the sqliteFixAAAA() routines below. 214 ** 215 ** The return value indicates whether or not fixation is required. TRUE 216 ** means we do need to fix the database references, FALSE means we do not. 217 */ 218 int sqlite3FixInit( 219 DbFixer *pFix, /* The fixer to be initialized */ 220 Parse *pParse, /* Error messages will be written here */ 221 int iDb, /* This is the database that must be used */ 222 const char *zType, /* "view", "trigger", or "index" */ 223 const Token *pName /* Name of the view, trigger, or index */ 224 ){ 225 sqlite3 *db; 226 227 if( iDb<0 || iDb==1 ) return 0; 228 db = pParse->db; 229 assert( db->nDb>iDb ); 230 pFix->pParse = pParse; 231 pFix->zDb = db->aDb[iDb].zName; 232 pFix->zType = zType; 233 pFix->pName = pName; 234 return 1; 235 } 236 237 /* 238 ** The following set of routines walk through the parse tree and assign 239 ** a specific database to all table references where the database name 240 ** was left unspecified in the original SQL statement. The pFix structure 241 ** must have been initialized by a prior call to sqlite3FixInit(). 242 ** 243 ** These routines are used to make sure that an index, trigger, or 244 ** view in one database does not refer to objects in a different database. 245 ** (Exception: indices, triggers, and views in the TEMP database are 246 ** allowed to refer to anything.) If a reference is explicitly made 247 ** to an object in a different database, an error message is added to 248 ** pParse->zErrMsg and these routines return non-zero. If everything 249 ** checks out, these routines return 0. 250 */ 251 int sqlite3FixSrcList( 252 DbFixer *pFix, /* Context of the fixation */ 253 SrcList *pList /* The Source list to check and modify */ 254 ){ 255 int i; 256 const char *zDb; 257 struct SrcList_item *pItem; 258 259 if( pList==0 ) return 0; 260 zDb = pFix->zDb; 261 for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ 262 if( pItem->zDatabase==0 ){ 263 pItem->zDatabase = sqliteStrDup(zDb); 264 }else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){ 265 sqlite3ErrorMsg(pFix->pParse, 266 "%s %T cannot reference objects in database %s", 267 pFix->zType, pFix->pName, pItem->zDatabase); 268 return 1; 269 } 270 #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) 271 if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; 272 if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1; 273 #endif 274 } 275 return 0; 276 } 277 #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) 278 int sqlite3FixSelect( 279 DbFixer *pFix, /* Context of the fixation */ 280 Select *pSelect /* The SELECT statement to be fixed to one database */ 281 ){ 282 while( pSelect ){ 283 if( sqlite3FixExprList(pFix, pSelect->pEList) ){ 284 return 1; 285 } 286 if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){ 287 return 1; 288 } 289 if( sqlite3FixExpr(pFix, pSelect->pWhere) ){ 290 return 1; 291 } 292 if( sqlite3FixExpr(pFix, pSelect->pHaving) ){ 293 return 1; 294 } 295 pSelect = pSelect->pPrior; 296 } 297 return 0; 298 } 299 int sqlite3FixExpr( 300 DbFixer *pFix, /* Context of the fixation */ 301 Expr *pExpr /* The expression to be fixed to one database */ 302 ){ 303 while( pExpr ){ 304 if( sqlite3FixSelect(pFix, pExpr->pSelect) ){ 305 return 1; 306 } 307 if( sqlite3FixExprList(pFix, pExpr->pList) ){ 308 return 1; 309 } 310 if( sqlite3FixExpr(pFix, pExpr->pRight) ){ 311 return 1; 312 } 313 pExpr = pExpr->pLeft; 314 } 315 return 0; 316 } 317 int sqlite3FixExprList( 318 DbFixer *pFix, /* Context of the fixation */ 319 ExprList *pList /* The expression to be fixed to one database */ 320 ){ 321 int i; 322 struct ExprList_item *pItem; 323 if( pList==0 ) return 0; 324 for(i=0, pItem=pList->a; i<pList->nExpr; i++, pItem++){ 325 if( sqlite3FixExpr(pFix, pItem->pExpr) ){ 326 return 1; 327 } 328 } 329 return 0; 330 } 331 #endif 332 333 #ifndef SQLITE_OMIT_TRIGGER 334 int sqlite3FixTriggerStep( 335 DbFixer *pFix, /* Context of the fixation */ 336 TriggerStep *pStep /* The trigger step be fixed to one database */ 337 ){ 338 while( pStep ){ 339 if( sqlite3FixSelect(pFix, pStep->pSelect) ){ 340 return 1; 341 } 342 if( sqlite3FixExpr(pFix, pStep->pWhere) ){ 343 return 1; 344 } 345 if( sqlite3FixExprList(pFix, pStep->pExprList) ){ 346 return 1; 347 } 348 pStep = pStep->pNext; 349 } 350 return 0; 351 } 352 #endif 353