64-bit fixes.
[AROS-Contrib.git] / sqlite3 / attach.c
blob12d227fdf9c355868ded1fa5316e6ec48f095e18
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.
11 *************************************************************************
12 ** This file contains code used to implement the ATTACH and DETACH commands.
14 ** $Id$
16 #include "sqliteInt.h"
19 ** This routine is called by the parser to process an ATTACH statement:
21 ** ATTACH DATABASE filename AS dbname
23 ** The pFilename and pDbname arguments are the tokens that define the
24 ** filename and dbname in the ATTACH statement.
26 void sqlite3Attach(
27 Parse *pParse, /* The parser context */
28 Token *pFilename, /* Name of database file */
29 Token *pDbname, /* Name of the database to use internally */
30 int keyType, /* 0: no key. 1: TEXT, 2: BLOB */
31 Token *pKey /* Text of the key for keytype 1 and 2 */
33 Db *aNew;
34 int rc, i;
35 char *zFile = 0;
36 char *zName = 0;
37 sqlite3 *db;
38 Vdbe *v;
40 v = sqlite3GetVdbe(pParse);
41 if( !v ) return;
42 sqlite3VdbeAddOp(v, OP_Expire, 1, 0);
43 sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
44 if( pParse->explain ) return;
45 db = pParse->db;
46 if( db->nDb>=MAX_ATTACHED+2 ){
47 sqlite3ErrorMsg(pParse, "too many attached databases - max %d",
48 MAX_ATTACHED);
49 pParse->rc = SQLITE_ERROR;
50 return;
53 if( !db->autoCommit ){
54 sqlite3ErrorMsg(pParse, "cannot ATTACH database within transaction");
55 pParse->rc = SQLITE_ERROR;
56 return;
59 zFile = sqlite3NameFromToken(pFilename);
60 if( zFile==0 ){
61 goto attach_end;
63 #ifndef SQLITE_OMIT_AUTHORIZATION
64 if( sqlite3AuthCheck(pParse, SQLITE_ATTACH, zFile, 0, 0)!=SQLITE_OK ){
65 goto attach_end;
67 #endif /* SQLITE_OMIT_AUTHORIZATION */
69 zName = sqlite3NameFromToken(pDbname);
70 if( zName==0 ){
71 goto attach_end;
73 for(i=0; i<db->nDb; i++){
74 char *z = db->aDb[i].zName;
75 if( z && sqlite3StrICmp(z, zName)==0 ){
76 sqlite3ErrorMsg(pParse, "database %s is already in use", zName);
77 pParse->rc = SQLITE_ERROR;
78 goto attach_end;
82 if( db->aDb==db->aDbStatic ){
83 aNew = sqliteMalloc( sizeof(db->aDb[0])*3 );
84 if( aNew==0 ){
85 goto attach_end;
87 memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
88 }else{
89 aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
90 if( aNew==0 ){
91 goto attach_end;
94 db->aDb = aNew;
95 aNew = &db->aDb[db->nDb++];
96 memset(aNew, 0, sizeof(*aNew));
97 sqlite3HashInit(&aNew->tblHash, SQLITE_HASH_STRING, 0);
98 sqlite3HashInit(&aNew->idxHash, SQLITE_HASH_STRING, 0);
99 sqlite3HashInit(&aNew->trigHash, SQLITE_HASH_STRING, 0);
100 sqlite3HashInit(&aNew->aFKey, SQLITE_HASH_STRING, 1);
101 aNew->zName = zName;
102 zName = 0;
103 aNew->safety_level = 3;
104 rc = sqlite3BtreeFactory(db, zFile, 0, MAX_PAGES, &aNew->pBt);
105 if( rc ){
106 sqlite3ErrorMsg(pParse, "unable to open database: %s", zFile);
108 #if SQLITE_HAS_CODEC
110 extern int sqlite3CodecAttach(sqlite3*, int, void*, int);
111 char *zKey;
112 int nKey;
113 if( keyType==0 ){
114 /* No key specified. Use the key from the main database */
115 extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
116 sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
117 }else if( keyType==1 ){
118 /* Key specified as text */
119 zKey = sqlite3NameFromToken(pKey);
120 nKey = strlen(zKey);
121 }else{
122 /* Key specified as a BLOB */
123 char *zTemp;
124 assert( keyType==2 );
125 pKey->z++;
126 pKey->n--;
127 zTemp = sqlite3NameFromToken(pKey);
128 zKey = sqlite3HexToBlob(zTemp);
129 sqliteFree(zTemp);
131 sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
132 if( keyType ){
133 sqliteFree(zKey);
136 #endif
137 db->flags &= ~SQLITE_Initialized;
138 if( pParse->nErr==0 && rc==SQLITE_OK ){
139 rc = sqlite3ReadSchema(pParse);
141 if( rc ){
142 int i = db->nDb - 1;
143 assert( i>=2 );
144 if( db->aDb[i].pBt ){
145 sqlite3BtreeClose(db->aDb[i].pBt);
146 db->aDb[i].pBt = 0;
148 sqlite3ResetInternalSchema(db, 0);
149 if( 0==pParse->nErr ){
150 pParse->nErr++;
151 pParse->rc = SQLITE_ERROR;
155 attach_end:
156 sqliteFree(zFile);
157 sqliteFree(zName);
161 ** This routine is called by the parser to process a DETACH statement:
163 ** DETACH DATABASE dbname
165 ** The pDbname argument is the name of the database in the DETACH statement.
167 void sqlite3Detach(Parse *pParse, Token *pDbname){
168 int i;
169 sqlite3 *db;
170 Vdbe *v;
171 Db *pDb = 0;
172 char *zName;
174 v = sqlite3GetVdbe(pParse);
175 if( !v ) return;
176 sqlite3VdbeAddOp(v, OP_Expire, 0, 0);
177 sqlite3VdbeAddOp(v, OP_Halt, 0, 0);
178 if( pParse->explain ) return;
179 db = pParse->db;
180 zName = sqlite3NameFromToken(pDbname);
181 if( zName==0 ) return;
182 for(i=0; i<db->nDb; i++){
183 pDb = &db->aDb[i];
184 if( pDb->pBt==0 ) continue;
185 if( sqlite3StrICmp(pDb->zName, zName)==0 ) break;
187 if( i>=db->nDb ){
188 sqlite3ErrorMsg(pParse, "no such database: %z", zName);
189 return;
191 if( i<2 ){
192 sqlite3ErrorMsg(pParse, "cannot detach database %z", zName);
193 return;
195 sqliteFree(zName);
196 if( !db->autoCommit ){
197 sqlite3ErrorMsg(pParse, "cannot DETACH database within transaction");
198 pParse->rc = SQLITE_ERROR;
199 return;
201 #ifndef SQLITE_OMIT_AUTHORIZATION
202 if( sqlite3AuthCheck(pParse,SQLITE_DETACH,db->aDb[i].zName,0,0)!=SQLITE_OK ){
203 return;
205 #endif /* SQLITE_OMIT_AUTHORIZATION */
206 sqlite3BtreeClose(pDb->pBt);
207 pDb->pBt = 0;
208 sqlite3ResetInternalSchema(db, 0);
212 ** Initialize a DbFixer structure. This routine must be called prior
213 ** to passing the structure to one of the sqliteFixAAAA() routines below.
215 ** The return value indicates whether or not fixation is required. TRUE
216 ** means we do need to fix the database references, FALSE means we do not.
218 int sqlite3FixInit(
219 DbFixer *pFix, /* The fixer to be initialized */
220 Parse *pParse, /* Error messages will be written here */
221 int iDb, /* This is the database that must be used */
222 const char *zType, /* "view", "trigger", or "index" */
223 const Token *pName /* Name of the view, trigger, or index */
225 sqlite3 *db;
227 if( iDb<0 || iDb==1 ) return 0;
228 db = pParse->db;
229 assert( db->nDb>iDb );
230 pFix->pParse = pParse;
231 pFix->zDb = db->aDb[iDb].zName;
232 pFix->zType = zType;
233 pFix->pName = pName;
234 return 1;
238 ** The following set of routines walk through the parse tree and assign
239 ** a specific database to all table references where the database name
240 ** was left unspecified in the original SQL statement. The pFix structure
241 ** must have been initialized by a prior call to sqlite3FixInit().
243 ** These routines are used to make sure that an index, trigger, or
244 ** view in one database does not refer to objects in a different database.
245 ** (Exception: indices, triggers, and views in the TEMP database are
246 ** allowed to refer to anything.) If a reference is explicitly made
247 ** to an object in a different database, an error message is added to
248 ** pParse->zErrMsg and these routines return non-zero. If everything
249 ** checks out, these routines return 0.
251 int sqlite3FixSrcList(
252 DbFixer *pFix, /* Context of the fixation */
253 SrcList *pList /* The Source list to check and modify */
255 int i;
256 const char *zDb;
257 struct SrcList_item *pItem;
259 if( pList==0 ) return 0;
260 zDb = pFix->zDb;
261 for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
262 if( pItem->zDatabase==0 ){
263 pItem->zDatabase = sqliteStrDup(zDb);
264 }else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){
265 sqlite3ErrorMsg(pFix->pParse,
266 "%s %T cannot reference objects in database %s",
267 pFix->zType, pFix->pName, pItem->zDatabase);
268 return 1;
270 #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
271 if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
272 if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
273 #endif
275 return 0;
277 #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
278 int sqlite3FixSelect(
279 DbFixer *pFix, /* Context of the fixation */
280 Select *pSelect /* The SELECT statement to be fixed to one database */
282 while( pSelect ){
283 if( sqlite3FixExprList(pFix, pSelect->pEList) ){
284 return 1;
286 if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){
287 return 1;
289 if( sqlite3FixExpr(pFix, pSelect->pWhere) ){
290 return 1;
292 if( sqlite3FixExpr(pFix, pSelect->pHaving) ){
293 return 1;
295 pSelect = pSelect->pPrior;
297 return 0;
299 int sqlite3FixExpr(
300 DbFixer *pFix, /* Context of the fixation */
301 Expr *pExpr /* The expression to be fixed to one database */
303 while( pExpr ){
304 if( sqlite3FixSelect(pFix, pExpr->pSelect) ){
305 return 1;
307 if( sqlite3FixExprList(pFix, pExpr->pList) ){
308 return 1;
310 if( sqlite3FixExpr(pFix, pExpr->pRight) ){
311 return 1;
313 pExpr = pExpr->pLeft;
315 return 0;
317 int sqlite3FixExprList(
318 DbFixer *pFix, /* Context of the fixation */
319 ExprList *pList /* The expression to be fixed to one database */
321 int i;
322 struct ExprList_item *pItem;
323 if( pList==0 ) return 0;
324 for(i=0, pItem=pList->a; i<pList->nExpr; i++, pItem++){
325 if( sqlite3FixExpr(pFix, pItem->pExpr) ){
326 return 1;
329 return 0;
331 #endif
333 #ifndef SQLITE_OMIT_TRIGGER
334 int sqlite3FixTriggerStep(
335 DbFixer *pFix, /* Context of the fixation */
336 TriggerStep *pStep /* The trigger step be fixed to one database */
338 while( pStep ){
339 if( sqlite3FixSelect(pFix, pStep->pSelect) ){
340 return 1;
342 if( sqlite3FixExpr(pFix, pStep->pWhere) ){
343 return 1;
345 if( sqlite3FixExprList(pFix, pStep->pExprList) ){
346 return 1;
348 pStep = pStep->pNext;
350 return 0;
352 #endif