File Coverage

attach.c
Criterion Covered Total %
statement 23 147 15.6
branch 10 106 9.4
condition n/a
subroutine n/a
pod n/a
total 33 253 13.0


line stmt bran cond sub pod time code
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.1.1.1 2004/08/08 15:03:56 matt 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 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 0         if( pParse->explain ) return;
36 0           db = pParse->db;
37 0 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 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 0         if( zFile==0 ) return;
53 0           sqliteDequote(zFile);
54             #ifndef SQLITE_OMIT_AUTHORIZATION
55 0 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 0         if( zName==0 ) return;
64 0           sqliteDequote(zName);
65 0 0         for(i=0; inDb; i++){
66 0 0         if( db->aDb[i].zName && sqliteStrICmp(db->aDb[i].zName, zName)==0 ){
    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 0         if( db->aDb==db->aDbStatic ){
75 0           aNew = sqliteMalloc( sizeof(db->aDb[0])*3 );
76 0 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 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 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 0         if( pParse->nErr ) return;
113 0 0         if( rc==SQLITE_OK ){
114 0           rc = sqliteInit(pParse->db, &pParse->zErrMsg);
115             }
116 0 0         if( rc ){
117 0           int i = db->nDb - 1;
118             assert( i>=2 );
119 0 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 0         if( pParse->explain ) return;
145 0           db = pParse->db;
146 0 0         for(i=0; inDb; i++){
147 0           pDb = &db->aDb[i];
148 0 0         if( pDb->pBt==0 || pDb->zName==0 ) continue;
    0          
149 0 0         if( strlen(pDb->zName)!=pDbname->n ) continue;
150 0 0         if( sqliteStrNICmp(pDb->zName, pDbname->z, pDbname->n)==0 ) break;
151             }
152 0 0         if( i>=db->nDb ){
153 0           sqliteErrorMsg(pParse, "no such database: %T", pDbname);
154 0           return;
155             }
156 0 0         if( i<2 ){
157 0           sqliteErrorMsg(pParse, "cannot detach database %T", pDbname);
158 0           return;
159             }
160             #ifndef SQLITE_OMIT_AUTHORIZATION
161 0 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 0         if( pDb->pAux && pDb->xFreeAux ) pDb->xFreeAux(pDb->pAux);
    0          
170 0           db->nDb--;
171 0 0         if( inDb ){
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 3           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 3 50         if( iDb<0 || iDb==1 ) return 0;
    50          
195 3           db = pParse->db;
196             assert( db->nDb>iDb );
197 3           pFix->pParse = pParse;
198 3           pFix->zDb = db->aDb[iDb].zName;
199 3           pFix->zType = zType;
200 3           pFix->pName = pName;
201 3           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 3           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 3 50         if( pList==0 ) return 0;
226 3           zDb = pFix->zDb;
227 6 100         for(i=0; inSrc; i++){
228 3 50         if( pList->a[i].zDatabase==0 ){
229 3           pList->a[i].zDatabase = sqliteStrDup(zDb);
230 0 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 0           pFix->zType, sqliteStrNDup(pFix->pName->z, pFix->pName->n),
234             pList->a[i].zDatabase);
235 0           return 1;
236             }
237 3 50         if( sqliteFixSelect(pFix, pList->a[i].pSelect) ) return 1;
238 3 50         if( sqliteFixExpr(pFix, pList->a[i].pOn) ) return 1;
239             }
240 3           return 0;
241             }
242 3           int sqliteFixSelect(
243             DbFixer *pFix, /* Context of the fixation */
244             Select *pSelect /* The SELECT statement to be fixed to one database */
245             ){
246 3 50         while( pSelect ){
247 0 0         if( sqliteFixExprList(pFix, pSelect->pEList) ){
248 0           return 1;
249             }
250 0 0         if( sqliteFixSrcList(pFix, pSelect->pSrc) ){
251 0           return 1;
252             }
253 0 0         if( sqliteFixExpr(pFix, pSelect->pWhere) ){
254 0           return 1;
255             }
256 0 0         if( sqliteFixExpr(pFix, pSelect->pHaving) ){
257 0           return 1;
258             }
259 0           pSelect = pSelect->pPrior;
260             }
261 3           return 0;
262             }
263 3           int sqliteFixExpr(
264             DbFixer *pFix, /* Context of the fixation */
265             Expr *pExpr /* The expression to be fixed to one database */
266             ){
267 3 50         while( pExpr ){
268 0 0         if( sqliteFixSelect(pFix, pExpr->pSelect) ){
269 0           return 1;
270             }
271 0 0         if( sqliteFixExprList(pFix, pExpr->pList) ){
272 0           return 1;
273             }
274 0 0         if( sqliteFixExpr(pFix, pExpr->pRight) ){
275 0           return 1;
276             }
277 0           pExpr = pExpr->pLeft;
278             }
279 3           return 0;
280             }
281 0           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 0 0         if( pList==0 ) return 0;
287 0 0         for(i=0; inExpr; i++){
288 0 0         if( sqliteFixExpr(pFix, pList->a[i].pExpr) ){
289 0           return 1;
290             }
291             }
292 0           return 0;
293             }
294 0           int sqliteFixTriggerStep(
295             DbFixer *pFix, /* Context of the fixation */
296             TriggerStep *pStep /* The trigger step be fixed to one database */
297             ){
298 0 0         while( pStep ){
299 0 0         if( sqliteFixSelect(pFix, pStep->pSelect) ){
300 0           return 1;
301             }
302 0 0         if( sqliteFixExpr(pFix, pStep->pWhere) ){
303 0           return 1;
304             }
305 0 0         if( sqliteFixExprList(pFix, pStep->pExprList) ){
306 0           return 1;
307             }
308 0           pStep = pStep->pNext;
309             }
310 0           return 0;
311             }