extensions/sqlite/sqlite-source/attach.c
author Scott Ehlert <ds@alliedmods.net>
Sun Mar 30 07:00:22 2008 +0000 (2008-03-30)
changeset 1952 b7aa2b626807
permissions -rw-r--r--
Spring Cleaning, Part Ichi (1)
Various minor things done to project files
Updated sample extension project file and updated makefile to the new unified version (more changes likely on the way)
Updated regex project file and makefile
     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$
    15 */
    16 #include "sqliteInt.h"
    17 
    18 #ifndef SQLITE_OMIT_ATTACH
    19 /*
    20 ** Resolve an expression that was part of an ATTACH or DETACH statement. This
    21 ** is slightly different from resolving a normal SQL expression, because simple
    22 ** identifiers are treated as strings, not possible column names or aliases.
    23 **
    24 ** i.e. if the parser sees:
    25 **
    26 **     ATTACH DATABASE abc AS def
    27 **
    28 ** it treats the two expressions as literal strings 'abc' and 'def' instead of
    29 ** looking for columns of the same name.
    30 **
    31 ** This only applies to the root node of pExpr, so the statement:
    32 **
    33 **     ATTACH DATABASE abc||def AS 'db2'
    34 **
    35 ** will fail because neither abc or def can be resolved.
    36 */
    37 static int resolveAttachExpr(NameContext *pName, Expr *pExpr)
    38 {
    39   int rc = SQLITE_OK;
    40   if( pExpr ){
    41     if( pExpr->op!=TK_ID ){
    42       rc = sqlite3ExprResolveNames(pName, pExpr);
    43       if( rc==SQLITE_OK && !sqlite3ExprIsConstant(pExpr) ){
    44         sqlite3ErrorMsg(pName->pParse, "invalid name: \"%T\"", &pExpr->span);
    45         return SQLITE_ERROR;
    46       }
    47     }else{
    48       pExpr->op = TK_STRING;
    49     }
    50   }
    51   return rc;
    52 }
    53 
    54 /*
    55 ** An SQL user-function registered to do the work of an ATTACH statement. The
    56 ** three arguments to the function come directly from an attach statement:
    57 **
    58 **     ATTACH DATABASE x AS y KEY z
    59 **
    60 **     SELECT sqlite_attach(x, y, z)
    61 **
    62 ** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the
    63 ** third argument.
    64 */
    65 static void attachFunc(
    66   sqlite3_context *context,
    67   int argc,
    68   sqlite3_value **argv
    69 ){
    70   int i;
    71   int rc = 0;
    72   sqlite3 *db = sqlite3_user_data(context);
    73   const char *zName;
    74   const char *zFile;
    75   Db *aNew;
    76   char *zErrDyn = 0;
    77   char zErr[128];
    78 
    79   zFile = (const char *)sqlite3_value_text(argv[0]);
    80   zName = (const char *)sqlite3_value_text(argv[1]);
    81   if( zFile==0 ) zFile = "";
    82   if( zName==0 ) zName = "";
    83 
    84   /* Check for the following errors:
    85   **
    86   **     * Too many attached databases,
    87   **     * Transaction currently open
    88   **     * Specified database name already being used.
    89   */
    90   if( db->nDb>=SQLITE_MAX_ATTACHED+2 ){
    91     sqlite3_snprintf(
    92       sizeof(zErr), zErr, "too many attached databases - max %d", 
    93       SQLITE_MAX_ATTACHED
    94     );
    95     goto attach_error;
    96   }
    97   if( !db->autoCommit ){
    98     sqlite3_snprintf(sizeof(zErr), zErr,
    99                      "cannot ATTACH database within transaction");
   100     goto attach_error;
   101   }
   102   for(i=0; i<db->nDb; i++){
   103     char *z = db->aDb[i].zName;
   104     if( z && zName && sqlite3StrICmp(z, zName)==0 ){
   105       sqlite3_snprintf(sizeof(zErr), zErr, 
   106                        "database %s is already in use", zName);
   107       goto attach_error;
   108     }
   109   }
   110 
   111   /* Allocate the new entry in the db->aDb[] array and initialise the schema
   112   ** hash tables.
   113   */
   114   if( db->aDb==db->aDbStatic ){
   115     aNew = sqlite3_malloc( sizeof(db->aDb[0])*3 );
   116     if( aNew==0 ){
   117       db->mallocFailed = 1;
   118       return;
   119     }
   120     memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
   121   }else{
   122     aNew = sqlite3_realloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
   123     if( aNew==0 ){
   124       db->mallocFailed = 1;
   125       return;
   126     } 
   127   }
   128   db->aDb = aNew;
   129   aNew = &db->aDb[db->nDb++];
   130   memset(aNew, 0, sizeof(*aNew));
   131 
   132   /* Open the database file. If the btree is successfully opened, use
   133   ** it to obtain the database schema. At this point the schema may
   134   ** or may not be initialised.
   135   */
   136   rc = sqlite3BtreeFactory(db, zFile, 0, SQLITE_DEFAULT_CACHE_SIZE,
   137                            db->openFlags | SQLITE_OPEN_MAIN_DB,
   138                            &aNew->pBt);
   139   if( rc==SQLITE_OK ){
   140     aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt);
   141     if( !aNew->pSchema ){
   142       rc = SQLITE_NOMEM;
   143     }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
   144       sqlite3_snprintf(sizeof(zErr), zErr, 
   145         "attached databases must use the same text encoding as main database");
   146       goto attach_error;
   147     }
   148     sqlite3PagerLockingMode(sqlite3BtreePager(aNew->pBt), db->dfltLockMode);
   149   }
   150   aNew->zName = sqlite3DbStrDup(db, zName);
   151   aNew->safety_level = 3;
   152 
   153 #if SQLITE_HAS_CODEC
   154   {
   155     extern int sqlite3CodecAttach(sqlite3*, int, const void*, int);
   156     extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
   157     int nKey;
   158     char *zKey;
   159     int t = sqlite3_value_type(argv[2]);
   160     switch( t ){
   161       case SQLITE_INTEGER:
   162       case SQLITE_FLOAT:
   163         zErrDyn = sqlite3DbStrDup(db, "Invalid key value");
   164         rc = SQLITE_ERROR;
   165         break;
   166         
   167       case SQLITE_TEXT:
   168       case SQLITE_BLOB:
   169         nKey = sqlite3_value_bytes(argv[2]);
   170         zKey = (char *)sqlite3_value_blob(argv[2]);
   171         sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
   172         break;
   173 
   174       case SQLITE_NULL:
   175         /* No key specified.  Use the key from the main database */
   176         sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
   177         sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
   178         break;
   179     }
   180   }
   181 #endif
   182 
   183   /* If the file was opened successfully, read the schema for the new database.
   184   ** If this fails, or if opening the file failed, then close the file and 
   185   ** remove the entry from the db->aDb[] array. i.e. put everything back the way
   186   ** we found it.
   187   */
   188   if( rc==SQLITE_OK ){
   189     sqlite3SafetyOn(db);
   190     rc = sqlite3Init(db, &zErrDyn);
   191     sqlite3SafetyOff(db);
   192   }
   193   if( rc ){
   194     int iDb = db->nDb - 1;
   195     assert( iDb>=2 );
   196     if( db->aDb[iDb].pBt ){
   197       sqlite3BtreeClose(db->aDb[iDb].pBt);
   198       db->aDb[iDb].pBt = 0;
   199       db->aDb[iDb].pSchema = 0;
   200     }
   201     sqlite3ResetInternalSchema(db, 0);
   202     db->nDb = iDb;
   203     if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
   204       db->mallocFailed = 1;
   205       sqlite3_snprintf(sizeof(zErr),zErr, "out of memory");
   206     }else{
   207       sqlite3_snprintf(sizeof(zErr),zErr, "unable to open database: %s", zFile);
   208     }
   209     goto attach_error;
   210   }
   211   
   212   return;
   213 
   214 attach_error:
   215   /* Return an error if we get here */
   216   if( zErrDyn ){
   217     sqlite3_result_error(context, zErrDyn, -1);
   218     sqlite3_free(zErrDyn);
   219   }else{
   220     zErr[sizeof(zErr)-1] = 0;
   221     sqlite3_result_error(context, zErr, -1);
   222   }
   223 }
   224 
   225 /*
   226 ** An SQL user-function registered to do the work of an DETACH statement. The
   227 ** three arguments to the function come directly from a detach statement:
   228 **
   229 **     DETACH DATABASE x
   230 **
   231 **     SELECT sqlite_detach(x)
   232 */
   233 static void detachFunc(
   234   sqlite3_context *context,
   235   int argc,
   236   sqlite3_value **argv
   237 ){
   238   const char *zName = (const char *)sqlite3_value_text(argv[0]);
   239   sqlite3 *db = sqlite3_user_data(context);
   240   int i;
   241   Db *pDb = 0;
   242   char zErr[128];
   243 
   244   if( zName==0 ) zName = "";
   245   for(i=0; i<db->nDb; i++){
   246     pDb = &db->aDb[i];
   247     if( pDb->pBt==0 ) continue;
   248     if( sqlite3StrICmp(pDb->zName, zName)==0 ) break;
   249   }
   250 
   251   if( i>=db->nDb ){
   252     sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName);
   253     goto detach_error;
   254   }
   255   if( i<2 ){
   256     sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName);
   257     goto detach_error;
   258   }
   259   if( !db->autoCommit ){
   260     sqlite3_snprintf(sizeof(zErr), zErr,
   261                      "cannot DETACH database within transaction");
   262     goto detach_error;
   263   }
   264   if( sqlite3BtreeIsInReadTrans(pDb->pBt) ){
   265     sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
   266     goto detach_error;
   267   }
   268 
   269   sqlite3BtreeClose(pDb->pBt);
   270   pDb->pBt = 0;
   271   pDb->pSchema = 0;
   272   sqlite3ResetInternalSchema(db, 0);
   273   return;
   274 
   275 detach_error:
   276   sqlite3_result_error(context, zErr, -1);
   277 }
   278 
   279 /*
   280 ** This procedure generates VDBE code for a single invocation of either the
   281 ** sqlite_detach() or sqlite_attach() SQL user functions.
   282 */
   283 static void codeAttach(
   284   Parse *pParse,       /* The parser context */
   285   int type,            /* Either SQLITE_ATTACH or SQLITE_DETACH */
   286   const char *zFunc,   /* Either "sqlite_attach" or "sqlite_detach */
   287   int nFunc,           /* Number of args to pass to zFunc */
   288   Expr *pAuthArg,      /* Expression to pass to authorization callback */
   289   Expr *pFilename,     /* Name of database file */
   290   Expr *pDbname,       /* Name of the database to use internally */
   291   Expr *pKey           /* Database key for encryption extension */
   292 ){
   293   int rc;
   294   NameContext sName;
   295   Vdbe *v;
   296   FuncDef *pFunc;
   297   sqlite3* db = pParse->db;
   298 
   299 #ifndef SQLITE_OMIT_AUTHORIZATION
   300   assert( db->mallocFailed || pAuthArg );
   301   if( pAuthArg ){
   302     char *zAuthArg = sqlite3NameFromToken(db, &pAuthArg->span);
   303     if( !zAuthArg ){
   304       goto attach_end;
   305     }
   306     rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0);
   307     sqlite3_free(zAuthArg);
   308     if(rc!=SQLITE_OK ){
   309       goto attach_end;
   310     }
   311   }
   312 #endif /* SQLITE_OMIT_AUTHORIZATION */
   313 
   314   memset(&sName, 0, sizeof(NameContext));
   315   sName.pParse = pParse;
   316 
   317   if( 
   318       SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) ||
   319       SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
   320       SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
   321   ){
   322     pParse->nErr++;
   323     goto attach_end;
   324   }
   325 
   326   v = sqlite3GetVdbe(pParse);
   327   sqlite3ExprCode(pParse, pFilename);
   328   sqlite3ExprCode(pParse, pDbname);
   329   sqlite3ExprCode(pParse, pKey);
   330 
   331   assert( v || db->mallocFailed );
   332   if( v ){
   333     sqlite3VdbeAddOp(v, OP_Function, 0, nFunc);
   334     pFunc = sqlite3FindFunction(db, zFunc, strlen(zFunc), nFunc, SQLITE_UTF8,0);
   335     sqlite3VdbeChangeP3(v, -1, (char *)pFunc, P3_FUNCDEF);
   336 
   337     /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
   338     ** statement only). For DETACH, set it to false (expire all existing
   339     ** statements).
   340     */
   341     sqlite3VdbeAddOp(v, OP_Expire, (type==SQLITE_ATTACH), 0);
   342   }
   343   
   344 attach_end:
   345   sqlite3ExprDelete(pFilename);
   346   sqlite3ExprDelete(pDbname);
   347   sqlite3ExprDelete(pKey);
   348 }
   349 
   350 /*
   351 ** Called by the parser to compile a DETACH statement.
   352 **
   353 **     DETACH pDbname
   354 */
   355 void sqlite3Detach(Parse *pParse, Expr *pDbname){
   356   codeAttach(pParse, SQLITE_DETACH, "sqlite_detach", 1, pDbname, 0, 0, pDbname);
   357 }
   358 
   359 /*
   360 ** Called by the parser to compile an ATTACH statement.
   361 **
   362 **     ATTACH p AS pDbname KEY pKey
   363 */
   364 void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){
   365   codeAttach(pParse, SQLITE_ATTACH, "sqlite_attach", 3, p, p, pDbname, pKey);
   366 }
   367 #endif /* SQLITE_OMIT_ATTACH */
   368 
   369 /*
   370 ** Register the functions sqlite_attach and sqlite_detach.
   371 */
   372 void sqlite3AttachFunctions(sqlite3 *db){
   373 #ifndef SQLITE_OMIT_ATTACH
   374   static const int enc = SQLITE_UTF8;
   375   sqlite3CreateFunc(db, "sqlite_attach", 3, enc, db, attachFunc, 0, 0);
   376   sqlite3CreateFunc(db, "sqlite_detach", 1, enc, db, detachFunc, 0, 0);
   377 #endif
   378 }
   379 
   380 /*
   381 ** Initialize a DbFixer structure.  This routine must be called prior
   382 ** to passing the structure to one of the sqliteFixAAAA() routines below.
   383 **
   384 ** The return value indicates whether or not fixation is required.  TRUE
   385 ** means we do need to fix the database references, FALSE means we do not.
   386 */
   387 int sqlite3FixInit(
   388   DbFixer *pFix,      /* The fixer to be initialized */
   389   Parse *pParse,      /* Error messages will be written here */
   390   int iDb,            /* This is the database that must be used */
   391   const char *zType,  /* "view", "trigger", or "index" */
   392   const Token *pName  /* Name of the view, trigger, or index */
   393 ){
   394   sqlite3 *db;
   395 
   396   if( iDb<0 || iDb==1 ) return 0;
   397   db = pParse->db;
   398   assert( db->nDb>iDb );
   399   pFix->pParse = pParse;
   400   pFix->zDb = db->aDb[iDb].zName;
   401   pFix->zType = zType;
   402   pFix->pName = pName;
   403   return 1;
   404 }
   405 
   406 /*
   407 ** The following set of routines walk through the parse tree and assign
   408 ** a specific database to all table references where the database name
   409 ** was left unspecified in the original SQL statement.  The pFix structure
   410 ** must have been initialized by a prior call to sqlite3FixInit().
   411 **
   412 ** These routines are used to make sure that an index, trigger, or
   413 ** view in one database does not refer to objects in a different database.
   414 ** (Exception: indices, triggers, and views in the TEMP database are
   415 ** allowed to refer to anything.)  If a reference is explicitly made
   416 ** to an object in a different database, an error message is added to
   417 ** pParse->zErrMsg and these routines return non-zero.  If everything
   418 ** checks out, these routines return 0.
   419 */
   420 int sqlite3FixSrcList(
   421   DbFixer *pFix,       /* Context of the fixation */
   422   SrcList *pList       /* The Source list to check and modify */
   423 ){
   424   int i;
   425   const char *zDb;
   426   struct SrcList_item *pItem;
   427 
   428   if( pList==0 ) return 0;
   429   zDb = pFix->zDb;
   430   for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
   431     if( pItem->zDatabase==0 ){
   432       pItem->zDatabase = sqlite3DbStrDup(pFix->pParse->db, zDb);
   433     }else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){
   434       sqlite3ErrorMsg(pFix->pParse,
   435          "%s %T cannot reference objects in database %s",
   436          pFix->zType, pFix->pName, pItem->zDatabase);
   437       return 1;
   438     }
   439 #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
   440     if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
   441     if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
   442 #endif
   443   }
   444   return 0;
   445 }
   446 #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
   447 int sqlite3FixSelect(
   448   DbFixer *pFix,       /* Context of the fixation */
   449   Select *pSelect      /* The SELECT statement to be fixed to one database */
   450 ){
   451   while( pSelect ){
   452     if( sqlite3FixExprList(pFix, pSelect->pEList) ){
   453       return 1;
   454     }
   455     if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){
   456       return 1;
   457     }
   458     if( sqlite3FixExpr(pFix, pSelect->pWhere) ){
   459       return 1;
   460     }
   461     if( sqlite3FixExpr(pFix, pSelect->pHaving) ){
   462       return 1;
   463     }
   464     pSelect = pSelect->pPrior;
   465   }
   466   return 0;
   467 }
   468 int sqlite3FixExpr(
   469   DbFixer *pFix,     /* Context of the fixation */
   470   Expr *pExpr        /* The expression to be fixed to one database */
   471 ){
   472   while( pExpr ){
   473     if( sqlite3FixSelect(pFix, pExpr->pSelect) ){
   474       return 1;
   475     }
   476     if( sqlite3FixExprList(pFix, pExpr->pList) ){
   477       return 1;
   478     }
   479     if( sqlite3FixExpr(pFix, pExpr->pRight) ){
   480       return 1;
   481     }
   482     pExpr = pExpr->pLeft;
   483   }
   484   return 0;
   485 }
   486 int sqlite3FixExprList(
   487   DbFixer *pFix,     /* Context of the fixation */
   488   ExprList *pList    /* The expression to be fixed to one database */
   489 ){
   490   int i;
   491   struct ExprList_item *pItem;
   492   if( pList==0 ) return 0;
   493   for(i=0, pItem=pList->a; i<pList->nExpr; i++, pItem++){
   494     if( sqlite3FixExpr(pFix, pItem->pExpr) ){
   495       return 1;
   496     }
   497   }
   498   return 0;
   499 }
   500 #endif
   501 
   502 #ifndef SQLITE_OMIT_TRIGGER
   503 int sqlite3FixTriggerStep(
   504   DbFixer *pFix,     /* Context of the fixation */
   505   TriggerStep *pStep /* The trigger step be fixed to one database */
   506 ){
   507   while( pStep ){
   508     if( sqlite3FixSelect(pFix, pStep->pSelect) ){
   509       return 1;
   510     }
   511     if( sqlite3FixExpr(pFix, pStep->pWhere) ){
   512       return 1;
   513     }
   514     if( sqlite3FixExprList(pFix, pStep->pExprList) ){
   515       return 1;
   516     }
   517     pStep = pStep->pNext;
   518   }
   519   return 0;
   520 }
   521 #endif