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 195361 2005-09-07 15:11:33Z iliaa $
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 0 : void sqliteAttach(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 0 : v = sqliteGetVdbe(pParse);
34 0 : sqliteVdbeAddOp(v, OP_Halt, 0, 0);
35 0 : if( pParse->explain ) return;
36 0 : db = pParse->db;
37 0 : if( db->file_format<4 ){
38 0 : sqliteErrorMsg(pParse, "cannot attach auxiliary databases to an "
39 : "older format master database", 0);
40 0 : pParse->rc = SQLITE_ERROR;
41 0 : return;
42 : }
43 0 : if( db->nDb>=MAX_ATTACHED+2 ){
44 0 : sqliteErrorMsg(pParse, "too many attached databases - max %d",
45 : MAX_ATTACHED);
46 0 : pParse->rc = SQLITE_ERROR;
47 0 : return;
48 : }
49 :
50 0 : zFile = 0;
51 0 : sqliteSetNString(&zFile, pFilename->z, pFilename->n, 0);
52 0 : if( zFile==0 ) return;
53 0 : sqliteDequote(zFile);
54 : #ifndef SQLITE_OMIT_AUTHORIZATION
55 0 : if( sqliteAuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){
56 0 : sqliteFree(zFile);
57 0 : return;
58 : }
59 : #endif /* SQLITE_OMIT_AUTHORIZATION */
60 :
61 0 : zName = 0;
62 0 : sqliteSetNString(&zName, pDbname->z, pDbname->n, 0);
63 0 : if( zName==0 ) return;
64 0 : sqliteDequote(zName);
65 0 : for(i=0; i<db->nDb; i++){
66 0 : if( db->aDb[i].zName && sqliteStrICmp(db->aDb[i].zName, zName)==0 ){
67 0 : sqliteErrorMsg(pParse, "database %z is already in use", zName);
68 0 : pParse->rc = SQLITE_ERROR;
69 0 : sqliteFree(zFile);
70 0 : return;
71 : }
72 : }
73 :
74 0 : if( db->aDb==db->aDbStatic ){
75 0 : aNew = sqliteMalloc( sizeof(db->aDb[0])*3 );
76 0 : if( aNew==0 ) return;
77 0 : memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
78 : }else{
79 0 : aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
80 0 : if( aNew==0 ) return;
81 : }
82 0 : db->aDb = aNew;
83 0 : aNew = &db->aDb[db->nDb++];
84 0 : memset(aNew, 0, sizeof(*aNew));
85 0 : sqliteHashInit(&aNew->tblHash, SQLITE_HASH_STRING, 0);
86 0 : sqliteHashInit(&aNew->idxHash, SQLITE_HASH_STRING, 0);
87 0 : sqliteHashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0);
88 0 : sqliteHashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1);
89 0 : aNew->zName = zName;
90 0 : rc = sqliteBtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
91 0 : if( rc ){
92 0 : sqliteErrorMsg(pParse, "unable to open database: %s", zFile);
93 : }
94 : #if SQLITE_HAS_CODEC
95 : {
96 : extern int sqliteCodecAttach(sqlite*, int, void*, int);
97 : char *zKey = 0;
98 : int nKey;
99 : if( pKey && pKey->z && pKey->n ){
100 : sqliteSetNString(&zKey, pKey->z, pKey->n, 0);
101 : sqliteDequote(zKey);
102 : nKey = strlen(zKey);
103 : }else{
104 : zKey = 0;
105 : nKey = 0;
106 : }
107 : sqliteCodecAttach(db, db->nDb-1, zKey, nKey);
108 : }
109 : #endif
110 0 : sqliteFree(zFile);
111 0 : db->flags &= ~SQLITE_Initialized;
112 0 : if( pParse->nErr ) return;
113 0 : if( rc==SQLITE_OK ){
114 0 : rc = sqliteInit(pParse->db, &pParse->zErrMsg);
115 : }
116 0 : if( rc ){
117 0 : int i = db->nDb - 1;
118 : assert( i>=2 );
119 0 : if( db->aDb[i].pBt ){
120 0 : sqliteBtreeClose(db->aDb[i].pBt);
121 0 : db->aDb[i].pBt = 0;
122 : }
123 0 : sqliteResetInternalSchema(db, 0);
124 0 : pParse->nErr++;
125 0 : pParse->rc = SQLITE_ERROR;
126 : }
127 : }
128 :
129 : /*
130 : ** This routine is called by the parser to process a DETACH statement:
131 : **
132 : ** DETACH DATABASE dbname
133 : **
134 : ** The pDbname argument is the name of the database in the DETACH statement.
135 : */
136 0 : void sqliteDetach(Parse *pParse, Token *pDbname){
137 : int i;
138 : sqlite *db;
139 : Vdbe *v;
140 : Db *pDb;
141 :
142 0 : v = sqliteGetVdbe(pParse);
143 0 : sqliteVdbeAddOp(v, OP_Halt, 0, 0);
144 0 : if( pParse->explain ) return;
145 0 : db = pParse->db;
146 0 : for(i=0; i<db->nDb; i++){
147 0 : pDb = &db->aDb[i];
148 0 : if( pDb->pBt==0 || pDb->zName==0 ) continue;
149 0 : if( strlen(pDb->zName)!=pDbname->n ) continue;
150 0 : if( sqliteStrNICmp(pDb->zName, pDbname->z, pDbname->n)==0 ) break;
151 : }
152 0 : if( i>=db->nDb ){
153 0 : sqliteErrorMsg(pParse, "no such database: %T", pDbname);
154 0 : return;
155 : }
156 0 : if( i<2 ){
157 0 : sqliteErrorMsg(pParse, "cannot detach database %T", pDbname);
158 0 : return;
159 : }
160 : #ifndef SQLITE_OMIT_AUTHORIZATION
161 0 : if( sqliteAuthCheck(pParse,SQLITE_DETACH,db->aDb[i].zName,0,0)!=SQLITE_OK ){
162 0 : return;
163 : }
164 : #endif /* SQLITE_OMIT_AUTHORIZATION */
165 0 : sqliteBtreeClose(pDb->pBt);
166 0 : pDb->pBt = 0;
167 0 : sqliteFree(pDb->zName);
168 0 : sqliteResetInternalSchema(db, i);
169 0 : if( pDb->pAux && pDb->xFreeAux ) pDb->xFreeAux(pDb->pAux);
170 0 : db->nDb--;
171 0 : if( i<db->nDb ){
172 0 : db->aDb[i] = db->aDb[db->nDb];
173 0 : memset(&db->aDb[db->nDb], 0, sizeof(db->aDb[0]));
174 0 : sqliteResetInternalSchema(db, i);
175 : }
176 : }
177 :
178 : /*
179 : ** Initialize a DbFixer structure. This routine must be called prior
180 : ** to passing the structure to one of the sqliteFixAAAA() routines below.
181 : **
182 : ** The return value indicates whether or not fixation is required. TRUE
183 : ** means we do need to fix the database references, FALSE means we do not.
184 : */
185 : int sqliteFixInit(
186 : DbFixer *pFix, /* The fixer to be initialized */
187 : Parse *pParse, /* Error messages will be written here */
188 : int iDb, /* This is the database that must must be used */
189 : const char *zType, /* "view", "trigger", or "index" */
190 : const Token *pName /* Name of the view, trigger, or index */
191 1 : ){
192 : sqlite *db;
193 :
194 1 : if( iDb<0 || iDb==1 ) return 0;
195 1 : db = pParse->db;
196 : assert( db->nDb>iDb );
197 1 : pFix->pParse = pParse;
198 1 : pFix->zDb = db->aDb[iDb].zName;
199 1 : pFix->zType = zType;
200 1 : pFix->pName = pName;
201 1 : return 1;
202 : }
203 :
204 : /*
205 : ** The following set of routines walk through the parse tree and assign
206 : ** a specific database to all table references where the database name
207 : ** was left unspecified in the original SQL statement. The pFix structure
208 : ** must have been initialized by a prior call to sqliteFixInit().
209 : **
210 : ** These routines are used to make sure that an index, trigger, or
211 : ** view in one database does not refer to objects in a different database.
212 : ** (Exception: indices, triggers, and views in the TEMP database are
213 : ** allowed to refer to anything.) If a reference is explicitly made
214 : ** to an object in a different database, an error message is added to
215 : ** pParse->zErrMsg and these routines return non-zero. If everything
216 : ** checks out, these routines return 0.
217 : */
218 : int sqliteFixSrcList(
219 : DbFixer *pFix, /* Context of the fixation */
220 : SrcList *pList /* The Source list to check and modify */
221 1 : ){
222 : int i;
223 : const char *zDb;
224 :
225 1 : if( pList==0 ) return 0;
226 0 : zDb = pFix->zDb;
227 0 : for(i=0; i<pList->nSrc; i++){
228 0 : if( pList->a[i].zDatabase==0 ){
229 0 : pList->a[i].zDatabase = sqliteStrDup(zDb);
230 0 : }else if( sqliteStrICmp(pList->a[i].zDatabase,zDb)!=0 ){
231 0 : sqliteErrorMsg(pFix->pParse,
232 : "%s %z cannot reference objects in database %s",
233 : pFix->zType, sqliteStrNDup(pFix->pName->z, pFix->pName->n),
234 : pList->a[i].zDatabase);
235 0 : return 1;
236 : }
237 0 : if( sqliteFixSelect(pFix, pList->a[i].pSelect) ) return 1;
238 0 : if( sqliteFixExpr(pFix, pList->a[i].pOn) ) return 1;
239 : }
240 0 : return 0;
241 : }
242 : int sqliteFixSelect(
243 : DbFixer *pFix, /* Context of the fixation */
244 : Select *pSelect /* The SELECT statement to be fixed to one database */
245 0 : ){
246 0 : while( pSelect ){
247 0 : if( sqliteFixExprList(pFix, pSelect->pEList) ){
248 0 : return 1;
249 : }
250 0 : if( sqliteFixSrcList(pFix, pSelect->pSrc) ){
251 0 : return 1;
252 : }
253 0 : if( sqliteFixExpr(pFix, pSelect->pWhere) ){
254 0 : return 1;
255 : }
256 0 : if( sqliteFixExpr(pFix, pSelect->pHaving) ){
257 0 : return 1;
258 : }
259 0 : pSelect = pSelect->pPrior;
260 : }
261 0 : return 0;
262 : }
263 : int sqliteFixExpr(
264 : DbFixer *pFix, /* Context of the fixation */
265 : Expr *pExpr /* The expression to be fixed to one database */
266 0 : ){
267 0 : while( pExpr ){
268 0 : if( sqliteFixSelect(pFix, pExpr->pSelect) ){
269 0 : return 1;
270 : }
271 0 : if( sqliteFixExprList(pFix, pExpr->pList) ){
272 0 : return 1;
273 : }
274 0 : if( sqliteFixExpr(pFix, pExpr->pRight) ){
275 0 : return 1;
276 : }
277 0 : pExpr = pExpr->pLeft;
278 : }
279 0 : return 0;
280 : }
281 : int sqliteFixExprList(
282 : DbFixer *pFix, /* Context of the fixation */
283 : ExprList *pList /* The expression to be fixed to one database */
284 0 : ){
285 : int i;
286 0 : if( pList==0 ) return 0;
287 0 : for(i=0; i<pList->nExpr; i++){
288 0 : if( sqliteFixExpr(pFix, pList->a[i].pExpr) ){
289 0 : return 1;
290 : }
291 : }
292 0 : return 0;
293 : }
294 : int sqliteFixTriggerStep(
295 : DbFixer *pFix, /* Context of the fixation */
296 : TriggerStep *pStep /* The trigger step be fixed to one database */
297 0 : ){
298 0 : while( pStep ){
299 0 : if( sqliteFixSelect(pFix, pStep->pSelect) ){
300 0 : return 1;
301 : }
302 0 : if( sqliteFixExpr(pFix, pStep->pWhere) ){
303 0 : return 1;
304 : }
305 0 : if( sqliteFixExprList(pFix, pStep->pExprList) ){
306 0 : return 1;
307 : }
308 0 : pStep = pStep->pNext;
309 : }
310 0 : return 0;
311 : }
|