1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/extensions/sqlite/sqlite-source/attach.c Sun Mar 30 07:00:22 2008 +0000
1.3 @@ -0,0 +1,521 @@
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 *zErrDyn = 0;
1.80 + char zErr[128];
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,
1.109 + "database %s is already in use", zName);
1.110 + goto attach_error;
1.111 + }
1.112 + }
1.113 +
1.114 + /* Allocate the new entry in the db->aDb[] array and initialise the schema
1.115 + ** hash tables.
1.116 + */
1.117 + if( db->aDb==db->aDbStatic ){
1.118 + aNew = sqlite3_malloc( sizeof(db->aDb[0])*3 );
1.119 + if( aNew==0 ){
1.120 + db->mallocFailed = 1;
1.121 + return;
1.122 + }
1.123 + memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
1.124 + }else{
1.125 + aNew = sqlite3_realloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
1.126 + if( aNew==0 ){
1.127 + db->mallocFailed = 1;
1.128 + return;
1.129 + }
1.130 + }
1.131 + db->aDb = aNew;
1.132 + aNew = &db->aDb[db->nDb++];
1.133 + memset(aNew, 0, sizeof(*aNew));
1.134 +
1.135 + /* Open the database file. If the btree is successfully opened, use
1.136 + ** it to obtain the database schema. At this point the schema may
1.137 + ** or may not be initialised.
1.138 + */
1.139 + rc = sqlite3BtreeFactory(db, zFile, 0, SQLITE_DEFAULT_CACHE_SIZE,
1.140 + db->openFlags | SQLITE_OPEN_MAIN_DB,
1.141 + &aNew->pBt);
1.142 + if( rc==SQLITE_OK ){
1.143 + aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt);
1.144 + if( !aNew->pSchema ){
1.145 + rc = SQLITE_NOMEM;
1.146 + }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
1.147 + sqlite3_snprintf(sizeof(zErr), zErr,
1.148 + "attached databases must use the same text encoding as main database");
1.149 + goto attach_error;
1.150 + }
1.151 + sqlite3PagerLockingMode(sqlite3BtreePager(aNew->pBt), db->dfltLockMode);
1.152 + }
1.153 + aNew->zName = sqlite3DbStrDup(db, zName);
1.154 + aNew->safety_level = 3;
1.155 +
1.156 +#if SQLITE_HAS_CODEC
1.157 + {
1.158 + extern int sqlite3CodecAttach(sqlite3*, int, const void*, int);
1.159 + extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
1.160 + int nKey;
1.161 + char *zKey;
1.162 + int t = sqlite3_value_type(argv[2]);
1.163 + switch( t ){
1.164 + case SQLITE_INTEGER:
1.165 + case SQLITE_FLOAT:
1.166 + zErrDyn = sqlite3DbStrDup(db, "Invalid key value");
1.167 + rc = SQLITE_ERROR;
1.168 + break;
1.169 +
1.170 + case SQLITE_TEXT:
1.171 + case SQLITE_BLOB:
1.172 + nKey = sqlite3_value_bytes(argv[2]);
1.173 + zKey = (char *)sqlite3_value_blob(argv[2]);
1.174 + sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
1.175 + break;
1.176 +
1.177 + case SQLITE_NULL:
1.178 + /* No key specified. Use the key from the main database */
1.179 + sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
1.180 + sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
1.181 + break;
1.182 + }
1.183 + }
1.184 +#endif
1.185 +
1.186 + /* If the file was opened successfully, read the schema for the new database.
1.187 + ** If this fails, or if opening the file failed, then close the file and
1.188 + ** remove the entry from the db->aDb[] array. i.e. put everything back the way
1.189 + ** we found it.
1.190 + */
1.191 + if( rc==SQLITE_OK ){
1.192 + sqlite3SafetyOn(db);
1.193 + rc = sqlite3Init(db, &zErrDyn);
1.194 + sqlite3SafetyOff(db);
1.195 + }
1.196 + if( rc ){
1.197 + int iDb = db->nDb - 1;
1.198 + assert( iDb>=2 );
1.199 + if( db->aDb[iDb].pBt ){
1.200 + sqlite3BtreeClose(db->aDb[iDb].pBt);
1.201 + db->aDb[iDb].pBt = 0;
1.202 + db->aDb[iDb].pSchema = 0;
1.203 + }
1.204 + sqlite3ResetInternalSchema(db, 0);
1.205 + db->nDb = iDb;
1.206 + if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
1.207 + db->mallocFailed = 1;
1.208 + sqlite3_snprintf(sizeof(zErr),zErr, "out of memory");
1.209 + }else{
1.210 + sqlite3_snprintf(sizeof(zErr),zErr, "unable to open database: %s", zFile);
1.211 + }
1.212 + goto attach_error;
1.213 + }
1.214 +
1.215 + return;
1.216 +
1.217 +attach_error:
1.218 + /* Return an error if we get here */
1.219 + if( zErrDyn ){
1.220 + sqlite3_result_error(context, zErrDyn, -1);
1.221 + sqlite3_free(zErrDyn);
1.222 + }else{
1.223 + zErr[sizeof(zErr)-1] = 0;
1.224 + sqlite3_result_error(context, zErr, -1);
1.225 + }
1.226 +}
1.227 +
1.228 +/*
1.229 +** An SQL user-function registered to do the work of an DETACH statement. The
1.230 +** three arguments to the function come directly from a detach statement:
1.231 +**
1.232 +** DETACH DATABASE x
1.233 +**
1.234 +** SELECT sqlite_detach(x)
1.235 +*/
1.236 +static void detachFunc(
1.237 + sqlite3_context *context,
1.238 + int argc,
1.239 + sqlite3_value **argv
1.240 +){
1.241 + const char *zName = (const char *)sqlite3_value_text(argv[0]);
1.242 + sqlite3 *db = sqlite3_user_data(context);
1.243 + int i;
1.244 + Db *pDb = 0;
1.245 + char zErr[128];
1.246 +
1.247 + if( zName==0 ) zName = "";
1.248 + for(i=0; i<db->nDb; i++){
1.249 + pDb = &db->aDb[i];
1.250 + if( pDb->pBt==0 ) continue;
1.251 + if( sqlite3StrICmp(pDb->zName, zName)==0 ) break;
1.252 + }
1.253 +
1.254 + if( i>=db->nDb ){
1.255 + sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName);
1.256 + goto detach_error;
1.257 + }
1.258 + if( i<2 ){
1.259 + sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName);
1.260 + goto detach_error;
1.261 + }
1.262 + if( !db->autoCommit ){
1.263 + sqlite3_snprintf(sizeof(zErr), zErr,
1.264 + "cannot DETACH database within transaction");
1.265 + goto detach_error;
1.266 + }
1.267 + if( sqlite3BtreeIsInReadTrans(pDb->pBt) ){
1.268 + sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
1.269 + goto detach_error;
1.270 + }
1.271 +
1.272 + sqlite3BtreeClose(pDb->pBt);
1.273 + pDb->pBt = 0;
1.274 + pDb->pSchema = 0;
1.275 + sqlite3ResetInternalSchema(db, 0);
1.276 + return;
1.277 +
1.278 +detach_error:
1.279 + sqlite3_result_error(context, zErr, -1);
1.280 +}
1.281 +
1.282 +/*
1.283 +** This procedure generates VDBE code for a single invocation of either the
1.284 +** sqlite_detach() or sqlite_attach() SQL user functions.
1.285 +*/
1.286 +static void codeAttach(
1.287 + Parse *pParse, /* The parser context */
1.288 + int type, /* Either SQLITE_ATTACH or SQLITE_DETACH */
1.289 + const char *zFunc, /* Either "sqlite_attach" or "sqlite_detach */
1.290 + int nFunc, /* Number of args to pass to zFunc */
1.291 + Expr *pAuthArg, /* Expression to pass to authorization callback */
1.292 + Expr *pFilename, /* Name of database file */
1.293 + Expr *pDbname, /* Name of the database to use internally */
1.294 + Expr *pKey /* Database key for encryption extension */
1.295 +){
1.296 + int rc;
1.297 + NameContext sName;
1.298 + Vdbe *v;
1.299 + FuncDef *pFunc;
1.300 + sqlite3* db = pParse->db;
1.301 +
1.302 +#ifndef SQLITE_OMIT_AUTHORIZATION
1.303 + assert( db->mallocFailed || pAuthArg );
1.304 + if( pAuthArg ){
1.305 + char *zAuthArg = sqlite3NameFromToken(db, &pAuthArg->span);
1.306 + if( !zAuthArg ){
1.307 + goto attach_end;
1.308 + }
1.309 + rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0);
1.310 + sqlite3_free(zAuthArg);
1.311 + if(rc!=SQLITE_OK ){
1.312 + goto attach_end;
1.313 + }
1.314 + }
1.315 +#endif /* SQLITE_OMIT_AUTHORIZATION */
1.316 +
1.317 + memset(&sName, 0, sizeof(NameContext));
1.318 + sName.pParse = pParse;
1.319 +
1.320 + if(
1.321 + SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) ||
1.322 + SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
1.323 + SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
1.324 + ){
1.325 + pParse->nErr++;
1.326 + goto attach_end;
1.327 + }
1.328 +
1.329 + v = sqlite3GetVdbe(pParse);
1.330 + sqlite3ExprCode(pParse, pFilename);
1.331 + sqlite3ExprCode(pParse, pDbname);
1.332 + sqlite3ExprCode(pParse, pKey);
1.333 +
1.334 + assert( v || db->mallocFailed );
1.335 + if( v ){
1.336 + sqlite3VdbeAddOp(v, OP_Function, 0, nFunc);
1.337 + pFunc = sqlite3FindFunction(db, zFunc, strlen(zFunc), nFunc, SQLITE_UTF8,0);
1.338 + sqlite3VdbeChangeP3(v, -1, (char *)pFunc, P3_FUNCDEF);
1.339 +
1.340 + /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
1.341 + ** statement only). For DETACH, set it to false (expire all existing
1.342 + ** statements).
1.343 + */
1.344 + sqlite3VdbeAddOp(v, OP_Expire, (type==SQLITE_ATTACH), 0);
1.345 + }
1.346 +
1.347 +attach_end:
1.348 + sqlite3ExprDelete(pFilename);
1.349 + sqlite3ExprDelete(pDbname);
1.350 + sqlite3ExprDelete(pKey);
1.351 +}
1.352 +
1.353 +/*
1.354 +** Called by the parser to compile a DETACH statement.
1.355 +**
1.356 +** DETACH pDbname
1.357 +*/
1.358 +void sqlite3Detach(Parse *pParse, Expr *pDbname){
1.359 + codeAttach(pParse, SQLITE_DETACH, "sqlite_detach", 1, pDbname, 0, 0, pDbname);
1.360 +}
1.361 +
1.362 +/*
1.363 +** Called by the parser to compile an ATTACH statement.
1.364 +**
1.365 +** ATTACH p AS pDbname KEY pKey
1.366 +*/
1.367 +void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){
1.368 + codeAttach(pParse, SQLITE_ATTACH, "sqlite_attach", 3, p, p, pDbname, pKey);
1.369 +}
1.370 +#endif /* SQLITE_OMIT_ATTACH */
1.371 +
1.372 +/*
1.373 +** Register the functions sqlite_attach and sqlite_detach.
1.374 +*/
1.375 +void sqlite3AttachFunctions(sqlite3 *db){
1.376 +#ifndef SQLITE_OMIT_ATTACH
1.377 + static const int enc = SQLITE_UTF8;
1.378 + sqlite3CreateFunc(db, "sqlite_attach", 3, enc, db, attachFunc, 0, 0);
1.379 + sqlite3CreateFunc(db, "sqlite_detach", 1, enc, db, detachFunc, 0, 0);
1.380 +#endif
1.381 +}
1.382 +
1.383 +/*
1.384 +** Initialize a DbFixer structure. This routine must be called prior
1.385 +** to passing the structure to one of the sqliteFixAAAA() routines below.
1.386 +**
1.387 +** The return value indicates whether or not fixation is required. TRUE
1.388 +** means we do need to fix the database references, FALSE means we do not.
1.389 +*/
1.390 +int sqlite3FixInit(
1.391 + DbFixer *pFix, /* The fixer to be initialized */
1.392 + Parse *pParse, /* Error messages will be written here */
1.393 + int iDb, /* This is the database that must be used */
1.394 + const char *zType, /* "view", "trigger", or "index" */
1.395 + const Token *pName /* Name of the view, trigger, or index */
1.396 +){
1.397 + sqlite3 *db;
1.398 +
1.399 + if( iDb<0 || iDb==1 ) return 0;
1.400 + db = pParse->db;
1.401 + assert( db->nDb>iDb );
1.402 + pFix->pParse = pParse;
1.403 + pFix->zDb = db->aDb[iDb].zName;
1.404 + pFix->zType = zType;
1.405 + pFix->pName = pName;
1.406 + return 1;
1.407 +}
1.408 +
1.409 +/*
1.410 +** The following set of routines walk through the parse tree and assign
1.411 +** a specific database to all table references where the database name
1.412 +** was left unspecified in the original SQL statement. The pFix structure
1.413 +** must have been initialized by a prior call to sqlite3FixInit().
1.414 +**
1.415 +** These routines are used to make sure that an index, trigger, or
1.416 +** view in one database does not refer to objects in a different database.
1.417 +** (Exception: indices, triggers, and views in the TEMP database are
1.418 +** allowed to refer to anything.) If a reference is explicitly made
1.419 +** to an object in a different database, an error message is added to
1.420 +** pParse->zErrMsg and these routines return non-zero. If everything
1.421 +** checks out, these routines return 0.
1.422 +*/
1.423 +int sqlite3FixSrcList(
1.424 + DbFixer *pFix, /* Context of the fixation */
1.425 + SrcList *pList /* The Source list to check and modify */
1.426 +){
1.427 + int i;
1.428 + const char *zDb;
1.429 + struct SrcList_item *pItem;
1.430 +
1.431 + if( pList==0 ) return 0;
1.432 + zDb = pFix->zDb;
1.433 + for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
1.434 + if( pItem->zDatabase==0 ){
1.435 + pItem->zDatabase = sqlite3DbStrDup(pFix->pParse->db, zDb);
1.436 + }else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){
1.437 + sqlite3ErrorMsg(pFix->pParse,
1.438 + "%s %T cannot reference objects in database %s",
1.439 + pFix->zType, pFix->pName, pItem->zDatabase);
1.440 + return 1;
1.441 + }
1.442 +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
1.443 + if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
1.444 + if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
1.445 +#endif
1.446 + }
1.447 + return 0;
1.448 +}
1.449 +#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
1.450 +int sqlite3FixSelect(
1.451 + DbFixer *pFix, /* Context of the fixation */
1.452 + Select *pSelect /* The SELECT statement to be fixed to one database */
1.453 +){
1.454 + while( pSelect ){
1.455 + if( sqlite3FixExprList(pFix, pSelect->pEList) ){
1.456 + return 1;
1.457 + }
1.458 + if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){
1.459 + return 1;
1.460 + }
1.461 + if( sqlite3FixExpr(pFix, pSelect->pWhere) ){
1.462 + return 1;
1.463 + }
1.464 + if( sqlite3FixExpr(pFix, pSelect->pHaving) ){
1.465 + return 1;
1.466 + }
1.467 + pSelect = pSelect->pPrior;
1.468 + }
1.469 + return 0;
1.470 +}
1.471 +int sqlite3FixExpr(
1.472 + DbFixer *pFix, /* Context of the fixation */
1.473 + Expr *pExpr /* The expression to be fixed to one database */
1.474 +){
1.475 + while( pExpr ){
1.476 + if( sqlite3FixSelect(pFix, pExpr->pSelect) ){
1.477 + return 1;
1.478 + }
1.479 + if( sqlite3FixExprList(pFix, pExpr->pList) ){
1.480 + return 1;
1.481 + }
1.482 + if( sqlite3FixExpr(pFix, pExpr->pRight) ){
1.483 + return 1;
1.484 + }
1.485 + pExpr = pExpr->pLeft;
1.486 + }
1.487 + return 0;
1.488 +}
1.489 +int sqlite3FixExprList(
1.490 + DbFixer *pFix, /* Context of the fixation */
1.491 + ExprList *pList /* The expression to be fixed to one database */
1.492 +){
1.493 + int i;
1.494 + struct ExprList_item *pItem;
1.495 + if( pList==0 ) return 0;
1.496 + for(i=0, pItem=pList->a; i<pList->nExpr; i++, pItem++){
1.497 + if( sqlite3FixExpr(pFix, pItem->pExpr) ){
1.498 + return 1;
1.499 + }
1.500 + }
1.501 + return 0;
1.502 +}
1.503 +#endif
1.504 +
1.505 +#ifndef SQLITE_OMIT_TRIGGER
1.506 +int sqlite3FixTriggerStep(
1.507 + DbFixer *pFix, /* Context of the fixation */
1.508 + TriggerStep *pStep /* The trigger step be fixed to one database */
1.509 +){
1.510 + while( pStep ){
1.511 + if( sqlite3FixSelect(pFix, pStep->pSelect) ){
1.512 + return 1;
1.513 + }
1.514 + if( sqlite3FixExpr(pFix, pStep->pWhere) ){
1.515 + return 1;
1.516 + }
1.517 + if( sqlite3FixExprList(pFix, pStep->pExprList) ){
1.518 + return 1;
1.519 + }
1.520 + pStep = pStep->pNext;
1.521 + }
1.522 + return 0;
1.523 +}
1.524 +#endif