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