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$
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 */
sqliteAttach(Parse * pParse,Token * pFilename,Token * pDbname,Token * pKey)26 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 v = sqliteGetVdbe(pParse);
34 sqliteVdbeAddOp(v, OP_Halt, 0, 0);
35 if( pParse->explain ) return;
36 db = pParse->db;
37 if( db->file_format<4 ){
38 sqliteErrorMsg(pParse, "cannot attach auxiliary databases to an "
39 "older format master database", 0);
40 pParse->rc = SQLITE_ERROR;
41 return;
42 }
43 if( db->nDb>=MAX_ATTACHED+2 ){
44 sqliteErrorMsg(pParse, "too many attached databases - max %d",
45 MAX_ATTACHED);
46 pParse->rc = SQLITE_ERROR;
47 return;
48 }
49
50 zFile = 0;
51 sqliteSetNString(&zFile, pFilename->z, pFilename->n, 0);
52 if( zFile==0 ) return;
53 sqliteDequote(zFile);
54 #ifndef SQLITE_OMIT_AUTHORIZATION
55 if( sqliteAuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){
56 sqliteFree(zFile);
57 return;
58 }
59 #endif /* SQLITE_OMIT_AUTHORIZATION */
60
61 zName = 0;
62 sqliteSetNString(&zName, pDbname->z, pDbname->n, 0);
63 if( zName==0 ) return;
64 sqliteDequote(zName);
65 for(i=0; i<db->nDb; i++){
66 if( db->aDb[i].zName && sqliteStrICmp(db->aDb[i].zName, zName)==0 ){
67 sqliteErrorMsg(pParse, "database %z is already in use", zName);
68 pParse->rc = SQLITE_ERROR;
69 sqliteFree(zFile);
70 return;
71 }
72 }
73
74 if( db->aDb==db->aDbStatic ){
75 aNew = sqliteMalloc( sizeof(db->aDb[0])*3 );
76 if( aNew==0 ) return;
77 memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
78 }else{
79 aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
80 if( aNew==0 ) return;
81 }
82 db->aDb = aNew;
83 aNew = &db->aDb[db->nDb++];
84 memset(aNew, 0, sizeof(*aNew));
85 sqliteHashInit(&aNew->tblHash, SQLITE_HASH_STRING, 0);
86 sqliteHashInit(&aNew->idxHash, SQLITE_HASH_STRING, 0);
87 sqliteHashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0);
88 sqliteHashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1);
89 aNew->zName = zName;
90 rc = sqliteBtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
91 if( rc ){
92 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 sqliteFree(zFile);
111 db->flags &= ~SQLITE_Initialized;
112 if( pParse->nErr ) return;
113 if( rc==SQLITE_OK ){
114 rc = sqliteInit(pParse->db, &pParse->zErrMsg);
115 }
116 if( rc ){
117 int i = db->nDb - 1;
118 assert( i>=2 );
119 if( db->aDb[i].pBt ){
120 sqliteBtreeClose(db->aDb[i].pBt);
121 db->aDb[i].pBt = 0;
122 }
123 sqliteResetInternalSchema(db, 0);
124 pParse->nErr++;
125 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 */
sqliteDetach(Parse * pParse,Token * pDbname)136 void sqliteDetach(Parse *pParse, Token *pDbname){
137 int i;
138 sqlite *db;
139 Vdbe *v;
140 Db *pDb;
141
142 v = sqliteGetVdbe(pParse);
143 sqliteVdbeAddOp(v, OP_Halt, 0, 0);
144 if( pParse->explain ) return;
145 db = pParse->db;
146 for(i=0; i<db->nDb; i++){
147 pDb = &db->aDb[i];
148 if( pDb->pBt==0 || pDb->zName==0 ) continue;
149 if( strlen(pDb->zName)!=pDbname->n ) continue;
150 if( sqliteStrNICmp(pDb->zName, pDbname->z, pDbname->n)==0 ) break;
151 }
152 if( i>=db->nDb ){
153 sqliteErrorMsg(pParse, "no such database: %T", pDbname);
154 return;
155 }
156 if( i<2 ){
157 sqliteErrorMsg(pParse, "cannot detach database %T", pDbname);
158 return;
159 }
160 #ifndef SQLITE_OMIT_AUTHORIZATION
161 if( sqliteAuthCheck(pParse,SQLITE_DETACH,db->aDb[i].zName,0,0)!=SQLITE_OK ){
162 return;
163 }
164 #endif /* SQLITE_OMIT_AUTHORIZATION */
165 sqliteBtreeClose(pDb->pBt);
166 pDb->pBt = 0;
167 sqliteFree(pDb->zName);
168 sqliteResetInternalSchema(db, i);
169 if( pDb->pAux && pDb->xFreeAux ) pDb->xFreeAux(pDb->pAux);
170 db->nDb--;
171 if( i<db->nDb ){
172 db->aDb[i] = db->aDb[db->nDb];
173 memset(&db->aDb[db->nDb], 0, sizeof(db->aDb[0]));
174 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 */
sqliteFixInit(DbFixer * pFix,Parse * pParse,int iDb,const char * zType,const Token * pName)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 ){
192 sqlite *db;
193
194 if( iDb<0 || iDb==1 ) return 0;
195 db = pParse->db;
196 assert( db->nDb>iDb );
197 pFix->pParse = pParse;
198 pFix->zDb = db->aDb[iDb].zName;
199 pFix->zType = zType;
200 pFix->pName = pName;
201 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 */
sqliteFixSrcList(DbFixer * pFix,SrcList * pList)218 int sqliteFixSrcList(
219 DbFixer *pFix, /* Context of the fixation */
220 SrcList *pList /* The Source list to check and modify */
221 ){
222 int i;
223 const char *zDb;
224
225 if( pList==0 ) return 0;
226 zDb = pFix->zDb;
227 for(i=0; i<pList->nSrc; i++){
228 if( pList->a[i].zDatabase==0 ){
229 pList->a[i].zDatabase = sqliteStrDup(zDb);
230 }else if( sqliteStrICmp(pList->a[i].zDatabase,zDb)!=0 ){
231 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 return 1;
236 }
237 if( sqliteFixSelect(pFix, pList->a[i].pSelect) ) return 1;
238 if( sqliteFixExpr(pFix, pList->a[i].pOn) ) return 1;
239 }
240 return 0;
241 }
sqliteFixSelect(DbFixer * pFix,Select * pSelect)242 int sqliteFixSelect(
243 DbFixer *pFix, /* Context of the fixation */
244 Select *pSelect /* The SELECT statement to be fixed to one database */
245 ){
246 while( pSelect ){
247 if( sqliteFixExprList(pFix, pSelect->pEList) ){
248 return 1;
249 }
250 if( sqliteFixSrcList(pFix, pSelect->pSrc) ){
251 return 1;
252 }
253 if( sqliteFixExpr(pFix, pSelect->pWhere) ){
254 return 1;
255 }
256 if( sqliteFixExpr(pFix, pSelect->pHaving) ){
257 return 1;
258 }
259 pSelect = pSelect->pPrior;
260 }
261 return 0;
262 }
sqliteFixExpr(DbFixer * pFix,Expr * pExpr)263 int sqliteFixExpr(
264 DbFixer *pFix, /* Context of the fixation */
265 Expr *pExpr /* The expression to be fixed to one database */
266 ){
267 while( pExpr ){
268 if( sqliteFixSelect(pFix, pExpr->pSelect) ){
269 return 1;
270 }
271 if( sqliteFixExprList(pFix, pExpr->pList) ){
272 return 1;
273 }
274 if( sqliteFixExpr(pFix, pExpr->pRight) ){
275 return 1;
276 }
277 pExpr = pExpr->pLeft;
278 }
279 return 0;
280 }
sqliteFixExprList(DbFixer * pFix,ExprList * pList)281 int sqliteFixExprList(
282 DbFixer *pFix, /* Context of the fixation */
283 ExprList *pList /* The expression to be fixed to one database */
284 ){
285 int i;
286 if( pList==0 ) return 0;
287 for(i=0; i<pList->nExpr; i++){
288 if( sqliteFixExpr(pFix, pList->a[i].pExpr) ){
289 return 1;
290 }
291 }
292 return 0;
293 }
sqliteFixTriggerStep(DbFixer * pFix,TriggerStep * pStep)294 int sqliteFixTriggerStep(
295 DbFixer *pFix, /* Context of the fixation */
296 TriggerStep *pStep /* The trigger step be fixed to one database */
297 ){
298 while( pStep ){
299 if( sqliteFixSelect(pFix, pStep->pSelect) ){
300 return 1;
301 }
302 if( sqliteFixExpr(pFix, pStep->pWhere) ){
303 return 1;
304 }
305 if( sqliteFixExprList(pFix, pStep->pExprList) ){
306 return 1;
307 }
308 pStep = pStep->pNext;
309 }
310 return 0;
311 }
312