xref: /sqlite-3.40.0/src/attach.c (revision 0bca3530)
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*0bca3530Sdrh ** $Id: attach.c,v 1.9 2004/01/20 11:54:03 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 */
26c11d4f93Sdrh void sqliteAttach(Parse *pParse, Token *pFilename, Token *pDbname){
27c11d4f93Sdrh   Db *aNew;
28c11d4f93Sdrh   int rc, i;
29c11d4f93Sdrh   char *zFile, *zName;
30c11d4f93Sdrh   sqlite *db;
31*0bca3530Sdrh   Vdbe *v;
32c11d4f93Sdrh 
33*0bca3530Sdrh   v = sqliteGetVdbe(pParse);
34*0bca3530Sdrh   sqliteVdbeAddOp(v, OP_Halt, 0, 0);
35c11d4f93Sdrh   if( pParse->explain ) return;
36c11d4f93Sdrh   db = pParse->db;
37c11d4f93Sdrh   if( db->file_format<4 ){
38c11d4f93Sdrh     sqliteErrorMsg(pParse, "cannot attach auxiliary databases to an "
39c11d4f93Sdrh        "older format master database", 0);
40c11d4f93Sdrh     pParse->rc = SQLITE_ERROR;
41c11d4f93Sdrh     return;
42c11d4f93Sdrh   }
43c11d4f93Sdrh   if( db->nDb>=MAX_ATTACHED+2 ){
44c11d4f93Sdrh     sqliteErrorMsg(pParse, "too many attached databases - max %d",
45c11d4f93Sdrh        MAX_ATTACHED);
46c11d4f93Sdrh     pParse->rc = SQLITE_ERROR;
47c11d4f93Sdrh     return;
48c11d4f93Sdrh   }
4981e293b4Sdrh 
5081e293b4Sdrh   zFile = 0;
5181e293b4Sdrh   sqliteSetNString(&zFile, pFilename->z, pFilename->n, 0);
5281e293b4Sdrh   if( zFile==0 ) return;
5381e293b4Sdrh   sqliteDequote(zFile);
5481e293b4Sdrh #ifndef SQLITE_OMIT_AUTHORIZATION
5581e293b4Sdrh   if( sqliteAuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){
5681e293b4Sdrh     sqliteFree(zFile);
5781e293b4Sdrh     return;
5881e293b4Sdrh   }
5981e293b4Sdrh #endif /* SQLITE_OMIT_AUTHORIZATION */
6081e293b4Sdrh 
6181e293b4Sdrh   zName = 0;
6281e293b4Sdrh   sqliteSetNString(&zName, pDbname->z, pDbname->n, 0);
6381e293b4Sdrh   if( zName==0 ) return;
6481e293b4Sdrh   sqliteDequote(zName);
6581e293b4Sdrh   for(i=0; i<db->nDb; i++){
6681e293b4Sdrh     if( db->aDb[i].zName && sqliteStrICmp(db->aDb[i].zName, zName)==0 ){
6781e293b4Sdrh       sqliteErrorMsg(pParse, "database %z is already in use", zName);
6881e293b4Sdrh       pParse->rc = SQLITE_ERROR;
6981e293b4Sdrh       sqliteFree(zFile);
7081e293b4Sdrh       return;
7181e293b4Sdrh     }
7281e293b4Sdrh   }
7381e293b4Sdrh 
74c11d4f93Sdrh   if( db->aDb==db->aDbStatic ){
75c11d4f93Sdrh     aNew = sqliteMalloc( sizeof(db->aDb[0])*3 );
76c11d4f93Sdrh     if( aNew==0 ) return;
77c11d4f93Sdrh     memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
78c11d4f93Sdrh   }else{
79c11d4f93Sdrh     aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
80c11d4f93Sdrh     if( aNew==0 ) return;
81c11d4f93Sdrh   }
82c11d4f93Sdrh   db->aDb = aNew;
83c11d4f93Sdrh   aNew = &db->aDb[db->nDb++];
84c11d4f93Sdrh   memset(aNew, 0, sizeof(*aNew));
85c11d4f93Sdrh   sqliteHashInit(&aNew->tblHash, SQLITE_HASH_STRING, 0);
86c11d4f93Sdrh   sqliteHashInit(&aNew->idxHash, SQLITE_HASH_STRING, 0);
87c11d4f93Sdrh   sqliteHashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0);
88c11d4f93Sdrh   sqliteHashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1);
89c11d4f93Sdrh   aNew->zName = zName;
90b0208ccaSpaul   rc = sqliteBtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
91c11d4f93Sdrh   if( rc ){
92c11d4f93Sdrh     sqliteErrorMsg(pParse, "unable to open database: %s", zFile);
93c11d4f93Sdrh   }
94c11d4f93Sdrh   sqliteFree(zFile);
95c11d4f93Sdrh   db->flags &= ~SQLITE_Initialized;
96c11d4f93Sdrh   if( pParse->nErr ) return;
97447623d9Sdrh   if( rc==SQLITE_OK ){
98c11d4f93Sdrh     rc = sqliteInit(pParse->db, &pParse->zErrMsg);
99447623d9Sdrh   }
100c11d4f93Sdrh   if( rc ){
101447623d9Sdrh     int i = db->nDb - 1;
102447623d9Sdrh     assert( i>=2 );
103447623d9Sdrh     if( db->aDb[i].pBt ){
104447623d9Sdrh       sqliteBtreeClose(db->aDb[i].pBt);
105447623d9Sdrh       db->aDb[i].pBt = 0;
106447623d9Sdrh     }
107c11d4f93Sdrh     sqliteResetInternalSchema(db, 0);
108c11d4f93Sdrh     pParse->nErr++;
109c11d4f93Sdrh     pParse->rc = SQLITE_ERROR;
110c11d4f93Sdrh   }
111c11d4f93Sdrh }
112c11d4f93Sdrh 
113c11d4f93Sdrh /*
114c11d4f93Sdrh ** This routine is called by the parser to process a DETACH statement:
115c11d4f93Sdrh **
116c11d4f93Sdrh **    DETACH DATABASE dbname
117c11d4f93Sdrh **
118c11d4f93Sdrh ** The pDbname argument is the name of the database in the DETACH statement.
119c11d4f93Sdrh */
120c11d4f93Sdrh void sqliteDetach(Parse *pParse, Token *pDbname){
121c11d4f93Sdrh   int i;
122c11d4f93Sdrh   sqlite *db;
123*0bca3530Sdrh   Vdbe *v;
124c11d4f93Sdrh 
125*0bca3530Sdrh   v = sqliteGetVdbe(pParse);
126*0bca3530Sdrh   sqliteVdbeAddOp(v, OP_Halt, 0, 0);
127c11d4f93Sdrh   if( pParse->explain ) return;
128c11d4f93Sdrh   db = pParse->db;
129c11d4f93Sdrh   for(i=0; i<db->nDb; i++){
130c11d4f93Sdrh     if( db->aDb[i].pBt==0 || db->aDb[i].zName==0 ) continue;
131c11d4f93Sdrh     if( strlen(db->aDb[i].zName)!=pDbname->n ) continue;
132c11d4f93Sdrh     if( sqliteStrNICmp(db->aDb[i].zName, pDbname->z, pDbname->n)==0 ) break;
133c11d4f93Sdrh   }
134c11d4f93Sdrh   if( i>=db->nDb ){
135c11d4f93Sdrh     sqliteErrorMsg(pParse, "no such database: %T", pDbname);
136c11d4f93Sdrh     return;
137c11d4f93Sdrh   }
138c11d4f93Sdrh   if( i<2 ){
139c11d4f93Sdrh     sqliteErrorMsg(pParse, "cannot detach database %T", pDbname);
140c11d4f93Sdrh     return;
141c11d4f93Sdrh   }
14281e293b4Sdrh #ifndef SQLITE_OMIT_AUTHORIZATION
14381e293b4Sdrh   if( sqliteAuthCheck(pParse,SQLITE_DETACH,db->aDb[i].zName,0,0)!=SQLITE_OK ){
14481e293b4Sdrh     return;
14581e293b4Sdrh   }
14681e293b4Sdrh #endif /* SQLITE_OMIT_AUTHORIZATION */
147c11d4f93Sdrh   sqliteBtreeClose(db->aDb[i].pBt);
148c11d4f93Sdrh   db->aDb[i].pBt = 0;
14970ce3f0cSdrh   sqliteFree(db->aDb[i].zName);
150c11d4f93Sdrh   sqliteResetInternalSchema(db, i);
151c11d4f93Sdrh   db->nDb--;
152c11d4f93Sdrh   if( i<db->nDb ){
153c11d4f93Sdrh     db->aDb[i] = db->aDb[db->nDb];
154c11d4f93Sdrh     memset(&db->aDb[db->nDb], 0, sizeof(db->aDb[0]));
155c11d4f93Sdrh     sqliteResetInternalSchema(db, i);
156c11d4f93Sdrh   }
157c11d4f93Sdrh }
158f26e09c8Sdrh 
159f26e09c8Sdrh /*
160f26e09c8Sdrh ** Initialize a DbFixer structure.  This routine must be called prior
161f26e09c8Sdrh ** to passing the structure to one of the sqliteFixAAAA() routines below.
162f26e09c8Sdrh **
163f26e09c8Sdrh ** The return value indicates whether or not fixation is required.  TRUE
164f26e09c8Sdrh ** means we do need to fix the database references, FALSE means we do not.
165f26e09c8Sdrh */
166f26e09c8Sdrh int sqliteFixInit(
167f26e09c8Sdrh   DbFixer *pFix,      /* The fixer to be initialized */
168f26e09c8Sdrh   Parse *pParse,      /* Error messages will be written here */
169f26e09c8Sdrh   int iDb,            /* This is the database that must must be used */
170f26e09c8Sdrh   const char *zType,  /* "view", "trigger", or "index" */
171f26e09c8Sdrh   const Token *pName  /* Name of the view, trigger, or index */
172f26e09c8Sdrh ){
173f26e09c8Sdrh   sqlite *db;
174f26e09c8Sdrh 
175f26e09c8Sdrh   if( iDb<0 || iDb==1 ) return 0;
176f26e09c8Sdrh   db = pParse->db;
177f26e09c8Sdrh   assert( db->nDb>iDb );
1784312db55Sdrh   pFix->pParse = pParse;
179f26e09c8Sdrh   pFix->zDb = db->aDb[iDb].zName;
180f26e09c8Sdrh   pFix->zType = zType;
181f26e09c8Sdrh   pFix->pName = pName;
182f26e09c8Sdrh   return 1;
183f26e09c8Sdrh }
184f26e09c8Sdrh 
185f26e09c8Sdrh /*
186f26e09c8Sdrh ** The following set of routines walk through the parse tree and assign
187f26e09c8Sdrh ** a specific database to all table references where the database name
188f26e09c8Sdrh ** was left unspecified in the original SQL statement.  The pFix structure
189f26e09c8Sdrh ** must have been initialized by a prior call to sqliteFixInit().
190f26e09c8Sdrh **
191f26e09c8Sdrh ** These routines are used to make sure that an index, trigger, or
192f26e09c8Sdrh ** view in one database does not refer to objects in a different database.
193f26e09c8Sdrh ** (Exception: indices, triggers, and views in the TEMP database are
194f26e09c8Sdrh ** allowed to refer to anything.)  If a reference is explicitly made
195f26e09c8Sdrh ** to an object in a different database, an error message is added to
196f26e09c8Sdrh ** pParse->zErrMsg and these routines return non-zero.  If everything
197f26e09c8Sdrh ** checks out, these routines return 0.
198f26e09c8Sdrh */
199f26e09c8Sdrh int sqliteFixSrcList(
200f26e09c8Sdrh   DbFixer *pFix,       /* Context of the fixation */
201f26e09c8Sdrh   SrcList *pList       /* The Source list to check and modify */
202f26e09c8Sdrh ){
203f26e09c8Sdrh   int i;
204f26e09c8Sdrh   const char *zDb;
205f26e09c8Sdrh 
206f26e09c8Sdrh   if( pList==0 ) return 0;
207f26e09c8Sdrh   zDb = pFix->zDb;
208f26e09c8Sdrh   for(i=0; i<pList->nSrc; i++){
209f26e09c8Sdrh     if( pList->a[i].zDatabase==0 ){
210f26e09c8Sdrh       pList->a[i].zDatabase = sqliteStrDup(zDb);
211f26e09c8Sdrh     }else if( sqliteStrICmp(pList->a[i].zDatabase,zDb)!=0 ){
212f26e09c8Sdrh       sqliteErrorMsg(pFix->pParse,
2134312db55Sdrh          "%s %z cannot reference objects in database %s",
2144312db55Sdrh          pFix->zType, sqliteStrNDup(pFix->pName->z, pFix->pName->n),
2154312db55Sdrh          pList->a[i].zDatabase);
216f26e09c8Sdrh       return 1;
217f26e09c8Sdrh     }
218f26e09c8Sdrh     if( sqliteFixSelect(pFix, pList->a[i].pSelect) ) return 1;
219f26e09c8Sdrh     if( sqliteFixExpr(pFix, pList->a[i].pOn) ) return 1;
220f26e09c8Sdrh   }
221f26e09c8Sdrh   return 0;
222f26e09c8Sdrh }
223f26e09c8Sdrh int sqliteFixSelect(
224f26e09c8Sdrh   DbFixer *pFix,       /* Context of the fixation */
225f26e09c8Sdrh   Select *pSelect      /* The SELECT statement to be fixed to one database */
226f26e09c8Sdrh ){
227f26e09c8Sdrh   while( pSelect ){
228f26e09c8Sdrh     if( sqliteFixExprList(pFix, pSelect->pEList) ){
229f26e09c8Sdrh       return 1;
230f26e09c8Sdrh     }
231f26e09c8Sdrh     if( sqliteFixSrcList(pFix, pSelect->pSrc) ){
232f26e09c8Sdrh       return 1;
233f26e09c8Sdrh     }
234f26e09c8Sdrh     if( sqliteFixExpr(pFix, pSelect->pWhere) ){
235f26e09c8Sdrh       return 1;
236f26e09c8Sdrh     }
237f26e09c8Sdrh     if( sqliteFixExpr(pFix, pSelect->pHaving) ){
238f26e09c8Sdrh       return 1;
239f26e09c8Sdrh     }
240f26e09c8Sdrh     pSelect = pSelect->pPrior;
241f26e09c8Sdrh   }
242f26e09c8Sdrh   return 0;
243f26e09c8Sdrh }
244f26e09c8Sdrh int sqliteFixExpr(
245f26e09c8Sdrh   DbFixer *pFix,     /* Context of the fixation */
246f26e09c8Sdrh   Expr *pExpr        /* The expression to be fixed to one database */
247f26e09c8Sdrh ){
248f26e09c8Sdrh   while( pExpr ){
249f26e09c8Sdrh     if( sqliteFixSelect(pFix, pExpr->pSelect) ){
250f26e09c8Sdrh       return 1;
251f26e09c8Sdrh     }
252f26e09c8Sdrh     if( sqliteFixExprList(pFix, pExpr->pList) ){
253f26e09c8Sdrh       return 1;
254f26e09c8Sdrh     }
255f26e09c8Sdrh     if( sqliteFixExpr(pFix, pExpr->pRight) ){
256f26e09c8Sdrh       return 1;
257f26e09c8Sdrh     }
258f26e09c8Sdrh     pExpr = pExpr->pLeft;
259f26e09c8Sdrh   }
260f26e09c8Sdrh   return 0;
261f26e09c8Sdrh }
262f26e09c8Sdrh int sqliteFixExprList(
263f26e09c8Sdrh   DbFixer *pFix,     /* Context of the fixation */
264f26e09c8Sdrh   ExprList *pList    /* The expression to be fixed to one database */
265f26e09c8Sdrh ){
266f26e09c8Sdrh   int i;
267f26e09c8Sdrh   if( pList==0 ) return 0;
268f26e09c8Sdrh   for(i=0; i<pList->nExpr; i++){
269f26e09c8Sdrh     if( sqliteFixExpr(pFix, pList->a[i].pExpr) ){
270f26e09c8Sdrh       return 1;
271f26e09c8Sdrh     }
272f26e09c8Sdrh   }
273f26e09c8Sdrh   return 0;
274f26e09c8Sdrh }
275f26e09c8Sdrh int sqliteFixTriggerStep(
276f26e09c8Sdrh   DbFixer *pFix,     /* Context of the fixation */
277f26e09c8Sdrh   TriggerStep *pStep /* The trigger step be fixed to one database */
278f26e09c8Sdrh ){
279f26e09c8Sdrh   while( pStep ){
280f26e09c8Sdrh     if( sqliteFixSelect(pFix, pStep->pSelect) ){
281f26e09c8Sdrh       return 1;
282f26e09c8Sdrh     }
283f26e09c8Sdrh     if( sqliteFixExpr(pFix, pStep->pWhere) ){
284f26e09c8Sdrh       return 1;
285f26e09c8Sdrh     }
286f26e09c8Sdrh     if( sqliteFixExprList(pFix, pStep->pExprList) ){
287f26e09c8Sdrh       return 1;
288f26e09c8Sdrh     }
289f26e09c8Sdrh     pStep = pStep->pNext;
290f26e09c8Sdrh   }
291f26e09c8Sdrh   return 0;
292f26e09c8Sdrh }
293