15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2003 April 6
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The author disclaims copyright to this source code.  In place of
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a legal notice, here is a blessing:
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you do good and not evil.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you find forgiveness for yourself and forgive others.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you share freely, never taking more than you give.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*************************************************************************
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This file contains code used to implement the ATTACH and DETACH commands.
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sqliteInt.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_ATTACH
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Resolve an expression that was part of an ATTACH or DETACH statement. This
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is slightly different from resolving a normal SQL expression, because simple
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** identifiers are treated as strings, not possible column names or aliases.
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** i.e. if the parser sees:
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     ATTACH DATABASE abc AS def
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** it treats the two expressions as literal strings 'abc' and 'def' instead of
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** looking for columns of the same name.
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This only applies to the root node of pExpr, so the statement:
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     ATTACH DATABASE abc||def AS 'db2'
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** will fail because neither abc or def can be resolved.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int resolveAttachExpr(NameContext *pName, Expr *pExpr)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc = SQLITE_OK;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pExpr ){
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( pExpr->op!=TK_ID ){
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rc = sqlite3ResolveExprNames(pName, pExpr);
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if( rc==SQLITE_OK && !sqlite3ExprIsConstant(pExpr) ){
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3ErrorMsg(pName->pParse, "invalid name: \"%s\"", pExpr->u.zToken);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return SQLITE_ERROR;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }else{
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pExpr->op = TK_STRING;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rc;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** An SQL user-function registered to do the work of an ATTACH statement. The
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** three arguments to the function come directly from an attach statement:
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     ATTACH DATABASE x AS y KEY z
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     SELECT sqlite_attach(x, y, z)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** third argument.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void attachFunc(
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_context *context,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int NotUsed,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_value **argv
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc = 0;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3 *db = sqlite3_context_db_handle(context);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zName;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zFile;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Db *aNew;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zErrDyn = 0;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UNUSED_PARAMETER(NotUsed);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zFile = (const char *)sqlite3_value_text(argv[0]);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zName = (const char *)sqlite3_value_text(argv[1]);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( zFile==0 ) zFile = "";
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( zName==0 ) zName = "";
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Check for the following errors:
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  **
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  **     * Too many attached databases,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  **     * Transaction currently open
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  **     * Specified database name already being used.
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d",
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      db->aLimit[SQLITE_LIMIT_ATTACHED]
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    );
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    goto attach_error;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( !db->autoCommit ){
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zErrDyn = sqlite3MPrintf(db, "cannot ATTACH database within transaction");
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    goto attach_error;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<db->nDb; i++){
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *z = db->aDb[i].zName;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert( z && zName );
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( sqlite3StrICmp(z, zName)==0 ){
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      goto attach_error;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Allocate the new entry in the db->aDb[] array and initialise the schema
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** hash tables.
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( db->aDb==db->aDbStatic ){
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    aNew = sqlite3DbMallocRaw(db, sizeof(db->aDb[0])*3 );
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( aNew==0 ) return;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else{
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( aNew==0 ) return;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  db->aDb = aNew;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  aNew = &db->aDb[db->nDb];
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(aNew, 0, sizeof(*aNew));
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Open the database file. If the btree is successfully opened, use
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** it to obtain the database schema. At this point the schema may
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** or may not be initialised.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3BtreeOpen(zFile, db, &aNew->pBt, 0,
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        db->openFlags | SQLITE_OPEN_MAIN_DB);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  db->nDb++;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc==SQLITE_CONSTRAINT ){
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = SQLITE_ERROR;
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    zErrDyn = sqlite3MPrintf(db, "database is already attached");
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }else if( rc==SQLITE_OK ){
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Pager *pPager;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( !aNew->pSchema ){
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rc = SQLITE_NOMEM;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      zErrDyn = sqlite3MPrintf(db,
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        "attached databases must use the same text encoding as main database");
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rc = SQLITE_ERROR;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pPager = sqlite3BtreePager(aNew->pBt);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3PagerLockingMode(pPager, db->dfltLockMode);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3BtreeSecureDelete(aNew->pBt,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) );
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  aNew->safety_level = 3;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  aNew->zName = sqlite3DbStrDup(db, zName);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc==SQLITE_OK && aNew->zName==0 ){
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = SQLITE_NOMEM;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_HAS_CODEC
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc==SQLITE_OK ){
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extern int sqlite3CodecAttach(sqlite3*, int, const void*, int);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nKey;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *zKey;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int t = sqlite3_value_type(argv[2]);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch( t ){
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SQLITE_INTEGER:
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SQLITE_FLOAT:
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        zErrDyn = sqlite3DbStrDup(db, "Invalid key value");
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rc = SQLITE_ERROR;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SQLITE_TEXT:
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SQLITE_BLOB:
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        nKey = sqlite3_value_bytes(argv[2]);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        zKey = (char *)sqlite3_value_blob(argv[2]);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case SQLITE_NULL:
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* No key specified.  Use the key from the main database */
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if( nKey>0 || sqlite3BtreeGetReserve(db->aDb[0].pBt)>0 ){
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* If the file was opened successfully, read the schema for the new database.
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** If this fails, or if opening the file failed, then close the file and
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** remove the entry from the db->aDb[] array. i.e. put everything back the way
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** we found it.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc==SQLITE_OK ){
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3BtreeEnterAll(db);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = sqlite3Init(db, &zErrDyn);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3BtreeLeaveAll(db);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc ){
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int iDb = db->nDb - 1;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert( iDb>=2 );
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( db->aDb[iDb].pBt ){
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3BtreeClose(db->aDb[iDb].pBt);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      db->aDb[iDb].pBt = 0;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      db->aDb[iDb].pSchema = 0;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3ResetInternalSchema(db, -1);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    db->nDb = iDb;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      db->mallocFailed = 1;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3DbFree(db, zErrDyn);
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      zErrDyn = sqlite3MPrintf(db, "out of memory");
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }else if( zErrDyn==0 ){
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    goto attach_error;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)attach_error:
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Return an error if we get here */
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( zErrDyn ){
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_result_error(context, zErrDyn, -1);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3DbFree(db, zErrDyn);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc ) sqlite3_result_error_code(context, rc);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** An SQL user-function registered to do the work of an DETACH statement. The
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** three arguments to the function come directly from a detach statement:
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     DETACH DATABASE x
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     SELECT sqlite_detach(x)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void detachFunc(
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_context *context,
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int NotUsed,
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_value **argv
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zName = (const char *)sqlite3_value_text(argv[0]);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3 *db = sqlite3_context_db_handle(context);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Db *pDb = 0;
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char zErr[128];
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UNUSED_PARAMETER(NotUsed);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( zName==0 ) zName = "";
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<db->nDb; i++){
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pDb = &db->aDb[i];
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( pDb->pBt==0 ) continue;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( sqlite3StrICmp(pDb->zName, zName)==0 ) break;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( i>=db->nDb ){
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    goto detach_error;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( i<2 ){
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    goto detach_error;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( !db->autoCommit ){
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_snprintf(sizeof(zErr), zErr,
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     "cannot DETACH database within transaction");
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    goto detach_error;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    goto detach_error;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3BtreeClose(pDb->pBt);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pDb->pBt = 0;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pDb->pSchema = 0;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3ResetInternalSchema(db, -1);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)detach_error:
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_result_error(context, zErr, -1);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This procedure generates VDBE code for a single invocation of either the
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** sqlite_detach() or sqlite_attach() SQL user functions.
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void codeAttach(
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Parse *pParse,       /* The parser context */
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int type,            /* Either SQLITE_ATTACH or SQLITE_DETACH */
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FuncDef const *pFunc,/* FuncDef wrapper for detachFunc() or attachFunc() */
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Expr *pAuthArg,      /* Expression to pass to authorization callback */
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Expr *pFilename,     /* Name of database file */
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Expr *pDbname,       /* Name of the database to use internally */
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Expr *pKey           /* Database key for encryption extension */
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NameContext sName;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Vdbe *v;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3* db = pParse->db;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int regArgs;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memset(&sName, 0, sizeof(NameContext));
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sName.pParse = pParse;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if(
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) ||
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ){
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pParse->nErr++;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    goto attach_end;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_AUTHORIZATION
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pAuthArg ){
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *zAuthArg;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( pAuthArg->op==TK_STRING ){
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      zAuthArg = pAuthArg->u.zToken;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }else{
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      zAuthArg = 0;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if(rc!=SQLITE_OK ){
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      goto attach_end;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_OMIT_AUTHORIZATION */
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  v = sqlite3GetVdbe(pParse);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  regArgs = sqlite3GetTempRange(pParse, 4);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3ExprCode(pParse, pFilename, regArgs);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3ExprCode(pParse, pDbname, regArgs+1);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3ExprCode(pParse, pKey, regArgs+2);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( v || db->mallocFailed );
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( v ){
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs+3-pFunc->nArg, regArgs+3);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert( pFunc->nArg==-1 || (pFunc->nArg&0xff)==pFunc->nArg );
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeChangeP5(v, (u8)(pFunc->nArg));
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeChangeP4(v, -1, (char *)pFunc, P4_FUNCDEF);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** statement only). For DETACH, set it to false (expire all existing
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ** statements).
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    */
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH));
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)attach_end:
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3ExprDelete(db, pFilename);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3ExprDelete(db, pDbname);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3ExprDelete(db, pKey);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Called by the parser to compile a DETACH statement.
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     DETACH pDbname
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3Detach(Parse *pParse, Expr *pDbname){
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const FuncDef detach_func = {
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    1,                /* nArg */
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SQLITE_UTF8,      /* iPrefEnc */
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0,                /* flags */
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0,                /* pUserData */
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0,                /* pNext */
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    detachFunc,       /* xFunc */
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0,                /* xStep */
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0,                /* xFinalize */
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "sqlite_detach",  /* zName */
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0,                /* pHash */
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0                 /* pDestructor */
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  codeAttach(pParse, SQLITE_DETACH, &detach_func, pDbname, 0, 0, pDbname);
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Called by the parser to compile an ATTACH statement.
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     ATTACH p AS pDbname KEY pKey
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const FuncDef attach_func = {
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    3,                /* nArg */
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SQLITE_UTF8,      /* iPrefEnc */
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0,                /* flags */
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0,                /* pUserData */
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0,                /* pNext */
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    attachFunc,       /* xFunc */
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0,                /* xStep */
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0,                /* xFinalize */
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "sqlite_attach",  /* zName */
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0,                /* pHash */
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    0                 /* pDestructor */
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  codeAttach(pParse, SQLITE_ATTACH, &attach_func, p, p, pDbname, pKey);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* SQLITE_OMIT_ATTACH */
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Initialize a DbFixer structure.  This routine must be called prior
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** to passing the structure to one of the sqliteFixAAAA() routines below.
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The return value indicates whether or not fixation is required.  TRUE
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** means we do need to fix the database references, FALSE means we do not.
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3FixInit(
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DbFixer *pFix,      /* The fixer to be initialized */
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Parse *pParse,      /* Error messages will be written here */
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iDb,            /* This is the database that must be used */
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zType,  /* "view", "trigger", or "index" */
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const Token *pName  /* Name of the view, trigger, or index */
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3 *db;
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( NEVER(iDb<0) || iDb==1 ) return 0;
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  db = pParse->db;
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert( db->nDb>iDb );
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pFix->pParse = pParse;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pFix->zDb = db->aDb[iDb].zName;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pFix->zType = zType;
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pFix->pName = pName;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 1;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The following set of routines walk through the parse tree and assign
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a specific database to all table references where the database name
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** was left unspecified in the original SQL statement.  The pFix structure
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** must have been initialized by a prior call to sqlite3FixInit().
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** These routines are used to make sure that an index, trigger, or
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** view in one database does not refer to objects in a different database.
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** (Exception: indices, triggers, and views in the TEMP database are
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** allowed to refer to anything.)  If a reference is explicitly made
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** to an object in a different database, an error message is added to
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** pParse->zErrMsg and these routines return non-zero.  If everything
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** checks out, these routines return 0.
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3FixSrcList(
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DbFixer *pFix,       /* Context of the fixation */
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SrcList *pList       /* The Source list to check and modify */
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zDb;
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct SrcList_item *pItem;
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( NEVER(pList==0) ) return 0;
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  zDb = pFix->zDb;
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( pItem->zDatabase==0 ){
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pItem->zDatabase = sqlite3DbStrDup(pFix->pParse->db, zDb);
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sqlite3ErrorMsg(pFix->pParse,
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         "%s %T cannot reference objects in database %s",
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         pFix->zType, pFix->pName, pItem->zDatabase);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 1;
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1;
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1;
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3FixSelect(
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DbFixer *pFix,       /* Context of the fixation */
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Select *pSelect      /* The SELECT statement to be fixed to one database */
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while( pSelect ){
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( sqlite3FixExprList(pFix, pSelect->pEList) ){
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 1;
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 1;
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( sqlite3FixExpr(pFix, pSelect->pWhere) ){
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 1;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( sqlite3FixExpr(pFix, pSelect->pHaving) ){
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 1;
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pSelect = pSelect->pPrior;
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3FixExpr(
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DbFixer *pFix,     /* Context of the fixation */
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Expr *pExpr        /* The expression to be fixed to one database */
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while( pExpr ){
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ) break;
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( ExprHasProperty(pExpr, EP_xIsSelect) ){
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1;
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }else{
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( sqlite3FixExpr(pFix, pExpr->pRight) ){
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 1;
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pExpr = pExpr->pLeft;
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3FixExprList(
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DbFixer *pFix,     /* Context of the fixation */
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExprList *pList    /* The expression to be fixed to one database */
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct ExprList_item *pItem;
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pList==0 ) return 0;
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0, pItem=pList->a; i<pList->nExpr; i++, pItem++){
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( sqlite3FixExpr(pFix, pItem->pExpr) ){
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 1;
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_TRIGGER
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3FixTriggerStep(
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DbFixer *pFix,     /* Context of the fixation */
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TriggerStep *pStep /* The trigger step be fixed to one database */
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while( pStep ){
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( sqlite3FixSelect(pFix, pStep->pSelect) ){
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 1;
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( sqlite3FixExpr(pFix, pStep->pWhere) ){
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 1;
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( sqlite3FixExprList(pFix, pStep->pExprList) ){
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return 1;
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pStep = pStep->pNext;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
544