xref: /sqlite-3.40.0/src/attach.c (revision ef5ecb41)
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