| Index: third_party/sqlite/src/src/attach.c | 
| diff --git a/third_party/sqlite/src/src/attach.c b/third_party/sqlite/src/src/attach.c | 
| index bda1c874454e437c37bdb43f83ec3e4228074287..cf52bb24b126f84efde80f77f51c8fcaeaa992b7 100644 | 
| --- a/third_party/sqlite/src/src/attach.c | 
| +++ b/third_party/sqlite/src/src/attach.c | 
| @@ -38,10 +38,6 @@ static int resolveAttachExpr(NameContext *pName, Expr *pExpr) | 
| if( pExpr ){ | 
| if( pExpr->op!=TK_ID ){ | 
| rc = sqlite3ResolveExprNames(pName, pExpr); | 
| -      if( rc==SQLITE_OK && !sqlite3ExprIsConstant(pExpr) ){ | 
| -        sqlite3ErrorMsg(pName->pParse, "invalid name: \"%s\"", pExpr->u.zToken); | 
| -        return SQLITE_ERROR; | 
| -      } | 
| }else{ | 
| pExpr->op = TK_STRING; | 
| } | 
| @@ -70,8 +66,12 @@ static void attachFunc( | 
| sqlite3 *db = sqlite3_context_db_handle(context); | 
| const char *zName; | 
| const char *zFile; | 
| +  char *zPath = 0; | 
| +  char *zErr = 0; | 
| +  unsigned int flags; | 
| Db *aNew; | 
| char *zErrDyn = 0; | 
| +  sqlite3_vfs *pVfs; | 
|  | 
| UNUSED_PARAMETER(NotUsed); | 
|  | 
| @@ -105,7 +105,7 @@ static void attachFunc( | 
| } | 
| } | 
|  | 
| -  /* Allocate the new entry in the db->aDb[] array and initialise the schema | 
| +  /* Allocate the new entry in the db->aDb[] array and initialize the schema | 
| ** hash tables. | 
| */ | 
| if( db->aDb==db->aDbStatic ){ | 
| @@ -122,10 +122,20 @@ static void attachFunc( | 
|  | 
| /* Open the database file. If the btree is successfully opened, use | 
| ** it to obtain the database schema. At this point the schema may | 
| -  ** or may not be initialised. | 
| +  ** or may not be initialized. | 
| */ | 
| -  rc = sqlite3BtreeOpen(zFile, db, &aNew->pBt, 0, | 
| -                        db->openFlags | SQLITE_OPEN_MAIN_DB); | 
| +  flags = db->openFlags; | 
| +  rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr); | 
| +  if( rc!=SQLITE_OK ){ | 
| +    if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; | 
| +    sqlite3_result_error(context, zErr, -1); | 
| +    sqlite3_free(zErr); | 
| +    return; | 
| +  } | 
| +  assert( pVfs ); | 
| +  flags |= SQLITE_OPEN_MAIN_DB; | 
| +  rc = sqlite3BtreeOpen(pVfs, zPath, db, &aNew->pBt, 0, flags); | 
| +  sqlite3_free( zPath ); | 
| db->nDb++; | 
| if( rc==SQLITE_CONSTRAINT ){ | 
| rc = SQLITE_ERROR; | 
| @@ -144,6 +154,9 @@ static void attachFunc( | 
| sqlite3PagerLockingMode(pPager, db->dfltLockMode); | 
| sqlite3BtreeSecureDelete(aNew->pBt, | 
| sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); | 
| +#ifndef SQLITE_OMIT_PAGER_PRAGMAS | 
| +    sqlite3BtreeSetPagerFlags(aNew->pBt, 3 | (db->flags & PAGER_FLAGS_MASK)); | 
| +#endif | 
| } | 
| aNew->safety_level = 3; | 
| aNew->zName = sqlite3DbStrDup(db, zName); | 
| @@ -194,6 +207,15 @@ static void attachFunc( | 
| rc = sqlite3Init(db, &zErrDyn); | 
| sqlite3BtreeLeaveAll(db); | 
| } | 
| +#ifdef SQLITE_USER_AUTHENTICATION | 
| +  if( rc==SQLITE_OK ){ | 
| +    u8 newAuth = 0; | 
| +    rc = sqlite3UserAuthCheckLogin(db, zName, &newAuth); | 
| +    if( newAuth<db->auth.authLevel ){ | 
| +      rc = SQLITE_AUTH_USER; | 
| +    } | 
| +  } | 
| +#endif | 
| if( rc ){ | 
| int iDb = db->nDb - 1; | 
| assert( iDb>=2 ); | 
| @@ -202,7 +224,7 @@ static void attachFunc( | 
| db->aDb[iDb].pBt = 0; | 
| db->aDb[iDb].pSchema = 0; | 
| } | 
| -    sqlite3ResetInternalSchema(db, -1); | 
| +    sqlite3ResetAllSchemasOfConnection(db); | 
| db->nDb = iDb; | 
| if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ | 
| db->mallocFailed = 1; | 
| @@ -274,7 +296,7 @@ static void detachFunc( | 
| sqlite3BtreeClose(pDb->pBt); | 
| pDb->pBt = 0; | 
| pDb->pSchema = 0; | 
| -  sqlite3ResetInternalSchema(db, -1); | 
| +  sqlite3ResetAllSchemasOfConnection(db); | 
| return; | 
|  | 
| detach_error: | 
| @@ -362,8 +384,7 @@ attach_end: | 
| void sqlite3Detach(Parse *pParse, Expr *pDbname){ | 
| static const FuncDef detach_func = { | 
| 1,                /* nArg */ | 
| -    SQLITE_UTF8,      /* iPrefEnc */ | 
| -    0,                /* flags */ | 
| +    SQLITE_UTF8,      /* funcFlags */ | 
| 0,                /* pUserData */ | 
| 0,                /* pNext */ | 
| detachFunc,       /* xFunc */ | 
| @@ -384,8 +405,7 @@ void sqlite3Detach(Parse *pParse, Expr *pDbname){ | 
| void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){ | 
| static const FuncDef attach_func = { | 
| 3,                /* nArg */ | 
| -    SQLITE_UTF8,      /* iPrefEnc */ | 
| -    0,                /* flags */ | 
| +    SQLITE_UTF8,      /* funcFlags */ | 
| 0,                /* pUserData */ | 
| 0,                /* pNext */ | 
| attachFunc,       /* xFunc */ | 
| @@ -402,11 +422,8 @@ void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){ | 
| /* | 
| ** Initialize a DbFixer structure.  This routine must be called prior | 
| ** to passing the structure to one of the sqliteFixAAAA() routines below. | 
| -** | 
| -** The return value indicates whether or not fixation is required.  TRUE | 
| -** means we do need to fix the database references, FALSE means we do not. | 
| */ | 
| -int sqlite3FixInit( | 
| +void sqlite3FixInit( | 
| DbFixer *pFix,      /* The fixer to be initialized */ | 
| Parse *pParse,      /* Error messages will be written here */ | 
| int iDb,            /* This is the database that must be used */ | 
| @@ -415,14 +432,14 @@ int sqlite3FixInit( | 
| ){ | 
| sqlite3 *db; | 
|  | 
| -  if( NEVER(iDb<0) || iDb==1 ) return 0; | 
| db = pParse->db; | 
| assert( db->nDb>iDb ); | 
| pFix->pParse = pParse; | 
| pFix->zDb = db->aDb[iDb].zName; | 
| +  pFix->pSchema = db->aDb[iDb].pSchema; | 
| pFix->zType = zType; | 
| pFix->pName = pName; | 
| -  return 1; | 
| +  pFix->bVarOnly = (iDb==1); | 
| } | 
|  | 
| /* | 
| @@ -450,13 +467,16 @@ int sqlite3FixSrcList( | 
| if( NEVER(pList==0) ) return 0; | 
| zDb = pFix->zDb; | 
| for(i=0, pItem=pList->a; i<pList->nSrc; i++, pItem++){ | 
| -    if( pItem->zDatabase==0 ){ | 
| -      pItem->zDatabase = sqlite3DbStrDup(pFix->pParse->db, zDb); | 
| -    }else if( sqlite3StrICmp(pItem->zDatabase,zDb)!=0 ){ | 
| -      sqlite3ErrorMsg(pFix->pParse, | 
| -         "%s %T cannot reference objects in database %s", | 
| -         pFix->zType, pFix->pName, pItem->zDatabase); | 
| -      return 1; | 
| +    if( pFix->bVarOnly==0 ){ | 
| +      if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){ | 
| +        sqlite3ErrorMsg(pFix->pParse, | 
| +            "%s %T cannot reference objects in database %s", | 
| +            pFix->zType, pFix->pName, pItem->zDatabase); | 
| +        return 1; | 
| +      } | 
| +      sqlite3DbFree(pFix->pParse->db, pItem->zDatabase); | 
| +      pItem->zDatabase = 0; | 
| +      pItem->pSchema = pFix->pSchema; | 
| } | 
| #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) | 
| if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; | 
| @@ -480,9 +500,21 @@ int sqlite3FixSelect( | 
| if( sqlite3FixExpr(pFix, pSelect->pWhere) ){ | 
| return 1; | 
| } | 
| +    if( sqlite3FixExprList(pFix, pSelect->pGroupBy) ){ | 
| +      return 1; | 
| +    } | 
| if( sqlite3FixExpr(pFix, pSelect->pHaving) ){ | 
| return 1; | 
| } | 
| +    if( sqlite3FixExprList(pFix, pSelect->pOrderBy) ){ | 
| +      return 1; | 
| +    } | 
| +    if( sqlite3FixExpr(pFix, pSelect->pLimit) ){ | 
| +      return 1; | 
| +    } | 
| +    if( sqlite3FixExpr(pFix, pSelect->pOffset) ){ | 
| +      return 1; | 
| +    } | 
| pSelect = pSelect->pPrior; | 
| } | 
| return 0; | 
| @@ -492,7 +524,15 @@ int sqlite3FixExpr( | 
| Expr *pExpr        /* The expression to be fixed to one database */ | 
| ){ | 
| while( pExpr ){ | 
| -    if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ) break; | 
| +    if( pExpr->op==TK_VARIABLE ){ | 
| +      if( pFix->pParse->db->init.busy ){ | 
| +        pExpr->op = TK_NULL; | 
| +      }else{ | 
| +        sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); | 
| +        return 1; | 
| +      } | 
| +    } | 
| +    if( ExprHasProperty(pExpr, EP_TokenOnly) ) break; | 
| if( ExprHasProperty(pExpr, EP_xIsSelect) ){ | 
| if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1; | 
| }else{ | 
|  |