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