1c11d4f93Sdrh /* 2c11d4f93Sdrh ** 2003 April 6 3c11d4f93Sdrh ** 4c11d4f93Sdrh ** The author disclaims copyright to this source code. In place of 5c11d4f93Sdrh ** a legal notice, here is a blessing: 6c11d4f93Sdrh ** 7c11d4f93Sdrh ** May you do good and not evil. 8c11d4f93Sdrh ** May you find forgiveness for yourself and forgive others. 9c11d4f93Sdrh ** May you share freely, never taking more than you give. 10c11d4f93Sdrh ** 11c11d4f93Sdrh ************************************************************************* 12c11d4f93Sdrh ** This file contains code used to implement the ATTACH and DETACH commands. 13c11d4f93Sdrh ** 14*9bb575fdSdrh ** $Id: attach.c,v 1.28 2004/09/06 17:24:12 drh Exp $ 15c11d4f93Sdrh */ 16c11d4f93Sdrh #include "sqliteInt.h" 17c11d4f93Sdrh 18c11d4f93Sdrh /* 19c11d4f93Sdrh ** This routine is called by the parser to process an ATTACH statement: 20c11d4f93Sdrh ** 21c11d4f93Sdrh ** ATTACH DATABASE filename AS dbname 22c11d4f93Sdrh ** 23c11d4f93Sdrh ** The pFilename and pDbname arguments are the tokens that define the 24c11d4f93Sdrh ** filename and dbname in the ATTACH statement. 25c11d4f93Sdrh */ 2625d6543dSdrh void sqlite3Attach( 2725d6543dSdrh Parse *pParse, /* The parser context */ 2825d6543dSdrh Token *pFilename, /* Name of database file */ 2925d6543dSdrh Token *pDbname, /* Name of the database to use internally */ 3025d6543dSdrh int keyType, /* 0: no key. 1: TEXT, 2: BLOB */ 31873cdcb2Sdrh Token *pKey /* Text of the key for keytype 1 and 2 */ 3225d6543dSdrh ){ 33c11d4f93Sdrh Db *aNew; 34c11d4f93Sdrh int rc, i; 35c11d4f93Sdrh char *zFile, *zName; 36*9bb575fdSdrh sqlite3 *db; 370bca3530Sdrh Vdbe *v; 38c11d4f93Sdrh 394adee20fSdanielk1977 v = sqlite3GetVdbe(pParse); 4096fb0dd5Sdanielk1977 if( !v ) return; 414adee20fSdanielk1977 sqlite3VdbeAddOp(v, OP_Halt, 0, 0); 42c11d4f93Sdrh if( pParse->explain ) return; 43c11d4f93Sdrh db = pParse->db; 44c11d4f93Sdrh if( db->nDb>=MAX_ATTACHED+2 ){ 454adee20fSdanielk1977 sqlite3ErrorMsg(pParse, "too many attached databases - max %d", 46c11d4f93Sdrh MAX_ATTACHED); 47c11d4f93Sdrh pParse->rc = SQLITE_ERROR; 48c11d4f93Sdrh return; 49c11d4f93Sdrh } 5081e293b4Sdrh 5192f9a1bbSdanielk1977 if( !db->autoCommit ){ 5292f9a1bbSdanielk1977 sqlite3ErrorMsg(pParse, "cannot ATTACH database within transaction"); 5392f9a1bbSdanielk1977 pParse->rc = SQLITE_ERROR; 5492f9a1bbSdanielk1977 return; 5592f9a1bbSdanielk1977 } 5692f9a1bbSdanielk1977 57a99db3b6Sdrh zFile = sqlite3NameFromToken(pFilename);; 5881e293b4Sdrh if( zFile==0 ) return; 5981e293b4Sdrh #ifndef SQLITE_OMIT_AUTHORIZATION 604adee20fSdanielk1977 if( sqlite3AuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){ 6181e293b4Sdrh sqliteFree(zFile); 6281e293b4Sdrh return; 6381e293b4Sdrh } 6481e293b4Sdrh #endif /* SQLITE_OMIT_AUTHORIZATION */ 6581e293b4Sdrh 66a99db3b6Sdrh zName = sqlite3NameFromToken(pDbname); 6781e293b4Sdrh if( zName==0 ) return; 6881e293b4Sdrh for(i=0; i<db->nDb; i++){ 69124b27e6Sdrh char *z = db->aDb[i].zName; 70124b27e6Sdrh if( z && sqlite3StrICmp(z, zName)==0 ){ 714adee20fSdanielk1977 sqlite3ErrorMsg(pParse, "database %z is already in use", zName); 7281e293b4Sdrh pParse->rc = SQLITE_ERROR; 7381e293b4Sdrh sqliteFree(zFile); 7481e293b4Sdrh return; 7581e293b4Sdrh } 7681e293b4Sdrh } 7781e293b4Sdrh 78c11d4f93Sdrh if( db->aDb==db->aDbStatic ){ 79c11d4f93Sdrh aNew = sqliteMalloc( sizeof(db->aDb[0])*3 ); 80c11d4f93Sdrh if( aNew==0 ) return; 81c11d4f93Sdrh memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); 82c11d4f93Sdrh }else{ 83c11d4f93Sdrh aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); 84c11d4f93Sdrh if( aNew==0 ) return; 85c11d4f93Sdrh } 86c11d4f93Sdrh db->aDb = aNew; 87c11d4f93Sdrh aNew = &db->aDb[db->nDb++]; 88c11d4f93Sdrh memset(aNew, 0, sizeof(*aNew)); 894adee20fSdanielk1977 sqlite3HashInit(&aNew->tblHash, SQLITE_HASH_STRING, 0); 904adee20fSdanielk1977 sqlite3HashInit(&aNew->idxHash, SQLITE_HASH_STRING, 0); 914adee20fSdanielk1977 sqlite3HashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0); 924adee20fSdanielk1977 sqlite3HashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1); 93c11d4f93Sdrh aNew->zName = zName; 9491cf71b0Sdanielk1977 aNew->safety_level = 3; 954adee20fSdanielk1977 rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt); 96c11d4f93Sdrh if( rc ){ 974adee20fSdanielk1977 sqlite3ErrorMsg(pParse, "unable to open database: %s", zFile); 98c11d4f93Sdrh } 994d189ca4Sdrh #if SQLITE_HAS_CODEC 10025d6543dSdrh { 10125d6543dSdrh extern int sqlite3CodecAttach(sqlite3*, int, void*, int); 10225d6543dSdrh char *zKey; 1034d189ca4Sdrh int nKey; 10425d6543dSdrh if( keyType==0 ){ 10525d6543dSdrh /* No key specified. Use the key from the main database */ 10625d6543dSdrh extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*); 10725d6543dSdrh sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); 10825d6543dSdrh }else if( keyType==1 ){ 10925d6543dSdrh /* Key specified as text */ 11090f5ecb3Sdrh zKey = sqlite3NameFromToken(pKey); 1114d189ca4Sdrh nKey = strlen(zKey); 11225d6543dSdrh }else{ 11325d6543dSdrh /* Key specified as a BLOB */ 11425d6543dSdrh char *zTemp; 11525d6543dSdrh assert( keyType==2 ); 11625d6543dSdrh pKey->z++; 11725d6543dSdrh pKey->n--; 11825d6543dSdrh zTemp = sqlite3NameFromToken(pKey); 11925d6543dSdrh zKey = sqlite3HexToBlob(zTemp); 12025d6543dSdrh sqliteFree(zTemp); 12125d6543dSdrh } 12225d6543dSdrh sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); 12325d6543dSdrh if( keyType ){ 12425d6543dSdrh sqliteFree(zKey); 12525d6543dSdrh } 1264d189ca4Sdrh } 1274d189ca4Sdrh #endif 128c11d4f93Sdrh sqliteFree(zFile); 129c11d4f93Sdrh db->flags &= ~SQLITE_Initialized; 130755b6ba9Sdrh if( pParse->nErr==0 && rc==SQLITE_OK ){ 1318a41449eSdanielk1977 rc = sqlite3ReadSchema(pParse); 132447623d9Sdrh } 133c11d4f93Sdrh if( rc ){ 134447623d9Sdrh int i = db->nDb - 1; 135447623d9Sdrh assert( i>=2 ); 136447623d9Sdrh if( db->aDb[i].pBt ){ 1374adee20fSdanielk1977 sqlite3BtreeClose(db->aDb[i].pBt); 138447623d9Sdrh db->aDb[i].pBt = 0; 139447623d9Sdrh } 1404adee20fSdanielk1977 sqlite3ResetInternalSchema(db, 0); 1418a41449eSdanielk1977 if( 0==pParse->nErr ){ 142c11d4f93Sdrh pParse->nErr++; 143c11d4f93Sdrh pParse->rc = SQLITE_ERROR; 144c11d4f93Sdrh } 145c11d4f93Sdrh } 1468a41449eSdanielk1977 } 147c11d4f93Sdrh 148c11d4f93Sdrh /* 149c11d4f93Sdrh ** This routine is called by the parser to process a DETACH statement: 150c11d4f93Sdrh ** 151c11d4f93Sdrh ** DETACH DATABASE dbname 152c11d4f93Sdrh ** 153c11d4f93Sdrh ** The pDbname argument is the name of the database in the DETACH statement. 154c11d4f93Sdrh */ 1554adee20fSdanielk1977 void sqlite3Detach(Parse *pParse, Token *pDbname){ 156c11d4f93Sdrh int i; 157*9bb575fdSdrh sqlite3 *db; 1580bca3530Sdrh Vdbe *v; 159e0d4b060Sdanielk1977 Db *pDb = 0; 160c11d4f93Sdrh 1614adee20fSdanielk1977 v = sqlite3GetVdbe(pParse); 16296fb0dd5Sdanielk1977 if( !v ) return; 1634adee20fSdanielk1977 sqlite3VdbeAddOp(v, OP_Halt, 0, 0); 164c11d4f93Sdrh if( pParse->explain ) return; 165c11d4f93Sdrh db = pParse->db; 166c11d4f93Sdrh for(i=0; i<db->nDb; i++){ 167124b27e6Sdrh pDb = &db->aDb[i]; 168124b27e6Sdrh if( pDb->pBt==0 || pDb->zName==0 ) continue; 169124b27e6Sdrh if( strlen(pDb->zName)!=pDbname->n ) continue; 170124b27e6Sdrh if( sqlite3StrNICmp(pDb->zName, pDbname->z, pDbname->n)==0 ) break; 171c11d4f93Sdrh } 172c11d4f93Sdrh if( i>=db->nDb ){ 1734adee20fSdanielk1977 sqlite3ErrorMsg(pParse, "no such database: %T", pDbname); 174c11d4f93Sdrh return; 175c11d4f93Sdrh } 176c11d4f93Sdrh if( i<2 ){ 1774adee20fSdanielk1977 sqlite3ErrorMsg(pParse, "cannot detach database %T", pDbname); 178c11d4f93Sdrh return; 179c11d4f93Sdrh } 18092f9a1bbSdanielk1977 if( !db->autoCommit ){ 18192f9a1bbSdanielk1977 sqlite3ErrorMsg(pParse, "cannot DETACH database within transaction"); 18292f9a1bbSdanielk1977 pParse->rc = SQLITE_ERROR; 18392f9a1bbSdanielk1977 return; 18492f9a1bbSdanielk1977 } 18581e293b4Sdrh #ifndef SQLITE_OMIT_AUTHORIZATION 1864adee20fSdanielk1977 if( sqlite3AuthCheck(pParse,SQLITE_DETACH,db->aDb[i].zName,0,0)!=SQLITE_OK ){ 18781e293b4Sdrh return; 18881e293b4Sdrh } 18981e293b4Sdrh #endif /* SQLITE_OMIT_AUTHORIZATION */ 190124b27e6Sdrh sqlite3BtreeClose(pDb->pBt); 191124b27e6Sdrh pDb->pBt = 0; 192db2d9a0bSdrh sqlite3ResetInternalSchema(db, 0); 193c11d4f93Sdrh } 194f26e09c8Sdrh 195f26e09c8Sdrh /* 196f26e09c8Sdrh ** Initialize a DbFixer structure. This routine must be called prior 197f26e09c8Sdrh ** to passing the structure to one of the sqliteFixAAAA() routines below. 198f26e09c8Sdrh ** 199f26e09c8Sdrh ** The return value indicates whether or not fixation is required. TRUE 200f26e09c8Sdrh ** means we do need to fix the database references, FALSE means we do not. 201f26e09c8Sdrh */ 2024adee20fSdanielk1977 int sqlite3FixInit( 203f26e09c8Sdrh DbFixer *pFix, /* The fixer to be initialized */ 204f26e09c8Sdrh Parse *pParse, /* Error messages will be written here */ 205873cdcb2Sdrh int iDb, /* This is the database that must be used */ 206f26e09c8Sdrh const char *zType, /* "view", "trigger", or "index" */ 207f26e09c8Sdrh const Token *pName /* Name of the view, trigger, or index */ 208f26e09c8Sdrh ){ 209*9bb575fdSdrh sqlite3 *db; 210f26e09c8Sdrh 211f26e09c8Sdrh if( iDb<0 || iDb==1 ) return 0; 212f26e09c8Sdrh db = pParse->db; 213f26e09c8Sdrh assert( db->nDb>iDb ); 2144312db55Sdrh pFix->pParse = pParse; 215f26e09c8Sdrh pFix->zDb = db->aDb[iDb].zName; 216f26e09c8Sdrh pFix->zType = zType; 217f26e09c8Sdrh pFix->pName = pName; 218f26e09c8Sdrh return 1; 219f26e09c8Sdrh } 220f26e09c8Sdrh 221f26e09c8Sdrh /* 222f26e09c8Sdrh ** The following set of routines walk through the parse tree and assign 223f26e09c8Sdrh ** a specific database to all table references where the database name 224f26e09c8Sdrh ** was left unspecified in the original SQL statement. The pFix structure 2254adee20fSdanielk1977 ** must have been initialized by a prior call to sqlite3FixInit(). 226f26e09c8Sdrh ** 227f26e09c8Sdrh ** These routines are used to make sure that an index, trigger, or 228f26e09c8Sdrh ** view in one database does not refer to objects in a different database. 229f26e09c8Sdrh ** (Exception: indices, triggers, and views in the TEMP database are 230f26e09c8Sdrh ** allowed to refer to anything.) If a reference is explicitly made 231f26e09c8Sdrh ** to an object in a different database, an error message is added to 232f26e09c8Sdrh ** pParse->zErrMsg and these routines return non-zero. If everything 233f26e09c8Sdrh ** checks out, these routines return 0. 234f26e09c8Sdrh */ 2354adee20fSdanielk1977 int sqlite3FixSrcList( 236f26e09c8Sdrh DbFixer *pFix, /* Context of the fixation */ 237f26e09c8Sdrh SrcList *pList /* The Source list to check and modify */ 238f26e09c8Sdrh ){ 239f26e09c8Sdrh int i; 240f26e09c8Sdrh const char *zDb; 241873cdcb2Sdrh struct SrcList_item *pItem; 242f26e09c8Sdrh 243f26e09c8Sdrh if( pList==0 ) return 0; 244f26e09c8Sdrh zDb = pFix->zDb; 245873cdcb2Sdrh for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ 246873cdcb2Sdrh if( pItem->zDatabase==0 ){ 247873cdcb2Sdrh pItem->zDatabase = sqliteStrDup(zDb); 248873cdcb2Sdrh }else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){ 2494adee20fSdanielk1977 sqlite3ErrorMsg(pFix->pParse, 250873cdcb2Sdrh "%s %T cannot reference objects in database %s", 251873cdcb2Sdrh pFix->zType, pFix->pName, pItem->zDatabase); 252f26e09c8Sdrh return 1; 253f26e09c8Sdrh } 254873cdcb2Sdrh if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; 255873cdcb2Sdrh if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1; 256f26e09c8Sdrh } 257f26e09c8Sdrh return 0; 258f26e09c8Sdrh } 2594adee20fSdanielk1977 int sqlite3FixSelect( 260f26e09c8Sdrh DbFixer *pFix, /* Context of the fixation */ 261f26e09c8Sdrh Select *pSelect /* The SELECT statement to be fixed to one database */ 262f26e09c8Sdrh ){ 263f26e09c8Sdrh while( pSelect ){ 2644adee20fSdanielk1977 if( sqlite3FixExprList(pFix, pSelect->pEList) ){ 265f26e09c8Sdrh return 1; 266f26e09c8Sdrh } 2674adee20fSdanielk1977 if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){ 268f26e09c8Sdrh return 1; 269f26e09c8Sdrh } 2704adee20fSdanielk1977 if( sqlite3FixExpr(pFix, pSelect->pWhere) ){ 271f26e09c8Sdrh return 1; 272f26e09c8Sdrh } 2734adee20fSdanielk1977 if( sqlite3FixExpr(pFix, pSelect->pHaving) ){ 274f26e09c8Sdrh return 1; 275f26e09c8Sdrh } 276f26e09c8Sdrh pSelect = pSelect->pPrior; 277f26e09c8Sdrh } 278f26e09c8Sdrh return 0; 279f26e09c8Sdrh } 2804adee20fSdanielk1977 int sqlite3FixExpr( 281f26e09c8Sdrh DbFixer *pFix, /* Context of the fixation */ 282f26e09c8Sdrh Expr *pExpr /* The expression to be fixed to one database */ 283f26e09c8Sdrh ){ 284f26e09c8Sdrh while( pExpr ){ 2854adee20fSdanielk1977 if( sqlite3FixSelect(pFix, pExpr->pSelect) ){ 286f26e09c8Sdrh return 1; 287f26e09c8Sdrh } 2884adee20fSdanielk1977 if( sqlite3FixExprList(pFix, pExpr->pList) ){ 289f26e09c8Sdrh return 1; 290f26e09c8Sdrh } 2914adee20fSdanielk1977 if( sqlite3FixExpr(pFix, pExpr->pRight) ){ 292f26e09c8Sdrh return 1; 293f26e09c8Sdrh } 294f26e09c8Sdrh pExpr = pExpr->pLeft; 295f26e09c8Sdrh } 296f26e09c8Sdrh return 0; 297f26e09c8Sdrh } 2984adee20fSdanielk1977 int sqlite3FixExprList( 299f26e09c8Sdrh DbFixer *pFix, /* Context of the fixation */ 300f26e09c8Sdrh ExprList *pList /* The expression to be fixed to one database */ 301f26e09c8Sdrh ){ 302f26e09c8Sdrh int i; 303873cdcb2Sdrh struct ExprList_item *pItem; 304f26e09c8Sdrh if( pList==0 ) return 0; 305873cdcb2Sdrh for(i=0, pItem=pList->a; i<pList->nExpr; i++, pItem++){ 306873cdcb2Sdrh if( sqlite3FixExpr(pFix, pItem->pExpr) ){ 307f26e09c8Sdrh return 1; 308f26e09c8Sdrh } 309f26e09c8Sdrh } 310f26e09c8Sdrh return 0; 311f26e09c8Sdrh } 3124adee20fSdanielk1977 int sqlite3FixTriggerStep( 313f26e09c8Sdrh DbFixer *pFix, /* Context of the fixation */ 314f26e09c8Sdrh TriggerStep *pStep /* The trigger step be fixed to one database */ 315f26e09c8Sdrh ){ 316f26e09c8Sdrh while( pStep ){ 3174adee20fSdanielk1977 if( sqlite3FixSelect(pFix, pStep->pSelect) ){ 318f26e09c8Sdrh return 1; 319f26e09c8Sdrh } 3204adee20fSdanielk1977 if( sqlite3FixExpr(pFix, pStep->pWhere) ){ 321f26e09c8Sdrh return 1; 322f26e09c8Sdrh } 3234adee20fSdanielk1977 if( sqlite3FixExprList(pFix, pStep->pExprList) ){ 324f26e09c8Sdrh return 1; 325f26e09c8Sdrh } 326f26e09c8Sdrh pStep = pStep->pNext; 327f26e09c8Sdrh } 328f26e09c8Sdrh return 0; 329f26e09c8Sdrh } 330