1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/extensions/sqlite/sqlite-source/attach.c Sun Jul 29 01:15:31 2007 +0000
1.3 @@ -0,0 +1,516 @@
1.4 +/*
1.5 +** 2003 April 6
1.6 +**
1.7 +** The author disclaims copyright to this source code. In place of
1.8 +** a legal notice, here is a blessing:
1.9 +**
1.10 +** May you do good and not evil.
1.11 +** May you find forgiveness for yourself and forgive others.
1.12 +** May you share freely, never taking more than you give.
1.13 +**
1.14 +*************************************************************************
1.15 +** This file contains code used to implement the ATTACH and DETACH commands.
1.16 +**
1.17 +** $Id$
1.18 +*/
1.19 +#include "sqliteInt.h"
1.20 +
1.21 +#ifndef SQLITE_OMIT_ATTACH
1.22 +/*
1.23 +** Resolve an expression that was part of an ATTACH or DETACH statement. This
1.24 +** is slightly different from resolving a normal SQL expression, because simple
1.25 +** identifiers are treated as strings, not possible column names or aliases.
1.26 +**
1.27 +** i.e. if the parser sees:
1.28 +**
1.29 +** ATTACH DATABASE abc AS def
1.30 +**
1.31 +** it treats the two expressions as literal strings 'abc' and 'def' instead of
1.32 +** looking for columns of the same name.
1.33 +**
1.34 +** This only applies to the root node of pExpr, so the statement:
1.35 +**
1.36 +** ATTACH DATABASE abc||def AS 'db2'
1.37 +**
1.38 +** will fail because neither abc or def can be resolved.
1.39 +*/
1.40 +static int resolveAttachExpr(NameContext *pName, Expr *pExpr)
1.41 +{
1.42 + int rc = SQLITE_OK;
1.43 + if( pExpr ){
1.44 + if( pExpr->op!=TK_ID ){
1.45 + rc = sqlite3ExprResolveNames(pName, pExpr);
1.46 + if( rc==SQLITE_OK && !sqlite3ExprIsConstant(pExpr) ){
1.47 + sqlite3ErrorMsg(pName->pParse, "invalid name: \"%T\"", &pExpr->span);
1.48 + return SQLITE_ERROR;
1.49 + }
1.50 + }else{
1.51 + pExpr->op = TK_STRING;
1.52 + }
1.53 + }
1.54 + return rc;
1.55 +}
1.56 +
1.57 +/*
1.58 +** An SQL user-function registered to do the work of an ATTACH statement. The
1.59 +** three arguments to the function come directly from an attach statement:
1.60 +**
1.61 +** ATTACH DATABASE x AS y KEY z
1.62 +**
1.63 +** SELECT sqlite_attach(x, y, z)
1.64 +**
1.65 +** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the
1.66 +** third argument.
1.67 +*/
1.68 +static void attachFunc(
1.69 + sqlite3_context *context,
1.70 + int argc,
1.71 + sqlite3_value **argv
1.72 +){
1.73 + int i;
1.74 + int rc = 0;
1.75 + sqlite3 *db = sqlite3_user_data(context);
1.76 + const char *zName;
1.77 + const char *zFile;
1.78 + Db *aNew;
1.79 + char zErr[128];
1.80 + char *zErrDyn = 0;
1.81 +
1.82 + zFile = (const char *)sqlite3_value_text(argv[0]);
1.83 + zName = (const char *)sqlite3_value_text(argv[1]);
1.84 + if( zFile==0 ) zFile = "";
1.85 + if( zName==0 ) zName = "";
1.86 +
1.87 + /* Check for the following errors:
1.88 + **
1.89 + ** * Too many attached databases,
1.90 + ** * Transaction currently open
1.91 + ** * Specified database name already being used.
1.92 + */
1.93 + if( db->nDb>=SQLITE_MAX_ATTACHED+2 ){
1.94 + sqlite3_snprintf(
1.95 + sizeof(zErr), zErr, "too many attached databases - max %d",
1.96 + SQLITE_MAX_ATTACHED
1.97 + );
1.98 + goto attach_error;
1.99 + }
1.100 + if( !db->autoCommit ){
1.101 + sqlite3_snprintf(sizeof(zErr), zErr,
1.102 + "cannot ATTACH database within transaction");
1.103 + goto attach_error;
1.104 + }
1.105 + for(i=0; i<db->nDb; i++){
1.106 + char *z = db->aDb[i].zName;
1.107 + if( z && zName && sqlite3StrICmp(z, zName)==0 ){
1.108 + sqlite3_snprintf(sizeof(zErr), zErr, "database %s is already in use", zName);
1.109 + goto attach_error;
1.110 + }
1.111 + }
1.112 +
1.113 + /* Allocate the new entry in the db->aDb[] array and initialise the schema
1.114 + ** hash tables.
1.115 + */
1.116 + if( db->aDb==db->aDbStatic ){
1.117 + aNew = sqliteMalloc( sizeof(db->aDb[0])*3 );
1.118 + if( aNew==0 ){
1.119 + return;
1.120 + }
1.121 + memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
1.122 + }else{
1.123 + aNew = sqliteRealloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
1.124 + if( aNew==0 ){
1.125 + return;
1.126 + }
1.127 + }
1.128 + db->aDb = aNew;
1.129 + aNew = &db->aDb[db->nDb++];
1.130 + memset(aNew, 0, sizeof(*aNew));
1.131 +
1.132 + /* Open the database file. If the btree is successfully opened, use
1.133 + ** it to obtain the database schema. At this point the schema may
1.134 + ** or may not be initialised.
1.135 + */
1.136 + rc = sqlite3BtreeFactory(db, zFile, 0, SQLITE_DEFAULT_CACHE_SIZE, &aNew->pBt);
1.137 + if( rc==SQLITE_OK ){
1.138 + aNew->pSchema = sqlite3SchemaGet(aNew->pBt);
1.139 + if( !aNew->pSchema ){
1.140 + rc = SQLITE_NOMEM;
1.141 + }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
1.142 + sqlite3_snprintf(sizeof(zErr), zErr,
1.143 + "attached databases must use the same text encoding as main database");
1.144 + goto attach_error;
1.145 + }
1.146 + sqlite3PagerLockingMode(sqlite3BtreePager(aNew->pBt), db->dfltLockMode);
1.147 + }
1.148 + aNew->zName = sqliteStrDup(zName);
1.149 + aNew->safety_level = 3;
1.150 +
1.151 +#if SQLITE_HAS_CODEC
1.152 + {
1.153 + extern int sqlite3CodecAttach(sqlite3*, int, const void*, int);
1.154 + extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
1.155 + int nKey;
1.156 + char *zKey;
1.157 + int t = sqlite3_value_type(argv[2]);
1.158 + switch( t ){
1.159 + case SQLITE_INTEGER:
1.160 + case SQLITE_FLOAT:
1.161 + zErrDyn = sqliteStrDup("Invalid key value");
1.162 + rc = SQLITE_ERROR;
1.163 + break;
1.164 +
1.165 + case SQLITE_TEXT:
1.166 + case SQLITE_BLOB:
1.167 + nKey = sqlite3_value_bytes(argv[2]);
1.168 + zKey = (char *)sqlite3_value_blob(argv[2]);
1.169 + sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
1.170 + break;
1.171 +
1.172 + case SQLITE_NULL:
1.173 + /* No key specified. Use the key from the main database */
1.174 + sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
1.175 + sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
1.176 + break;
1.177 + }
1.178 + }
1.179 +#endif
1.180 +
1.181 + /* If the file was opened successfully, read the schema for the new database.
1.182 + ** If this fails, or if opening the file failed, then close the file and
1.183 + ** remove the entry from the db->aDb[] array. i.e. put everything back the way
1.184 + ** we found it.
1.185 + */
1.186 + if( rc==SQLITE_OK ){
1.187 + sqlite3SafetyOn(db);
1.188 + rc = sqlite3Init(db, &zErrDyn);
1.189 + sqlite3SafetyOff(db);
1.190 + }
1.191 + if( rc ){
1.192 + int iDb = db->nDb - 1;
1.193 + assert( iDb>=2 );
1.194 + if( db->aDb[iDb].pBt ){
1.195 + sqlite3BtreeClose(db->aDb[iDb].pBt);
1.196 + db->aDb[iDb].pBt = 0;
1.197 + db->aDb[iDb].pSchema = 0;
1.198 + }
1.199 + sqlite3ResetInternalSchema(db, 0);
1.200 + db->nDb = iDb;
1.201 + if( rc==SQLITE_NOMEM ){
1.202 + sqlite3FailedMalloc();
1.203 + sqlite3_snprintf(sizeof(zErr),zErr, "out of memory");
1.204 + }else{
1.205 + sqlite3_snprintf(sizeof(zErr),zErr, "unable to open database: %s", zFile);
1.206 + }
1.207 + goto attach_error;
1.208 + }
1.209 +
1.210 + return;
1.211 +
1.212 +attach_error:
1.213 + /* Return an error if we get here */
1.214 + if( zErrDyn ){
1.215 + sqlite3_result_error(context, zErrDyn, -1);
1.216 + sqliteFree(zErrDyn);
1.217 + }else{
1.218 + zErr[sizeof(zErr)-1] = 0;
1.219 + sqlite3_result_error(context, zErr, -1);
1.220 + }
1.221 +}
1.222 +
1.223 +/*
1.224 +** An SQL user-function registered to do the work of an DETACH statement. The
1.225 +** three arguments to the function come directly from a detach statement:
1.226 +**
1.227 +** DETACH DATABASE x
1.228 +**
1.229 +** SELECT sqlite_detach(x)
1.230 +*/
1.231 +static void detachFunc(
1.232 + sqlite3_context *context,
1.233 + int argc,
1.234 + sqlite3_value **argv
1.235 +){
1.236 + const char *zName = (const char *)sqlite3_value_text(argv[0]);
1.237 + sqlite3 *db = sqlite3_user_data(context);
1.238 + int i;
1.239 + Db *pDb = 0;
1.240 + char zErr[128];
1.241 +
1.242 + if( zName==0 ) zName = "";
1.243 + for(i=0; i<db->nDb; i++){
1.244 + pDb = &db->aDb[i];
1.245 + if( pDb->pBt==0 ) continue;
1.246 + if( sqlite3StrICmp(pDb->zName, zName)==0 ) break;
1.247 + }
1.248 +
1.249 + if( i>=db->nDb ){
1.250 + sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName);
1.251 + goto detach_error;
1.252 + }
1.253 + if( i<2 ){
1.254 + sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName);
1.255 + goto detach_error;
1.256 + }
1.257 + if( !db->autoCommit ){
1.258 + sqlite3_snprintf(sizeof(zErr), zErr,
1.259 + "cannot DETACH database within transaction");
1.260 + goto detach_error;
1.261 + }
1.262 + if( sqlite3BtreeIsInReadTrans(pDb->pBt) ){
1.263 + sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
1.264 + goto detach_error;
1.265 + }
1.266 +
1.267 + sqlite3BtreeClose(pDb->pBt);
1.268 + pDb->pBt = 0;
1.269 + pDb->pSchema = 0;
1.270 + sqlite3ResetInternalSchema(db, 0);
1.271 + return;
1.272 +
1.273 +detach_error:
1.274 + sqlite3_result_error(context, zErr, -1);
1.275 +}
1.276 +
1.277 +/*
1.278 +** This procedure generates VDBE code for a single invocation of either the
1.279 +** sqlite_detach() or sqlite_attach() SQL user functions.
1.280 +*/
1.281 +static void codeAttach(
1.282 + Parse *pParse, /* The parser context */
1.283 + int type, /* Either SQLITE_ATTACH or SQLITE_DETACH */
1.284 + const char *zFunc, /* Either "sqlite_attach" or "sqlite_detach */
1.285 + int nFunc, /* Number of args to pass to zFunc */
1.286 + Expr *pAuthArg, /* Expression to pass to authorization callback */
1.287 + Expr *pFilename, /* Name of database file */
1.288 + Expr *pDbname, /* Name of the database to use internally */
1.289 + Expr *pKey /* Database key for encryption extension */
1.290 +){
1.291 + int rc;
1.292 + NameContext sName;
1.293 + Vdbe *v;
1.294 + FuncDef *pFunc;
1.295 + sqlite3* db = pParse->db;
1.296 +
1.297 +#ifndef SQLITE_OMIT_AUTHORIZATION
1.298 + assert( sqlite3MallocFailed() || pAuthArg );
1.299 + if( pAuthArg ){
1.300 + char *zAuthArg = sqlite3NameFromToken(&pAuthArg->span);
1.301 + if( !zAuthArg ){
1.302 + goto attach_end;
1.303 + }
1.304 + rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0);
1.305 + sqliteFree(zAuthArg);
1.306 + if(rc!=SQLITE_OK ){
1.307 + goto attach_end;
1.308 + }
1.309 + }
1.310 +#endif /* SQLITE_OMIT_AUTHORIZATION */
1.311 +
1.312 + memset(&sName, 0, sizeof(NameContext));
1.313 + sName.pParse = pParse;
1.314 +
1.315 + if(
1.316 + SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) ||
1.317 + SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
1.318 + SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
1.319 + ){
1.320 + pParse->nErr++;
1.321 + goto attach_end;
1.322 + }
1.323 +
1.324 + v = sqlite3GetVdbe(pParse);
1.325 + sqlite3ExprCode(pParse, pFilename);
1.326 + sqlite3ExprCode(pParse, pDbname);
1.327 + sqlite3ExprCode(pParse, pKey);
1.328 +
1.329 + assert( v || sqlite3MallocFailed() );
1.330 + if( v ){
1.331 + sqlite3VdbeAddOp(v, OP_Function, 0, nFunc);
1.332 + pFunc = sqlite3FindFunction(db, zFunc, strlen(zFunc), nFunc, SQLITE_UTF8,0);
1.333 + sqlite3VdbeChangeP3(v, -1, (char *)pFunc, P3_FUNCDEF);
1.334 +
1.335 + /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
1.336 + ** statement only). For DETACH, set it to false (expire all existing
1.337 + ** statements).
1.338 + */
1.339 + sqlite3VdbeAddOp(v, OP_Expire, (type==SQLITE_ATTACH), 0);
1.340 + }
1.341 +
1.342 +attach_end:
1.343 + sqlite3ExprDelete(pFilename);
1.344 + sqlite3ExprDelete(pDbname);
1.345 + sqlite3ExprDelete(pKey);
1.346 +}
1.347 +
1.348 +/*
1.349 +** Called by the parser to compile a DETACH statement.
1.350 +**
1.351 +** DETACH pDbname
1.352 +*/
1.353 +void sqlite3Detach(Parse *pParse, Expr *pDbname){
1.354 + codeAttach(pParse, SQLITE_DETACH, "sqlite_detach", 1, pDbname, 0, 0, pDbname);
1.355 +}
1.356 +
1.357 +/*
1.358 +** Called by the parser to compile an ATTACH statement.
1.359 +**
1.360 +** ATTACH p AS pDbname KEY pKey
1.361 +*/
1.362 +void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){
1.363 + codeAttach(pParse, SQLITE_ATTACH, "sqlite_attach", 3, p, p, pDbname, pKey);
1.364 +}
1.365 +#endif /* SQLITE_OMIT_ATTACH */
1.366 +
1.367 +/*
1.368 +** Register the functions sqlite_attach and sqlite_detach.
1.369 +*/
1.370 +void sqlite3AttachFunctions(sqlite3 *db){
1.371 +#ifndef SQLITE_OMIT_ATTACH
1.372 + static const int enc = SQLITE_UTF8;
1.373 + sqlite3CreateFunc(db, "sqlite_attach", 3, enc, db, attachFunc, 0, 0);
1.374 + sqlite3CreateFunc(db, "sqlite_detach", 1, enc, db, detachFunc, 0, 0);
1.375 +#endif
1.376 +}
1.377 +
1.378 +/*
1.379 +** Initialize a DbFixer structure. This routine must be called prior
1.380 +** to passing the structure to one of the sqliteFixAAAA() routines below.
1.381 +**
1.382 +** The return value indicates whether or not fixation is required. TRUE
1.383 +** means we do need to fix the database references, FALSE means we do not.
1.384 +*/
1.385 +int sqlite3FixInit(
1.386 + DbFixer *pFix, /* The fixer to be initialized */
1.387 + Parse *pParse, /* Error messages will be written here */
1.388 + int iDb, /* This is the database that must be used */
1.389 + const char *zType, /* "view", "trigger", or "index" */
1.390 + const Token *pName /* Name of the view, trigger, or index */
1.391 +){
1.392 + sqlite3 *db;
1.393 +
1.394 + if( iDb<0 || iDb==1 ) return 0;
1.395 + db = pParse->db;
1.396 + assert( db->nDb>iDb );
1.397 + pFix->pParse = pParse;
1.398 + pFix->zDb = db->aDb[iDb].zName;
1.399 + pFix->zType = zType;
1.400 + pFix->pName = pName;
1.401 + return 1;
1.402 +}
1.403 +
1.404 +/*
1.405 +** The following set of routines walk through the parse tree and assign
1.406 +** a specific database to all table references where the database name
1.407 +** was left unspecified in the original SQL statement. The pFix structure
1.408 +** must have been initialized by a prior call to sqlite3FixInit().
1.409 +**
1.410 +** These routines are used to make sure that an index, trigger, or
1.411 +** view in one database does not refer to objects in a different database.
1.412 +** (Exception: indices, triggers, and views in the TEMP database are
1.413 +** allowed to refer to anything.) If a reference is explicitly made
1.414 +** to an object in a different database, an error message is added to
1.415 +** pParse->zErrMsg and these routines return non-zero. If everything
1.416 +** checks out, these routines return 0.
1.417 +*/
1.418 +int sqlite3FixSrcList(
1.419 + DbFixer *pFix, /* Context of the fixation */
1.420 + SrcList *pList /* The Source list to check and modify */
1.421 +){
1.422 + int i;
1.423 + const char *zDb;
1.424 + struct SrcList_item *pItem;
1.425 +
1.426 + if( pList==0 ) return 0;
1.427 + zDb = pFix->zDb;
1.428 + for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
1.429 + if( pItem->zDatabase==0 ){
1.430 + pItem->zDatabase = sqliteStrDup(zDb);
1.431 + }else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){
1.432 + sqlite3ErrorMsg(pFix->pParse,
1.433 + "%s %T cannot reference objects in database %s",
1.434 + pFix->zType, pFix->pName, pItem->zDatabase);
1.435 + return 1;
1.436 + }
1.437 +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
1.438 + if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
1.439 + if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
1.440 +#endif
1.441 + }
1.442 + return 0;
1.443 +}
1.444 +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
1.445 +int sqlite3FixSelect(
1.446 + DbFixer *pFix, /* Context of the fixation */
1.447 + Select *pSelect /* The SELECT statement to be fixed to one database */
1.448 +){
1.449 + while( pSelect ){
1.450 + if( sqlite3FixExprList(pFix, pSelect->pEList) ){
1.451 + return 1;
1.452 + }
1.453 + if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){
1.454 + return 1;
1.455 + }
1.456 + if( sqlite3FixExpr(pFix, pSelect->pWhere) ){
1.457 + return 1;
1.458 + }
1.459 + if( sqlite3FixExpr(pFix, pSelect->pHaving) ){
1.460 + return 1;
1.461 + }
1.462 + pSelect = pSelect->pPrior;
1.463 + }
1.464 + return 0;
1.465 +}
1.466 +int sqlite3FixExpr(
1.467 + DbFixer *pFix, /* Context of the fixation */
1.468 + Expr *pExpr /* The expression to be fixed to one database */
1.469 +){
1.470 + while( pExpr ){
1.471 + if( sqlite3FixSelect(pFix, pExpr->pSelect) ){
1.472 + return 1;
1.473 + }
1.474 + if( sqlite3FixExprList(pFix, pExpr->pList) ){
1.475 + return 1;
1.476 + }
1.477 + if( sqlite3FixExpr(pFix, pExpr->pRight) ){
1.478 + return 1;
1.479 + }
1.480 + pExpr = pExpr->pLeft;
1.481 + }
1.482 + return 0;
1.483 +}
1.484 +int sqlite3FixExprList(
1.485 + DbFixer *pFix, /* Context of the fixation */
1.486 + ExprList *pList /* The expression to be fixed to one database */
1.487 +){
1.488 + int i;
1.489 + struct ExprList_item *pItem;
1.490 + if( pList==0 ) return 0;
1.491 + for(i=0, pItem=pList->a; i<pList->nExpr; i++, pItem++){
1.492 + if( sqlite3FixExpr(pFix, pItem->pExpr) ){
1.493 + return 1;
1.494 + }
1.495 + }
1.496 + return 0;
1.497 +}
1.498 +#endif
1.499 +
1.500 +#ifndef SQLITE_OMIT_TRIGGER
1.501 +int sqlite3FixTriggerStep(
1.502 + DbFixer *pFix, /* Context of the fixation */
1.503 + TriggerStep *pStep /* The trigger step be fixed to one database */
1.504 +){
1.505 + while( pStep ){
1.506 + if( sqlite3FixSelect(pFix, pStep->pSelect) ){
1.507 + return 1;
1.508 + }
1.509 + if( sqlite3FixExpr(pFix, pStep->pWhere) ){
1.510 + return 1;
1.511 + }
1.512 + if( sqlite3FixExprList(pFix, pStep->pExprList) ){
1.513 + return 1;
1.514 + }
1.515 + pStep = pStep->pNext;
1.516 + }
1.517 + return 0;
1.518 +}
1.519 +#endif