| Index: third_party/sqlite/src/src/main.c | 
| diff --git a/third_party/sqlite/src/src/main.c b/third_party/sqlite/src/src/main.c | 
| index 696de1cbce7eef092799bebea82317a423589c09..d15ab9bba11209516be4110a6fd542906939c3bc 100644 | 
| --- a/third_party/sqlite/src/src/main.c | 
| +++ b/third_party/sqlite/src/src/main.c | 
| @@ -49,8 +49,8 @@ const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } | 
| */ | 
| int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; } | 
|  | 
| -/* IMPLEMENTATION-OF: R-54823-41343 The sqlite3_threadsafe() function returns | 
| -** zero if and only if SQLite was compiled mutexing code omitted due to | 
| +/* IMPLEMENTATION-OF: R-20790-14025 The sqlite3_threadsafe() function returns | 
| +** zero if and only if SQLite was compiled with mutexing code omitted due to | 
| ** the SQLITE_THREADSAFE compile-time option being set to 0. | 
| */ | 
| int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; } | 
| @@ -75,6 +75,15 @@ void (*sqlite3IoTrace)(const char*, ...) = 0; | 
| char *sqlite3_temp_directory = 0; | 
|  | 
| /* | 
| +** If the following global variable points to a string which is the | 
| +** name of a directory, then that directory will be used to store | 
| +** all database files specified with a relative pathname. | 
| +** | 
| +** See also the "PRAGMA data_store_directory" SQL command. | 
| +*/ | 
| +char *sqlite3_data_directory = 0; | 
| + | 
| +/* | 
| ** Initialize SQLite. | 
| ** | 
| ** This routine must be called to initialize the memory allocation, | 
| @@ -106,8 +115,11 @@ char *sqlite3_temp_directory = 0; | 
| **       without blocking. | 
| */ | 
| int sqlite3_initialize(void){ | 
| -  sqlite3_mutex *pMaster;                      /* The main static mutex */ | 
| +  MUTEX_LOGIC( sqlite3_mutex *pMaster; )       /* The main static mutex */ | 
| int rc;                                      /* Result code */ | 
| +#ifdef SQLITE_EXTRA_INIT | 
| +  int bRunExtraInit = 0;                       /* Extra initialization needed */ | 
| +#endif | 
|  | 
| #ifdef SQLITE_OMIT_WSD | 
| rc = sqlite3_wsd_init(4096, 24); | 
| @@ -140,7 +152,7 @@ int sqlite3_initialize(void){ | 
| ** malloc subsystem - this implies that the allocation of a static | 
| ** mutex must not require support from the malloc subsystem. | 
| */ | 
| -  pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); | 
| +  MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) | 
| sqlite3_mutex_enter(pMaster); | 
| sqlite3GlobalConfig.isMutexInit = 1; | 
| if( !sqlite3GlobalConfig.isMallocInit ){ | 
| @@ -198,6 +210,9 @@ int sqlite3_initialize(void){ | 
| sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, | 
| sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage); | 
| sqlite3GlobalConfig.isInit = 1; | 
| +#ifdef SQLITE_EXTRA_INIT | 
| +      bRunExtraInit = 1; | 
| +#endif | 
| } | 
| sqlite3GlobalConfig.inProgress = 0; | 
| } | 
| @@ -234,6 +249,16 @@ int sqlite3_initialize(void){ | 
| #endif | 
| #endif | 
|  | 
| +  /* Do extra initialization steps requested by the SQLITE_EXTRA_INIT | 
| +  ** compile-time option. | 
| +  */ | 
| +#ifdef SQLITE_EXTRA_INIT | 
| +  if( bRunExtraInit ){ | 
| +    int SQLITE_EXTRA_INIT(const char*); | 
| +    rc = SQLITE_EXTRA_INIT(0); | 
| +  } | 
| +#endif | 
| + | 
| return rc; | 
| } | 
|  | 
| @@ -247,6 +272,10 @@ int sqlite3_initialize(void){ | 
| */ | 
| int sqlite3_shutdown(void){ | 
| if( sqlite3GlobalConfig.isInit ){ | 
| +#ifdef SQLITE_EXTRA_SHUTDOWN | 
| +    void SQLITE_EXTRA_SHUTDOWN(void); | 
| +    SQLITE_EXTRA_SHUTDOWN(); | 
| +#endif | 
| sqlite3_os_end(); | 
| sqlite3_reset_auto_extension(); | 
| sqlite3GlobalConfig.isInit = 0; | 
| @@ -258,6 +287,18 @@ int sqlite3_shutdown(void){ | 
| if( sqlite3GlobalConfig.isMallocInit ){ | 
| sqlite3MallocEnd(); | 
| sqlite3GlobalConfig.isMallocInit = 0; | 
| + | 
| +#ifndef SQLITE_OMIT_SHUTDOWN_DIRECTORIES | 
| +    /* The heap subsystem has now been shutdown and these values are supposed | 
| +    ** to be NULL or point to memory that was obtained from sqlite3_malloc(), | 
| +    ** which would rely on that heap subsystem; therefore, make sure these | 
| +    ** values cannot refer to heap memory that was just invalidated when the | 
| +    ** heap subsystem was shutdown.  This is only done if the current call to | 
| +    ** this function resulted in the heap subsystem actually being shutdown. | 
| +    */ | 
| +    sqlite3_data_directory = 0; | 
| +    sqlite3_temp_directory = 0; | 
| +#endif | 
| } | 
| if( sqlite3GlobalConfig.isMutexInit ){ | 
| sqlite3MutexEnd(); | 
| @@ -355,16 +396,25 @@ int sqlite3_config(int op, ...){ | 
| } | 
|  | 
| case SQLITE_CONFIG_PCACHE: { | 
| -      /* Specify an alternative page cache implementation */ | 
| -      sqlite3GlobalConfig.pcache = *va_arg(ap, sqlite3_pcache_methods*); | 
| +      /* no-op */ | 
| break; | 
| } | 
| - | 
| case SQLITE_CONFIG_GETPCACHE: { | 
| -      if( sqlite3GlobalConfig.pcache.xInit==0 ){ | 
| +      /* now an error */ | 
| +      rc = SQLITE_ERROR; | 
| +      break; | 
| +    } | 
| + | 
| +    case SQLITE_CONFIG_PCACHE2: { | 
| +      /* Specify an alternative page cache implementation */ | 
| +      sqlite3GlobalConfig.pcache2 = *va_arg(ap, sqlite3_pcache_methods2*); | 
| +      break; | 
| +    } | 
| +    case SQLITE_CONFIG_GETPCACHE2: { | 
| +      if( sqlite3GlobalConfig.pcache2.xInit==0 ){ | 
| sqlite3PCacheSetDefault(); | 
| } | 
| -      *va_arg(ap, sqlite3_pcache_methods*) = sqlite3GlobalConfig.pcache; | 
| +      *va_arg(ap, sqlite3_pcache_methods2*) = sqlite3GlobalConfig.pcache2; | 
| break; | 
| } | 
|  | 
| @@ -391,8 +441,8 @@ int sqlite3_config(int op, ...){ | 
| memset(&sqlite3GlobalConfig.m, 0, sizeof(sqlite3GlobalConfig.m)); | 
| }else{ | 
| /* The heap pointer is not NULL, then install one of the | 
| -        ** mem5.c/mem3.c methods. If neither ENABLE_MEMSYS3 nor | 
| -        ** ENABLE_MEMSYS5 is defined, return an error. | 
| +        ** mem5.c/mem3.c methods.  The enclosing #if guarantees at | 
| +        ** least one of these methods is currently enabled. | 
| */ | 
| #ifdef SQLITE_ENABLE_MEMSYS3 | 
| sqlite3GlobalConfig.m = *sqlite3MemGetMemsys3(); | 
| @@ -411,7 +461,7 @@ int sqlite3_config(int op, ...){ | 
| break; | 
| } | 
|  | 
| -    /* Record a pointer to the logger funcction and its first argument. | 
| +    /* Record a pointer to the logger function and its first argument. | 
| ** The default is NULL.  Logging is disabled if the function pointer is | 
| ** NULL. | 
| */ | 
| @@ -426,6 +476,50 @@ int sqlite3_config(int op, ...){ | 
| break; | 
| } | 
|  | 
| +    /* EVIDENCE-OF: R-55548-33817 The compile-time setting for URI filenames | 
| +    ** can be changed at start-time using the | 
| +    ** sqlite3_config(SQLITE_CONFIG_URI,1) or | 
| +    ** sqlite3_config(SQLITE_CONFIG_URI,0) configuration calls. | 
| +    */ | 
| +    case SQLITE_CONFIG_URI: { | 
| +      sqlite3GlobalConfig.bOpenUri = va_arg(ap, int); | 
| +      break; | 
| +    } | 
| + | 
| +    case SQLITE_CONFIG_COVERING_INDEX_SCAN: { | 
| +      sqlite3GlobalConfig.bUseCis = va_arg(ap, int); | 
| +      break; | 
| +    } | 
| + | 
| +#ifdef SQLITE_ENABLE_SQLLOG | 
| +    case SQLITE_CONFIG_SQLLOG: { | 
| +      typedef void(*SQLLOGFUNC_t)(void*, sqlite3*, const char*, int); | 
| +      sqlite3GlobalConfig.xSqllog = va_arg(ap, SQLLOGFUNC_t); | 
| +      sqlite3GlobalConfig.pSqllogArg = va_arg(ap, void *); | 
| +      break; | 
| +    } | 
| +#endif | 
| + | 
| +    case SQLITE_CONFIG_MMAP_SIZE: { | 
| +      sqlite3_int64 szMmap = va_arg(ap, sqlite3_int64); | 
| +      sqlite3_int64 mxMmap = va_arg(ap, sqlite3_int64); | 
| +      if( mxMmap<0 || mxMmap>SQLITE_MAX_MMAP_SIZE ){ | 
| +        mxMmap = SQLITE_MAX_MMAP_SIZE; | 
| +      } | 
| +      sqlite3GlobalConfig.mxMmap = mxMmap; | 
| +      if( szMmap<0 ) szMmap = SQLITE_DEFAULT_MMAP_SIZE; | 
| +      if( szMmap>mxMmap) szMmap = mxMmap; | 
| +      sqlite3GlobalConfig.szMmap = szMmap; | 
| +      break; | 
| +    } | 
| + | 
| +#if SQLITE_OS_WIN && defined(SQLITE_WIN32_MALLOC) | 
| +    case SQLITE_CONFIG_WIN32_HEAPSIZE: { | 
| +      sqlite3GlobalConfig.nHeap = va_arg(ap, int); | 
| +      break; | 
| +    } | 
| +#endif | 
| + | 
| default: { | 
| rc = SQLITE_ERROR; | 
| break; | 
| @@ -458,21 +552,21 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ | 
| if( db->lookaside.bMalloced ){ | 
| sqlite3_free(db->lookaside.pStart); | 
| } | 
| -  /* The size of a lookaside slot needs to be larger than a pointer | 
| -  ** to be useful. | 
| +  /* The size of a lookaside slot after ROUNDDOWN8 needs to be larger | 
| +  ** than a pointer to be useful. | 
| */ | 
| +  sz = ROUNDDOWN8(sz);  /* IMP: R-33038-09382 */ | 
| if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0; | 
| if( cnt<0 ) cnt = 0; | 
| if( sz==0 || cnt==0 ){ | 
| sz = 0; | 
| pStart = 0; | 
| }else if( pBuf==0 ){ | 
| -    sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */ | 
| sqlite3BeginBenignMalloc(); | 
| pStart = sqlite3Malloc( sz*cnt );  /* IMP: R-61949-35727 */ | 
| sqlite3EndBenignMalloc(); | 
| +    if( pStart ) cnt = sqlite3MallocSize(pStart)/sz; | 
| }else{ | 
| -    sz = ROUNDDOWN8(sz); /* IMP: R-33038-09382 */ | 
| pStart = pBuf; | 
| } | 
| db->lookaside.pStart = pStart; | 
| @@ -492,7 +586,8 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ | 
| db->lookaside.bEnabled = 1; | 
| db->lookaside.bMalloced = pBuf==0 ?1:0; | 
| }else{ | 
| -    db->lookaside.pEnd = 0; | 
| +    db->lookaside.pStart = db; | 
| +    db->lookaside.pEnd = db; | 
| db->lookaside.bEnabled = 0; | 
| db->lookaside.bMalloced = 0; | 
| } | 
| @@ -507,6 +602,26 @@ sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){ | 
| } | 
|  | 
| /* | 
| +** Free up as much memory as we can from the given database | 
| +** connection. | 
| +*/ | 
| +int sqlite3_db_release_memory(sqlite3 *db){ | 
| +  int i; | 
| +  sqlite3_mutex_enter(db->mutex); | 
| +  sqlite3BtreeEnterAll(db); | 
| +  for(i=0; i<db->nDb; i++){ | 
| +    Btree *pBt = db->aDb[i].pBt; | 
| +    if( pBt ){ | 
| +      Pager *pPager = sqlite3BtreePager(pBt); | 
| +      sqlite3PagerShrink(pPager); | 
| +    } | 
| +  } | 
| +  sqlite3BtreeLeaveAll(db); | 
| +  sqlite3_mutex_leave(db->mutex); | 
| +  return SQLITE_OK; | 
| +} | 
| + | 
| +/* | 
| ** Configuration settings for an individual database connection | 
| */ | 
| int sqlite3_db_config(sqlite3 *db, int op, ...){ | 
| @@ -598,7 +713,7 @@ static int binCollFunc( | 
| /* | 
| ** Another built-in collating sequence: NOCASE. | 
| ** | 
| -** This collating sequence is intended to be used for "case independant | 
| +** This collating sequence is intended to be used for "case independent | 
| ** comparison". SQLite's knowledge of upper and lower case equivalents | 
| ** extends only to the 26 characters used in the English language. | 
| ** | 
| @@ -673,13 +788,52 @@ static void functionDestroy(sqlite3 *db, FuncDef *p){ | 
| } | 
|  | 
| /* | 
| -** Close an existing SQLite database | 
| +** Disconnect all sqlite3_vtab objects that belong to database connection | 
| +** db. This is called when db is being closed. | 
| */ | 
| -int sqlite3_close(sqlite3 *db){ | 
| -  HashElem *i;                    /* Hash table iterator */ | 
| +static void disconnectAllVtab(sqlite3 *db){ | 
| +#ifndef SQLITE_OMIT_VIRTUALTABLE | 
| +  int i; | 
| +  sqlite3BtreeEnterAll(db); | 
| +  for(i=0; i<db->nDb; i++){ | 
| +    Schema *pSchema = db->aDb[i].pSchema; | 
| +    if( db->aDb[i].pSchema ){ | 
| +      HashElem *p; | 
| +      for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){ | 
| +        Table *pTab = (Table *)sqliteHashData(p); | 
| +        if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab); | 
| +      } | 
| +    } | 
| +  } | 
| +  sqlite3VtabUnlockList(db); | 
| +  sqlite3BtreeLeaveAll(db); | 
| +#else | 
| +  UNUSED_PARAMETER(db); | 
| +#endif | 
| +} | 
| + | 
| +/* | 
| +** Return TRUE if database connection db has unfinalized prepared | 
| +** statements or unfinished sqlite3_backup objects. | 
| +*/ | 
| +static int connectionIsBusy(sqlite3 *db){ | 
| int j; | 
| +  assert( sqlite3_mutex_held(db->mutex) ); | 
| +  if( db->pVdbe ) return 1; | 
| +  for(j=0; j<db->nDb; j++){ | 
| +    Btree *pBt = db->aDb[j].pBt; | 
| +    if( pBt && sqlite3BtreeIsInBackup(pBt) ) return 1; | 
| +  } | 
| +  return 0; | 
| +} | 
|  | 
| +/* | 
| +** Close an existing SQLite database | 
| +*/ | 
| +static int sqlite3Close(sqlite3 *db, int forceZombie){ | 
| if( !db ){ | 
| +    /* EVIDENCE-OF: R-63257-11740 Calling sqlite3_close() or | 
| +    ** sqlite3_close_v2() with a NULL pointer argument is a harmless no-op. */ | 
| return SQLITE_OK; | 
| } | 
| if( !sqlite3SafetyCheckSickOrOk(db) ){ | 
| @@ -687,10 +841,10 @@ int sqlite3_close(sqlite3 *db){ | 
| } | 
| sqlite3_mutex_enter(db->mutex); | 
|  | 
| -  /* Force xDestroy calls on all virtual tables */ | 
| -  sqlite3ResetInternalSchema(db, -1); | 
| +  /* Force xDisconnect calls on all virtual tables */ | 
| +  disconnectAllVtab(db); | 
|  | 
| -  /* If a transaction is open, the ResetInternalSchema() call above | 
| +  /* If a transaction is open, the disconnectAllVtab() call above | 
| ** will not have called the xDisconnect() method on any virtual | 
| ** tables in the db->aVTrans[] array. The following sqlite3VtabRollback() | 
| ** call will do so. We need to do this before the check for active | 
| @@ -699,31 +853,93 @@ int sqlite3_close(sqlite3 *db){ | 
| */ | 
| sqlite3VtabRollback(db); | 
|  | 
| -  /* If there are any outstanding VMs, return SQLITE_BUSY. */ | 
| -  if( db->pVdbe ){ | 
| -    sqlite3Error(db, SQLITE_BUSY, | 
| -        "unable to close due to unfinalised statements"); | 
| +  /* Legacy behavior (sqlite3_close() behavior) is to return | 
| +  ** SQLITE_BUSY if the connection can not be closed immediately. | 
| +  */ | 
| +  if( !forceZombie && connectionIsBusy(db) ){ | 
| +    sqlite3ErrorWithMsg(db, SQLITE_BUSY, "unable to close due to unfinalized " | 
| +       "statements or unfinished backups"); | 
| sqlite3_mutex_leave(db->mutex); | 
| return SQLITE_BUSY; | 
| } | 
| -  assert( sqlite3SafetyCheckSickOrOk(db) ); | 
|  | 
| -  for(j=0; j<db->nDb; j++){ | 
| -    Btree *pBt = db->aDb[j].pBt; | 
| -    if( pBt && sqlite3BtreeIsInBackup(pBt) ){ | 
| -      sqlite3Error(db, SQLITE_BUSY, | 
| -          "unable to close due to unfinished backup operation"); | 
| -      sqlite3_mutex_leave(db->mutex); | 
| -      return SQLITE_BUSY; | 
| -    } | 
| +#ifdef SQLITE_ENABLE_SQLLOG | 
| +  if( sqlite3GlobalConfig.xSqllog ){ | 
| +    /* Closing the handle. Fourth parameter is passed the value 2. */ | 
| +    sqlite3GlobalConfig.xSqllog(sqlite3GlobalConfig.pSqllogArg, db, 0, 2); | 
| +  } | 
| +#endif | 
| + | 
| +  /* Convert the connection into a zombie and then close it. | 
| +  */ | 
| +  db->magic = SQLITE_MAGIC_ZOMBIE; | 
| +  sqlite3LeaveMutexAndCloseZombie(db); | 
| +  return SQLITE_OK; | 
| +} | 
| + | 
| +/* | 
| +** Two variations on the public interface for closing a database | 
| +** connection. The sqlite3_close() version returns SQLITE_BUSY and | 
| +** leaves the connection option if there are unfinalized prepared | 
| +** statements or unfinished sqlite3_backups.  The sqlite3_close_v2() | 
| +** version forces the connection to become a zombie if there are | 
| +** unclosed resources, and arranges for deallocation when the last | 
| +** prepare statement or sqlite3_backup closes. | 
| +*/ | 
| +int sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); } | 
| +int sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); } | 
| + | 
| + | 
| +/* | 
| +** Close the mutex on database connection db. | 
| +** | 
| +** Furthermore, if database connection db is a zombie (meaning that there | 
| +** has been a prior call to sqlite3_close(db) or sqlite3_close_v2(db)) and | 
| +** every sqlite3_stmt has now been finalized and every sqlite3_backup has | 
| +** finished, then free all resources. | 
| +*/ | 
| +void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ | 
| +  HashElem *i;                    /* Hash table iterator */ | 
| +  int j; | 
| + | 
| +  /* If there are outstanding sqlite3_stmt or sqlite3_backup objects | 
| +  ** or if the connection has not yet been closed by sqlite3_close_v2(), | 
| +  ** then just leave the mutex and return. | 
| +  */ | 
| +  if( db->magic!=SQLITE_MAGIC_ZOMBIE || connectionIsBusy(db) ){ | 
| +    sqlite3_mutex_leave(db->mutex); | 
| +    return; | 
| } | 
|  | 
| +  /* If we reach this point, it means that the database connection has | 
| +  ** closed all sqlite3_stmt and sqlite3_backup objects and has been | 
| +  ** passed to sqlite3_close (meaning that it is a zombie).  Therefore, | 
| +  ** go ahead and free all resources. | 
| +  */ | 
| + | 
| +  /* If a transaction is open, roll it back. This also ensures that if | 
| +  ** any database schemas have been modified by an uncommitted transaction | 
| +  ** they are reset. And that the required b-tree mutex is held to make | 
| +  ** the pager rollback and schema reset an atomic operation. */ | 
| +  sqlite3RollbackAll(db, SQLITE_OK); | 
| + | 
| /* Free any outstanding Savepoint structures. */ | 
| sqlite3CloseSavepoints(db); | 
|  | 
| +  /* Close all database connections */ | 
| for(j=0; j<db->nDb; j++){ | 
| struct Db *pDb = &db->aDb[j]; | 
| if( pDb->pBt ){ | 
| +      if( pDb->pSchema ){ | 
| +        /* Must clear the KeyInfo cache.  See ticket [e4a18565a36884b00edf] */ | 
| +        sqlite3BtreeEnter(pDb->pBt); | 
| +        for(i=sqliteHashFirst(&pDb->pSchema->idxHash); i; i=sqliteHashNext(i)){ | 
| +          Index *pIdx = sqliteHashData(i); | 
| +          sqlite3KeyInfoUnref(pIdx->pKeyInfo); | 
| +          pIdx->pKeyInfo = 0; | 
| +        } | 
| +        sqlite3BtreeLeave(pDb->pBt); | 
| +      } | 
| sqlite3BtreeClose(pDb->pBt); | 
| pDb->pBt = 0; | 
| if( j!=1 ){ | 
| @@ -731,15 +947,22 @@ int sqlite3_close(sqlite3 *db){ | 
| } | 
| } | 
| } | 
| -  sqlite3ResetInternalSchema(db, -1); | 
| +  /* Clear the TEMP schema separately and last */ | 
| +  if( db->aDb[1].pSchema ){ | 
| +    sqlite3SchemaClear(db->aDb[1].pSchema); | 
| +  } | 
| +  sqlite3VtabUnlockList(db); | 
| + | 
| +  /* Free up the array of auxiliary databases */ | 
| +  sqlite3CollapseDatabaseArray(db); | 
| +  assert( db->nDb<=2 ); | 
| +  assert( db->aDb==db->aDbStatic ); | 
|  | 
| /* Tell the code in notify.c that the connection no longer holds any | 
| ** locks and does not require any further unlock-notify callbacks. | 
| */ | 
| sqlite3ConnectionClosed(db); | 
|  | 
| -  assert( db->nDb<=2 ); | 
| -  assert( db->aDb==db->aDbStatic ); | 
| for(j=0; j<ArraySize(db->aFunc.a); j++){ | 
| FuncDef *pNext, *pHash, *p; | 
| for(p=db->aFunc.a[j]; p; p=pHash){ | 
| @@ -774,11 +997,13 @@ int sqlite3_close(sqlite3 *db){ | 
| sqlite3HashClear(&db->aModule); | 
| #endif | 
|  | 
| -  sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */ | 
| -  if( db->pErr ){ | 
| -    sqlite3ValueFree(db->pErr); | 
| -  } | 
| +  sqlite3Error(db, SQLITE_OK); /* Deallocates any cached error strings. */ | 
| +  sqlite3ValueFree(db->pErr); | 
| sqlite3CloseExtensions(db); | 
| +#if SQLITE_USER_AUTHENTICATION | 
| +  sqlite3_free(db->auth.zAuthUser); | 
| +  sqlite3_free(db->auth.zAuthPW); | 
| +#endif | 
|  | 
| db->magic = SQLITE_MAGIC_ERROR; | 
|  | 
| @@ -797,36 +1022,53 @@ int sqlite3_close(sqlite3 *db){ | 
| sqlite3_free(db->lookaside.pStart); | 
| } | 
| sqlite3_free(db); | 
| -  return SQLITE_OK; | 
| } | 
|  | 
| /* | 
| -** Rollback all database files. | 
| +** Rollback all database files.  If tripCode is not SQLITE_OK, then | 
| +** any write cursors are invalidated ("tripped" - as in "tripping a circuit | 
| +** breaker") and made to return tripCode if there are any further | 
| +** attempts to use that cursor.  Read cursors remain open and valid | 
| +** but are "saved" in case the table pages are moved around. | 
| */ | 
| -void sqlite3RollbackAll(sqlite3 *db){ | 
| +void sqlite3RollbackAll(sqlite3 *db, int tripCode){ | 
| int i; | 
| int inTrans = 0; | 
| +  int schemaChange; | 
| assert( sqlite3_mutex_held(db->mutex) ); | 
| sqlite3BeginBenignMalloc(); | 
| + | 
| +  /* Obtain all b-tree mutexes before making any calls to BtreeRollback(). | 
| +  ** This is important in case the transaction being rolled back has | 
| +  ** modified the database schema. If the b-tree mutexes are not taken | 
| +  ** here, then another shared-cache connection might sneak in between | 
| +  ** the database rollback and schema reset, which can cause false | 
| +  ** corruption reports in some cases.  */ | 
| +  sqlite3BtreeEnterAll(db); | 
| +  schemaChange = (db->flags & SQLITE_InternChanges)!=0 && db->init.busy==0; | 
| + | 
| for(i=0; i<db->nDb; i++){ | 
| -    if( db->aDb[i].pBt ){ | 
| -      if( sqlite3BtreeIsInTrans(db->aDb[i].pBt) ){ | 
| +    Btree *p = db->aDb[i].pBt; | 
| +    if( p ){ | 
| +      if( sqlite3BtreeIsInTrans(p) ){ | 
| inTrans = 1; | 
| } | 
| -      sqlite3BtreeRollback(db->aDb[i].pBt); | 
| -      db->aDb[i].inTrans = 0; | 
| +      sqlite3BtreeRollback(p, tripCode, !schemaChange); | 
| } | 
| } | 
| sqlite3VtabRollback(db); | 
| sqlite3EndBenignMalloc(); | 
|  | 
| -  if( db->flags&SQLITE_InternChanges ){ | 
| +  if( (db->flags&SQLITE_InternChanges)!=0 && db->init.busy==0 ){ | 
| sqlite3ExpirePreparedStatements(db); | 
| -    sqlite3ResetInternalSchema(db, -1); | 
| +    sqlite3ResetAllSchemasOfConnection(db); | 
| } | 
| +  sqlite3BtreeLeaveAll(db); | 
|  | 
| /* Any deferred constraint violations have now been resolved. */ | 
| db->nDeferredCons = 0; | 
| +  db->nDeferredImmCons = 0; | 
| +  db->flags &= ~SQLITE_DeferFKs; | 
|  | 
| /* If one has been configured, invoke the rollback-hook callback */ | 
| if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){ | 
| @@ -835,6 +1077,115 @@ void sqlite3RollbackAll(sqlite3 *db){ | 
| } | 
|  | 
| /* | 
| +** Return a static string containing the name corresponding to the error code | 
| +** specified in the argument. | 
| +*/ | 
| +#if (defined(SQLITE_DEBUG) && SQLITE_OS_WIN) || defined(SQLITE_TEST) | 
| +const char *sqlite3ErrName(int rc){ | 
| +  const char *zName = 0; | 
| +  int i, origRc = rc; | 
| +  for(i=0; i<2 && zName==0; i++, rc &= 0xff){ | 
| +    switch( rc ){ | 
| +      case SQLITE_OK:                 zName = "SQLITE_OK";                break; | 
| +      case SQLITE_ERROR:              zName = "SQLITE_ERROR";             break; | 
| +      case SQLITE_INTERNAL:           zName = "SQLITE_INTERNAL";          break; | 
| +      case SQLITE_PERM:               zName = "SQLITE_PERM";              break; | 
| +      case SQLITE_ABORT:              zName = "SQLITE_ABORT";             break; | 
| +      case SQLITE_ABORT_ROLLBACK:     zName = "SQLITE_ABORT_ROLLBACK";    break; | 
| +      case SQLITE_BUSY:               zName = "SQLITE_BUSY";              break; | 
| +      case SQLITE_BUSY_RECOVERY:      zName = "SQLITE_BUSY_RECOVERY";     break; | 
| +      case SQLITE_BUSY_SNAPSHOT:      zName = "SQLITE_BUSY_SNAPSHOT";     break; | 
| +      case SQLITE_LOCKED:             zName = "SQLITE_LOCKED";            break; | 
| +      case SQLITE_LOCKED_SHAREDCACHE: zName = "SQLITE_LOCKED_SHAREDCACHE";break; | 
| +      case SQLITE_NOMEM:              zName = "SQLITE_NOMEM";             break; | 
| +      case SQLITE_READONLY:           zName = "SQLITE_READONLY";          break; | 
| +      case SQLITE_READONLY_RECOVERY:  zName = "SQLITE_READONLY_RECOVERY"; break; | 
| +      case SQLITE_READONLY_CANTLOCK:  zName = "SQLITE_READONLY_CANTLOCK"; break; | 
| +      case SQLITE_READONLY_ROLLBACK:  zName = "SQLITE_READONLY_ROLLBACK"; break; | 
| +      case SQLITE_READONLY_DBMOVED:   zName = "SQLITE_READONLY_DBMOVED";  break; | 
| +      case SQLITE_INTERRUPT:          zName = "SQLITE_INTERRUPT";         break; | 
| +      case SQLITE_IOERR:              zName = "SQLITE_IOERR";             break; | 
| +      case SQLITE_IOERR_READ:         zName = "SQLITE_IOERR_READ";        break; | 
| +      case SQLITE_IOERR_SHORT_READ:   zName = "SQLITE_IOERR_SHORT_READ";  break; | 
| +      case SQLITE_IOERR_WRITE:        zName = "SQLITE_IOERR_WRITE";       break; | 
| +      case SQLITE_IOERR_FSYNC:        zName = "SQLITE_IOERR_FSYNC";       break; | 
| +      case SQLITE_IOERR_DIR_FSYNC:    zName = "SQLITE_IOERR_DIR_FSYNC";   break; | 
| +      case SQLITE_IOERR_TRUNCATE:     zName = "SQLITE_IOERR_TRUNCATE";    break; | 
| +      case SQLITE_IOERR_FSTAT:        zName = "SQLITE_IOERR_FSTAT";       break; | 
| +      case SQLITE_IOERR_UNLOCK:       zName = "SQLITE_IOERR_UNLOCK";      break; | 
| +      case SQLITE_IOERR_RDLOCK:       zName = "SQLITE_IOERR_RDLOCK";      break; | 
| +      case SQLITE_IOERR_DELETE:       zName = "SQLITE_IOERR_DELETE";      break; | 
| +      case SQLITE_IOERR_NOMEM:        zName = "SQLITE_IOERR_NOMEM";       break; | 
| +      case SQLITE_IOERR_ACCESS:       zName = "SQLITE_IOERR_ACCESS";      break; | 
| +      case SQLITE_IOERR_CHECKRESERVEDLOCK: | 
| +                                zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break; | 
| +      case SQLITE_IOERR_LOCK:         zName = "SQLITE_IOERR_LOCK";        break; | 
| +      case SQLITE_IOERR_CLOSE:        zName = "SQLITE_IOERR_CLOSE";       break; | 
| +      case SQLITE_IOERR_DIR_CLOSE:    zName = "SQLITE_IOERR_DIR_CLOSE";   break; | 
| +      case SQLITE_IOERR_SHMOPEN:      zName = "SQLITE_IOERR_SHMOPEN";     break; | 
| +      case SQLITE_IOERR_SHMSIZE:      zName = "SQLITE_IOERR_SHMSIZE";     break; | 
| +      case SQLITE_IOERR_SHMLOCK:      zName = "SQLITE_IOERR_SHMLOCK";     break; | 
| +      case SQLITE_IOERR_SHMMAP:       zName = "SQLITE_IOERR_SHMMAP";      break; | 
| +      case SQLITE_IOERR_SEEK:         zName = "SQLITE_IOERR_SEEK";        break; | 
| +      case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break; | 
| +      case SQLITE_IOERR_MMAP:         zName = "SQLITE_IOERR_MMAP";        break; | 
| +      case SQLITE_IOERR_GETTEMPPATH:  zName = "SQLITE_IOERR_GETTEMPPATH"; break; | 
| +      case SQLITE_IOERR_CONVPATH:     zName = "SQLITE_IOERR_CONVPATH";    break; | 
| +      case SQLITE_CORRUPT:            zName = "SQLITE_CORRUPT";           break; | 
| +      case SQLITE_CORRUPT_VTAB:       zName = "SQLITE_CORRUPT_VTAB";      break; | 
| +      case SQLITE_NOTFOUND:           zName = "SQLITE_NOTFOUND";          break; | 
| +      case SQLITE_FULL:               zName = "SQLITE_FULL";              break; | 
| +      case SQLITE_CANTOPEN:           zName = "SQLITE_CANTOPEN";          break; | 
| +      case SQLITE_CANTOPEN_NOTEMPDIR: zName = "SQLITE_CANTOPEN_NOTEMPDIR";break; | 
| +      case SQLITE_CANTOPEN_ISDIR:     zName = "SQLITE_CANTOPEN_ISDIR";    break; | 
| +      case SQLITE_CANTOPEN_FULLPATH:  zName = "SQLITE_CANTOPEN_FULLPATH"; break; | 
| +      case SQLITE_CANTOPEN_CONVPATH:  zName = "SQLITE_CANTOPEN_CONVPATH"; break; | 
| +      case SQLITE_PROTOCOL:           zName = "SQLITE_PROTOCOL";          break; | 
| +      case SQLITE_EMPTY:              zName = "SQLITE_EMPTY";             break; | 
| +      case SQLITE_SCHEMA:             zName = "SQLITE_SCHEMA";            break; | 
| +      case SQLITE_TOOBIG:             zName = "SQLITE_TOOBIG";            break; | 
| +      case SQLITE_CONSTRAINT:         zName = "SQLITE_CONSTRAINT";        break; | 
| +      case SQLITE_CONSTRAINT_UNIQUE:  zName = "SQLITE_CONSTRAINT_UNIQUE"; break; | 
| +      case SQLITE_CONSTRAINT_TRIGGER: zName = "SQLITE_CONSTRAINT_TRIGGER";break; | 
| +      case SQLITE_CONSTRAINT_FOREIGNKEY: | 
| +                                zName = "SQLITE_CONSTRAINT_FOREIGNKEY";   break; | 
| +      case SQLITE_CONSTRAINT_CHECK:   zName = "SQLITE_CONSTRAINT_CHECK";  break; | 
| +      case SQLITE_CONSTRAINT_PRIMARYKEY: | 
| +                                zName = "SQLITE_CONSTRAINT_PRIMARYKEY";   break; | 
| +      case SQLITE_CONSTRAINT_NOTNULL: zName = "SQLITE_CONSTRAINT_NOTNULL";break; | 
| +      case SQLITE_CONSTRAINT_COMMITHOOK: | 
| +                                zName = "SQLITE_CONSTRAINT_COMMITHOOK";   break; | 
| +      case SQLITE_CONSTRAINT_VTAB:    zName = "SQLITE_CONSTRAINT_VTAB";   break; | 
| +      case SQLITE_CONSTRAINT_FUNCTION: | 
| +                                zName = "SQLITE_CONSTRAINT_FUNCTION";     break; | 
| +      case SQLITE_CONSTRAINT_ROWID:   zName = "SQLITE_CONSTRAINT_ROWID";  break; | 
| +      case SQLITE_MISMATCH:           zName = "SQLITE_MISMATCH";          break; | 
| +      case SQLITE_MISUSE:             zName = "SQLITE_MISUSE";            break; | 
| +      case SQLITE_NOLFS:              zName = "SQLITE_NOLFS";             break; | 
| +      case SQLITE_AUTH:               zName = "SQLITE_AUTH";              break; | 
| +      case SQLITE_FORMAT:             zName = "SQLITE_FORMAT";            break; | 
| +      case SQLITE_RANGE:              zName = "SQLITE_RANGE";             break; | 
| +      case SQLITE_NOTADB:             zName = "SQLITE_NOTADB";            break; | 
| +      case SQLITE_ROW:                zName = "SQLITE_ROW";               break; | 
| +      case SQLITE_NOTICE:             zName = "SQLITE_NOTICE";            break; | 
| +      case SQLITE_NOTICE_RECOVER_WAL: zName = "SQLITE_NOTICE_RECOVER_WAL";break; | 
| +      case SQLITE_NOTICE_RECOVER_ROLLBACK: | 
| +                                zName = "SQLITE_NOTICE_RECOVER_ROLLBACK"; break; | 
| +      case SQLITE_WARNING:            zName = "SQLITE_WARNING";           break; | 
| +      case SQLITE_WARNING_AUTOINDEX:  zName = "SQLITE_WARNING_AUTOINDEX"; break; | 
| +      case SQLITE_DONE:               zName = "SQLITE_DONE";              break; | 
| +    } | 
| +  } | 
| +  if( zName==0 ){ | 
| +    static char zBuf[50]; | 
| +    sqlite3_snprintf(sizeof(zBuf), zBuf, "SQLITE_UNKNOWN(%d)", origRc); | 
| +    zName = zBuf; | 
| +  } | 
| +  return zName; | 
| +} | 
| +#endif | 
| + | 
| +/* | 
| ** Return a static string that describes the kind of error specified in the | 
| ** argument. | 
| */ | 
| @@ -868,12 +1219,21 @@ const char *sqlite3ErrStr(int rc){ | 
| /* SQLITE_RANGE       */ "bind or column index out of range", | 
| /* SQLITE_NOTADB      */ "file is encrypted or is not a database", | 
| }; | 
| -  rc &= 0xff; | 
| -  if( ALWAYS(rc>=0) && rc<(int)(sizeof(aMsg)/sizeof(aMsg[0])) && aMsg[rc]!=0 ){ | 
| -    return aMsg[rc]; | 
| -  }else{ | 
| -    return "unknown error"; | 
| +  const char *zErr = "unknown error"; | 
| +  switch( rc ){ | 
| +    case SQLITE_ABORT_ROLLBACK: { | 
| +      zErr = "abort due to ROLLBACK"; | 
| +      break; | 
| +    } | 
| +    default: { | 
| +      rc &= 0xff; | 
| +      if( ALWAYS(rc>=0) && rc<ArraySize(aMsg) && aMsg[rc]!=0 ){ | 
| +        zErr = aMsg[rc]; | 
| +      } | 
| +      break; | 
| +    } | 
| } | 
| +  return zErr; | 
| } | 
|  | 
| /* | 
| @@ -953,6 +1313,7 @@ int sqlite3_busy_handler( | 
| db->busyHandler.xFunc = xBusy; | 
| db->busyHandler.pArg = pArg; | 
| db->busyHandler.nBusy = 0; | 
| +  db->busyTimeout = 0; | 
| sqlite3_mutex_leave(db->mutex); | 
| return SQLITE_OK; | 
| } | 
| @@ -972,7 +1333,7 @@ void sqlite3_progress_handler( | 
| sqlite3_mutex_enter(db->mutex); | 
| if( nOps>0 ){ | 
| db->xProgress = xProgress; | 
| -    db->nProgressOps = nOps; | 
| +    db->nProgressOps = (unsigned)nOps; | 
| db->pProgressArg = pArg; | 
| }else{ | 
| db->xProgress = 0; | 
| @@ -990,8 +1351,8 @@ void sqlite3_progress_handler( | 
| */ | 
| int sqlite3_busy_timeout(sqlite3 *db, int ms){ | 
| if( ms>0 ){ | 
| -    db->busyTimeout = ms; | 
| sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db); | 
| +    db->busyTimeout = ms; | 
| }else{ | 
| sqlite3_busy_handler(db, 0, 0); | 
| } | 
| @@ -1025,6 +1386,7 @@ int sqlite3CreateFunc( | 
| ){ | 
| FuncDef *p; | 
| int nName; | 
| +  int extraFlags; | 
|  | 
| assert( sqlite3_mutex_held(db->mutex) ); | 
| if( zFunctionName==0 || | 
| @@ -1035,6 +1397,10 @@ int sqlite3CreateFunc( | 
| (255<(nName = sqlite3Strlen30( zFunctionName))) ){ | 
| return SQLITE_MISUSE_BKPT; | 
| } | 
| + | 
| +  assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); | 
| +  extraFlags = enc &  SQLITE_DETERMINISTIC; | 
| +  enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); | 
|  | 
| #ifndef SQLITE_OMIT_UTF16 | 
| /* If SQLITE_UTF16 is specified as the encoding type, transform this | 
| @@ -1048,10 +1414,10 @@ int sqlite3CreateFunc( | 
| enc = SQLITE_UTF16NATIVE; | 
| }else if( enc==SQLITE_ANY ){ | 
| int rc; | 
| -    rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8, | 
| +    rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF8|extraFlags, | 
| pUserData, xFunc, xStep, xFinal, pDestructor); | 
| if( rc==SQLITE_OK ){ | 
| -      rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE, | 
| +      rc = sqlite3CreateFunc(db, zFunctionName, nArg, SQLITE_UTF16LE|extraFlags, | 
| pUserData, xFunc, xStep, xFinal, pDestructor); | 
| } | 
| if( rc!=SQLITE_OK ){ | 
| @@ -1069,9 +1435,9 @@ int sqlite3CreateFunc( | 
| ** operation to continue but invalidate all precompiled statements. | 
| */ | 
| p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0); | 
| -  if( p && p->iPrefEnc==enc && p->nArg==nArg ){ | 
| -    if( db->activeVdbeCnt ){ | 
| -      sqlite3Error(db, SQLITE_BUSY, | 
| +  if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){ | 
| +    if( db->nVdbeActive ){ | 
| +      sqlite3ErrorWithMsg(db, SQLITE_BUSY, | 
| "unable to delete/modify user-function due to active statements"); | 
| assert( !db->mallocFailed ); | 
| return SQLITE_BUSY; | 
| @@ -1094,7 +1460,8 @@ int sqlite3CreateFunc( | 
| pDestructor->nRef++; | 
| } | 
| p->pDestructor = pDestructor; | 
| -  p->flags = 0; | 
| +  p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags; | 
| +  testcase( p->funcFlags & SQLITE_DETERMINISTIC ); | 
| p->xFunc = xFunc; | 
| p->xStep = xStep; | 
| p->xFinalize = xFinal; | 
| @@ -1199,13 +1566,13 @@ int sqlite3_overload_function( | 
| int nArg | 
| ){ | 
| int nName = sqlite3Strlen30(zName); | 
| -  int rc; | 
| +  int rc = SQLITE_OK; | 
| sqlite3_mutex_enter(db->mutex); | 
| if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){ | 
| -    sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8, | 
| -                      0, sqlite3InvalidFunction, 0, 0, 0); | 
| +    rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8, | 
| +                           0, sqlite3InvalidFunction, 0, 0, 0); | 
| } | 
| -  rc = sqlite3ApiExit(db, SQLITE_OK); | 
| +  rc = sqlite3ApiExit(db, rc); | 
| sqlite3_mutex_leave(db->mutex); | 
| return rc; | 
| } | 
| @@ -1251,9 +1618,8 @@ void *sqlite3_profile( | 
| } | 
| #endif /* SQLITE_OMIT_TRACE */ | 
|  | 
| -/*** EXPERIMENTAL *** | 
| -** | 
| -** Register a function to be invoked when a transaction comments. | 
| +/* | 
| +** Register a function to be invoked when a transaction commits. | 
| ** If the invoked function returns non-zero, then the commit becomes a | 
| ** rollback. | 
| */ | 
| @@ -1409,10 +1775,10 @@ int sqlite3_wal_checkpoint_v2( | 
| } | 
| if( iDb<0 ){ | 
| rc = SQLITE_ERROR; | 
| -    sqlite3Error(db, SQLITE_ERROR, "unknown database: %s", zDb); | 
| +    sqlite3ErrorWithMsg(db, SQLITE_ERROR, "unknown database: %s", zDb); | 
| }else{ | 
| rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt); | 
| -    sqlite3Error(db, rc, 0); | 
| +    sqlite3Error(db, rc); | 
| } | 
| rc = sqlite3ApiExit(db, rc); | 
| sqlite3_mutex_leave(db->mutex); | 
| @@ -1525,6 +1891,7 @@ const char *sqlite3_errmsg(sqlite3 *db){ | 
| if( db->mallocFailed ){ | 
| z = sqlite3ErrStr(SQLITE_NOMEM); | 
| }else{ | 
| +    testcase( db->pErr==0 ); | 
| z = (char*)sqlite3_value_text(db->pErr); | 
| assert( !db->mallocFailed ); | 
| if( z==0 ){ | 
| @@ -1566,8 +1933,7 @@ const void *sqlite3_errmsg16(sqlite3 *db){ | 
| }else{ | 
| z = sqlite3_value_text16(db->pErr); | 
| if( z==0 ){ | 
| -      sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode), | 
| -           SQLITE_UTF8, SQLITE_STATIC); | 
| +      sqlite3ErrorWithMsg(db, db->errCode, sqlite3ErrStr(db->errCode)); | 
| z = sqlite3_value_text16(db->pErr); | 
| } | 
| /* A malloc() may have failed within the call to sqlite3_value_text16() | 
| @@ -1606,6 +1972,41 @@ int sqlite3_extended_errcode(sqlite3 *db){ | 
| } | 
|  | 
| /* | 
| +** Return a string that describes the kind of error specified in the | 
| +** argument.  For now, this simply calls the internal sqlite3ErrStr() | 
| +** function. | 
| +*/ | 
| +const char *sqlite3_errstr(int rc){ | 
| +  return sqlite3ErrStr(rc); | 
| +} | 
| + | 
| +/* | 
| +** Invalidate all cached KeyInfo objects for database connection "db" | 
| +*/ | 
| +static void invalidateCachedKeyInfo(sqlite3 *db){ | 
| +  Db *pDb;                    /* A single database */ | 
| +  int iDb;                    /* The database index number */ | 
| +  HashElem *k;                /* For looping over tables in pDb */ | 
| +  Table *pTab;                /* A table in the database */ | 
| +  Index *pIdx;                /* Each index */ | 
| + | 
| +  for(iDb=0, pDb=db->aDb; iDb<db->nDb; iDb++, pDb++){ | 
| +    if( pDb->pBt==0 ) continue; | 
| +    sqlite3BtreeEnter(pDb->pBt); | 
| +    for(k=sqliteHashFirst(&pDb->pSchema->tblHash);  k; k=sqliteHashNext(k)){ | 
| +      pTab = (Table*)sqliteHashData(k); | 
| +      for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ | 
| +        if( pIdx->pKeyInfo && pIdx->pKeyInfo->db==db ){ | 
| +          sqlite3KeyInfoUnref(pIdx->pKeyInfo); | 
| +          pIdx->pKeyInfo = 0; | 
| +        } | 
| +      } | 
| +    } | 
| +    sqlite3BtreeLeave(pDb->pBt); | 
| +  } | 
| +} | 
| + | 
| +/* | 
| ** Create a new collating function for database "db".  The name is zName | 
| ** and the encoding is enc. | 
| */ | 
| @@ -1613,14 +2014,12 @@ static int createCollation( | 
| sqlite3* db, | 
| const char *zName, | 
| u8 enc, | 
| -  u8 collType, | 
| void* pCtx, | 
| int(*xCompare)(void*,int,const void*,int,const void*), | 
| void(*xDel)(void*) | 
| ){ | 
| CollSeq *pColl; | 
| int enc2; | 
| -  int nName = sqlite3Strlen30(zName); | 
|  | 
| assert( sqlite3_mutex_held(db->mutex) ); | 
|  | 
| @@ -1644,12 +2043,13 @@ static int createCollation( | 
| */ | 
| pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0); | 
| if( pColl && pColl->xCmp ){ | 
| -    if( db->activeVdbeCnt ){ | 
| -      sqlite3Error(db, SQLITE_BUSY, | 
| +    if( db->nVdbeActive ){ | 
| +      sqlite3ErrorWithMsg(db, SQLITE_BUSY, | 
| "unable to delete/modify collation sequence due to active statements"); | 
| return SQLITE_BUSY; | 
| } | 
| sqlite3ExpirePreparedStatements(db); | 
| +    invalidateCachedKeyInfo(db); | 
|  | 
| /* If collation sequence pColl was created directly by a call to | 
| ** sqlite3_create_collation, and not generated by synthCollSeq(), | 
| @@ -1658,7 +2058,7 @@ static int createCollation( | 
| ** to be called. | 
| */ | 
| if( (pColl->enc & ~SQLITE_UTF16_ALIGNED)==enc2 ){ | 
| -      CollSeq *aColl = sqlite3HashFind(&db->aCollSeq, zName, nName); | 
| +      CollSeq *aColl = sqlite3HashFind(&db->aCollSeq, zName); | 
| int j; | 
| for(j=0; j<3; j++){ | 
| CollSeq *p = &aColl[j]; | 
| @@ -1678,8 +2078,7 @@ static int createCollation( | 
| pColl->pUser = pCtx; | 
| pColl->xDel = xDel; | 
| pColl->enc = (u8)(enc2 | (enc & SQLITE_UTF16_ALIGNED)); | 
| -  pColl->type = collType; | 
| -  sqlite3Error(db, SQLITE_OK, 0); | 
| +  sqlite3Error(db, SQLITE_OK); | 
| return SQLITE_OK; | 
| } | 
|  | 
| @@ -1699,8 +2098,9 @@ static const int aHardLimit[] = { | 
| SQLITE_MAX_FUNCTION_ARG, | 
| SQLITE_MAX_ATTACHED, | 
| SQLITE_MAX_LIKE_PATTERN_LENGTH, | 
| -  SQLITE_MAX_VARIABLE_NUMBER, | 
| +  SQLITE_MAX_VARIABLE_NUMBER,      /* IMP: R-38091-32352 */ | 
| SQLITE_MAX_TRIGGER_DEPTH, | 
| +  SQLITE_MAX_WORKER_THREADS, | 
| }; | 
|  | 
| /* | 
| @@ -1724,8 +2124,8 @@ static const int aHardLimit[] = { | 
| #if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>1000 | 
| # error SQLITE_MAX_FUNCTION_ARG must be between 0 and 1000 | 
| #endif | 
| -#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>62 | 
| -# error SQLITE_MAX_ATTACHED must be between 0 and 62 | 
| +#if SQLITE_MAX_ATTACHED<0 || SQLITE_MAX_ATTACHED>125 | 
| +# error SQLITE_MAX_ATTACHED must be between 0 and 125 | 
| #endif | 
| #if SQLITE_MAX_LIKE_PATTERN_LENGTH<1 | 
| # error SQLITE_MAX_LIKE_PATTERN_LENGTH must be at least 1 | 
| @@ -1736,6 +2136,9 @@ static const int aHardLimit[] = { | 
| #if SQLITE_MAX_TRIGGER_DEPTH<1 | 
| # error SQLITE_MAX_TRIGGER_DEPTH must be at least 1 | 
| #endif | 
| +#if SQLITE_MAX_WORKER_THREADS<0 || SQLITE_MAX_WORKER_THREADS>50 | 
| +# error SQLITE_MAX_WORKER_THREADS must be between 0 and 50 | 
| +#endif | 
|  | 
|  | 
| /* | 
| @@ -1769,7 +2172,8 @@ int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ | 
| SQLITE_MAX_LIKE_PATTERN_LENGTH ); | 
| assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER); | 
| assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH ); | 
| -  assert( SQLITE_LIMIT_TRIGGER_DEPTH==(SQLITE_N_LIMIT-1) ); | 
| +  assert( aHardLimit[SQLITE_LIMIT_WORKER_THREADS]==SQLITE_MAX_WORKER_THREADS ); | 
| +  assert( SQLITE_LIMIT_WORKER_THREADS==(SQLITE_N_LIMIT-1) ); | 
|  | 
|  | 
| if( limitId<0 || limitId>=SQLITE_N_LIMIT ){ | 
| @@ -1786,6 +2190,239 @@ int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ | 
| } | 
|  | 
| /* | 
| +** This function is used to parse both URIs and non-URI filenames passed by the | 
| +** user to API functions sqlite3_open() or sqlite3_open_v2(), and for database | 
| +** URIs specified as part of ATTACH statements. | 
| +** | 
| +** The first argument to this function is the name of the VFS to use (or | 
| +** a NULL to signify the default VFS) if the URI does not contain a "vfs=xxx" | 
| +** query parameter. The second argument contains the URI (or non-URI filename) | 
| +** itself. When this function is called the *pFlags variable should contain | 
| +** the default flags to open the database handle with. The value stored in | 
| +** *pFlags may be updated before returning if the URI filename contains | 
| +** "cache=xxx" or "mode=xxx" query parameters. | 
| +** | 
| +** If successful, SQLITE_OK is returned. In this case *ppVfs is set to point to | 
| +** the VFS that should be used to open the database file. *pzFile is set to | 
| +** point to a buffer containing the name of the file to open. It is the | 
| +** responsibility of the caller to eventually call sqlite3_free() to release | 
| +** this buffer. | 
| +** | 
| +** If an error occurs, then an SQLite error code is returned and *pzErrMsg | 
| +** may be set to point to a buffer containing an English language error | 
| +** message. It is the responsibility of the caller to eventually release | 
| +** this buffer by calling sqlite3_free(). | 
| +*/ | 
| +int sqlite3ParseUri( | 
| +  const char *zDefaultVfs,        /* VFS to use if no "vfs=xxx" query option */ | 
| +  const char *zUri,               /* Nul-terminated URI to parse */ | 
| +  unsigned int *pFlags,           /* IN/OUT: SQLITE_OPEN_XXX flags */ | 
| +  sqlite3_vfs **ppVfs,            /* OUT: VFS to use */ | 
| +  char **pzFile,                  /* OUT: Filename component of URI */ | 
| +  char **pzErrMsg                 /* OUT: Error message (if rc!=SQLITE_OK) */ | 
| +){ | 
| +  int rc = SQLITE_OK; | 
| +  unsigned int flags = *pFlags; | 
| +  const char *zVfs = zDefaultVfs; | 
| +  char *zFile; | 
| +  char c; | 
| +  int nUri = sqlite3Strlen30(zUri); | 
| + | 
| +  assert( *pzErrMsg==0 ); | 
| + | 
| +  if( ((flags & SQLITE_OPEN_URI) || sqlite3GlobalConfig.bOpenUri) | 
| +   && nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */ | 
| +  ){ | 
| +    char *zOpt; | 
| +    int eState;                   /* Parser state when parsing URI */ | 
| +    int iIn;                      /* Input character index */ | 
| +    int iOut = 0;                 /* Output character index */ | 
| +    int nByte = nUri+2;           /* Bytes of space to allocate */ | 
| + | 
| +    /* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen | 
| +    ** method that there may be extra parameters following the file-name.  */ | 
| +    flags |= SQLITE_OPEN_URI; | 
| + | 
| +    for(iIn=0; iIn<nUri; iIn++) nByte += (zUri[iIn]=='&'); | 
| +    zFile = sqlite3_malloc(nByte); | 
| +    if( !zFile ) return SQLITE_NOMEM; | 
| + | 
| +    iIn = 5; | 
| +#ifndef SQLITE_ALLOW_URI_AUTHORITY | 
| +    /* Discard the scheme and authority segments of the URI. */ | 
| +    if( zUri[5]=='/' && zUri[6]=='/' ){ | 
| +      iIn = 7; | 
| +      while( zUri[iIn] && zUri[iIn]!='/' ) iIn++; | 
| +      if( iIn!=7 && (iIn!=16 || memcmp("localhost", &zUri[7], 9)) ){ | 
| +        *pzErrMsg = sqlite3_mprintf("invalid uri authority: %.*s", | 
| +            iIn-7, &zUri[7]); | 
| +        rc = SQLITE_ERROR; | 
| +        goto parse_uri_out; | 
| +      } | 
| +    } | 
| +#endif | 
| + | 
| +    /* Copy the filename and any query parameters into the zFile buffer. | 
| +    ** Decode %HH escape codes along the way. | 
| +    ** | 
| +    ** Within this loop, variable eState may be set to 0, 1 or 2, depending | 
| +    ** on the parsing context. As follows: | 
| +    ** | 
| +    **   0: Parsing file-name. | 
| +    **   1: Parsing name section of a name=value query parameter. | 
| +    **   2: Parsing value section of a name=value query parameter. | 
| +    */ | 
| +    eState = 0; | 
| +    while( (c = zUri[iIn])!=0 && c!='#' ){ | 
| +      iIn++; | 
| +      if( c=='%' | 
| +       && sqlite3Isxdigit(zUri[iIn]) | 
| +       && sqlite3Isxdigit(zUri[iIn+1]) | 
| +      ){ | 
| +        int octet = (sqlite3HexToInt(zUri[iIn++]) << 4); | 
| +        octet += sqlite3HexToInt(zUri[iIn++]); | 
| + | 
| +        assert( octet>=0 && octet<256 ); | 
| +        if( octet==0 ){ | 
| +          /* This branch is taken when "%00" appears within the URI. In this | 
| +          ** case we ignore all text in the remainder of the path, name or | 
| +          ** value currently being parsed. So ignore the current character | 
| +          ** and skip to the next "?", "=" or "&", as appropriate. */ | 
| +          while( (c = zUri[iIn])!=0 && c!='#' | 
| +              && (eState!=0 || c!='?') | 
| +              && (eState!=1 || (c!='=' && c!='&')) | 
| +              && (eState!=2 || c!='&') | 
| +          ){ | 
| +            iIn++; | 
| +          } | 
| +          continue; | 
| +        } | 
| +        c = octet; | 
| +      }else if( eState==1 && (c=='&' || c=='=') ){ | 
| +        if( zFile[iOut-1]==0 ){ | 
| +          /* An empty option name. Ignore this option altogether. */ | 
| +          while( zUri[iIn] && zUri[iIn]!='#' && zUri[iIn-1]!='&' ) iIn++; | 
| +          continue; | 
| +        } | 
| +        if( c=='&' ){ | 
| +          zFile[iOut++] = '\0'; | 
| +        }else{ | 
| +          eState = 2; | 
| +        } | 
| +        c = 0; | 
| +      }else if( (eState==0 && c=='?') || (eState==2 && c=='&') ){ | 
| +        c = 0; | 
| +        eState = 1; | 
| +      } | 
| +      zFile[iOut++] = c; | 
| +    } | 
| +    if( eState==1 ) zFile[iOut++] = '\0'; | 
| +    zFile[iOut++] = '\0'; | 
| +    zFile[iOut++] = '\0'; | 
| + | 
| +    /* Check if there were any options specified that should be interpreted | 
| +    ** here. Options that are interpreted here include "vfs" and those that | 
| +    ** correspond to flags that may be passed to the sqlite3_open_v2() | 
| +    ** method. */ | 
| +    zOpt = &zFile[sqlite3Strlen30(zFile)+1]; | 
| +    while( zOpt[0] ){ | 
| +      int nOpt = sqlite3Strlen30(zOpt); | 
| +      char *zVal = &zOpt[nOpt+1]; | 
| +      int nVal = sqlite3Strlen30(zVal); | 
| + | 
| +      if( nOpt==3 && memcmp("vfs", zOpt, 3)==0 ){ | 
| +        zVfs = zVal; | 
| +      }else{ | 
| +        struct OpenMode { | 
| +          const char *z; | 
| +          int mode; | 
| +        } *aMode = 0; | 
| +        char *zModeType = 0; | 
| +        int mask = 0; | 
| +        int limit = 0; | 
| + | 
| +        if( nOpt==5 && memcmp("cache", zOpt, 5)==0 ){ | 
| +          static struct OpenMode aCacheMode[] = { | 
| +            { "shared",  SQLITE_OPEN_SHAREDCACHE }, | 
| +            { "private", SQLITE_OPEN_PRIVATECACHE }, | 
| +            { 0, 0 } | 
| +          }; | 
| + | 
| +          mask = SQLITE_OPEN_SHAREDCACHE|SQLITE_OPEN_PRIVATECACHE; | 
| +          aMode = aCacheMode; | 
| +          limit = mask; | 
| +          zModeType = "cache"; | 
| +        } | 
| +        if( nOpt==4 && memcmp("mode", zOpt, 4)==0 ){ | 
| +          static struct OpenMode aOpenMode[] = { | 
| +            { "ro",  SQLITE_OPEN_READONLY }, | 
| +            { "rw",  SQLITE_OPEN_READWRITE }, | 
| +            { "rwc", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE }, | 
| +            { "memory", SQLITE_OPEN_MEMORY }, | 
| +            { 0, 0 } | 
| +          }; | 
| + | 
| +          mask = SQLITE_OPEN_READONLY | SQLITE_OPEN_READWRITE | 
| +                   | SQLITE_OPEN_CREATE | SQLITE_OPEN_MEMORY; | 
| +          aMode = aOpenMode; | 
| +          limit = mask & flags; | 
| +          zModeType = "access"; | 
| +        } | 
| + | 
| +        if( aMode ){ | 
| +          int i; | 
| +          int mode = 0; | 
| +          for(i=0; aMode[i].z; i++){ | 
| +            const char *z = aMode[i].z; | 
| +            if( nVal==sqlite3Strlen30(z) && 0==memcmp(zVal, z, nVal) ){ | 
| +              mode = aMode[i].mode; | 
| +              break; | 
| +            } | 
| +          } | 
| +          if( mode==0 ){ | 
| +            *pzErrMsg = sqlite3_mprintf("no such %s mode: %s", zModeType, zVal); | 
| +            rc = SQLITE_ERROR; | 
| +            goto parse_uri_out; | 
| +          } | 
| +          if( (mode & ~SQLITE_OPEN_MEMORY)>limit ){ | 
| +            *pzErrMsg = sqlite3_mprintf("%s mode not allowed: %s", | 
| +                                        zModeType, zVal); | 
| +            rc = SQLITE_PERM; | 
| +            goto parse_uri_out; | 
| +          } | 
| +          flags = (flags & ~mask) | mode; | 
| +        } | 
| +      } | 
| + | 
| +      zOpt = &zVal[nVal+1]; | 
| +    } | 
| + | 
| +  }else{ | 
| +    zFile = sqlite3_malloc(nUri+2); | 
| +    if( !zFile ) return SQLITE_NOMEM; | 
| +    memcpy(zFile, zUri, nUri); | 
| +    zFile[nUri] = '\0'; | 
| +    zFile[nUri+1] = '\0'; | 
| +    flags &= ~SQLITE_OPEN_URI; | 
| +  } | 
| + | 
| +  *ppVfs = sqlite3_vfs_find(zVfs); | 
| +  if( *ppVfs==0 ){ | 
| +    *pzErrMsg = sqlite3_mprintf("no such vfs: %s", zVfs); | 
| +    rc = SQLITE_ERROR; | 
| +  } | 
| + parse_uri_out: | 
| +  if( rc!=SQLITE_OK ){ | 
| +    sqlite3_free(zFile); | 
| +    zFile = 0; | 
| +  } | 
| +  *pFlags = flags; | 
| +  *pzFile = zFile; | 
| +  return rc; | 
| +} | 
| + | 
| + | 
| +/* | 
| ** This routine does the work of opening a database on behalf of | 
| ** sqlite3_open() and sqlite3_open16(). The database filename "zFilename" | 
| ** is UTF-8 encoded. | 
| @@ -1793,12 +2430,14 @@ int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ | 
| static int openDatabase( | 
| const char *zFilename, /* Database filename UTF-8 encoded */ | 
| sqlite3 **ppDb,        /* OUT: Returned database handle */ | 
| -  unsigned flags,        /* Operational flags */ | 
| +  unsigned int flags,    /* Operational flags */ | 
| const char *zVfs       /* Name of the VFS to use */ | 
| ){ | 
| -  sqlite3 *db; | 
| -  int rc; | 
| -  int isThreadsafe; | 
| +  sqlite3 *db;                    /* Store allocated handle here */ | 
| +  int rc;                         /* Return code */ | 
| +  int isThreadsafe;               /* True for threadsafe connections */ | 
| +  char *zOpen = 0;                /* Filename argument to pass to BtreeOpen() */ | 
| +  char *zErrMsg = 0;              /* Error message from sqlite3ParseUri() */ | 
|  | 
| *ppDb = 0; | 
| #ifndef SQLITE_OMIT_AUTOINIT | 
| @@ -1822,7 +2461,9 @@ static int openDatabase( | 
| testcase( (1<<(flags&7))==0x02 ); /* READONLY */ | 
| testcase( (1<<(flags&7))==0x04 ); /* READWRITE */ | 
| testcase( (1<<(flags&7))==0x40 ); /* READWRITE | CREATE */ | 
| -  if( ((1<<(flags&7)) & 0x46)==0 ) return SQLITE_MISUSE; | 
| +  if( ((1<<(flags&7)) & 0x46)==0 ){ | 
| +    return SQLITE_MISUSE_BKPT;  /* IMP: R-65497-44594 */ | 
| +  } | 
|  | 
| if( sqlite3GlobalConfig.bCoreMutex==0 ){ | 
| isThreadsafe = 0; | 
| @@ -1881,10 +2522,16 @@ static int openDatabase( | 
|  | 
| assert( sizeof(db->aLimit)==sizeof(aHardLimit) ); | 
| memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit)); | 
| +  db->aLimit[SQLITE_LIMIT_WORKER_THREADS] = SQLITE_DEFAULT_WORKER_THREADS; | 
| db->autoCommit = 1; | 
| db->nextAutovac = -1; | 
| +  db->szMmap = sqlite3GlobalConfig.szMmap; | 
| db->nextPagesize = 0; | 
| -  db->flags |= SQLITE_ShortColNames | SQLITE_AutoIndex | SQLITE_EnableTrigger | 
| +  db->nMaxSorterMmap = 0x7FFFFFFF; | 
| +  db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger | SQLITE_CacheSpill | 
| +#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX | 
| +                 | SQLITE_AutoIndex | 
| +#endif | 
| #if SQLITE_DEFAULT_FILE_FORMAT<4 | 
| | SQLITE_LegacyFileFmt | 
| #endif | 
| @@ -1903,25 +2550,14 @@ static int openDatabase( | 
| sqlite3HashInit(&db->aModule); | 
| #endif | 
|  | 
| -  db->pVfs = sqlite3_vfs_find(zVfs); | 
| -  if( !db->pVfs ){ | 
| -    rc = SQLITE_ERROR; | 
| -    sqlite3Error(db, rc, "no such vfs: %s", zVfs); | 
| -    goto opendb_out; | 
| -  } | 
| - | 
| /* Add the default collation sequence BINARY. BINARY works for both UTF-8 | 
| ** and UTF-16, so add a version for each to avoid any unnecessary | 
| ** conversions. The only error that can occur here is a malloc() failure. | 
| */ | 
| -  createCollation(db, "BINARY", SQLITE_UTF8, SQLITE_COLL_BINARY, 0, | 
| -                  binCollFunc, 0); | 
| -  createCollation(db, "BINARY", SQLITE_UTF16BE, SQLITE_COLL_BINARY, 0, | 
| -                  binCollFunc, 0); | 
| -  createCollation(db, "BINARY", SQLITE_UTF16LE, SQLITE_COLL_BINARY, 0, | 
| -                  binCollFunc, 0); | 
| -  createCollation(db, "RTRIM", SQLITE_UTF8, SQLITE_COLL_USER, (void*)1, | 
| -                  binCollFunc, 0); | 
| +  createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0); | 
| +  createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0); | 
| +  createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0); | 
| +  createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0); | 
| if( db->mallocFailed ){ | 
| goto opendb_out; | 
| } | 
| @@ -1929,24 +2565,33 @@ static int openDatabase( | 
| assert( db->pDfltColl!=0 ); | 
|  | 
| /* Also add a UTF-8 case-insensitive collation sequence. */ | 
| -  createCollation(db, "NOCASE", SQLITE_UTF8, SQLITE_COLL_NOCASE, 0, | 
| -                  nocaseCollatingFunc, 0); | 
| +  createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0); | 
|  | 
| -  /* Open the backend database driver */ | 
| +  /* Parse the filename/URI argument. */ | 
| db->openFlags = flags; | 
| -  rc = sqlite3BtreeOpen(zFilename, db, &db->aDb[0].pBt, 0, | 
| +  rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); | 
| +  if( rc!=SQLITE_OK ){ | 
| +    if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; | 
| +    sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg); | 
| +    sqlite3_free(zErrMsg); | 
| +    goto opendb_out; | 
| +  } | 
| + | 
| +  /* Open the backend database driver */ | 
| +  rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0, | 
| flags | SQLITE_OPEN_MAIN_DB); | 
| if( rc!=SQLITE_OK ){ | 
| if( rc==SQLITE_IOERR_NOMEM ){ | 
| rc = SQLITE_NOMEM; | 
| } | 
| -    sqlite3Error(db, rc, 0); | 
| +    sqlite3Error(db, rc); | 
| goto opendb_out; | 
| } | 
| +  sqlite3BtreeEnter(db->aDb[0].pBt); | 
| db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt); | 
| +  sqlite3BtreeLeave(db->aDb[0].pBt); | 
| db->aDb[1].pSchema = sqlite3SchemaGet(db, 0); | 
|  | 
| - | 
| /* The default safety_level for the main database is 'full'; for the temp | 
| ** database it is 'NONE'. This matches the pager layer defaults. | 
| */ | 
| @@ -1964,16 +2609,19 @@ static int openDatabase( | 
| ** database schema yet. This is delayed until the first time the database | 
| ** is accessed. | 
| */ | 
| -  sqlite3Error(db, SQLITE_OK, 0); | 
| +  sqlite3Error(db, SQLITE_OK); | 
| sqlite3RegisterBuiltinFunctions(db); | 
|  | 
| /* Load automatic extensions - extensions that have been registered | 
| ** using the sqlite3_automatic_extension() API. | 
| */ | 
| -  sqlite3AutoLoadExtensions(db); | 
| rc = sqlite3_errcode(db); | 
| -  if( rc!=SQLITE_OK ){ | 
| -    goto opendb_out; | 
| +  if( rc==SQLITE_OK ){ | 
| +    sqlite3AutoLoadExtensions(db); | 
| +    rc = sqlite3_errcode(db); | 
| +    if( rc!=SQLITE_OK ){ | 
| +      goto opendb_out; | 
| +    } | 
| } | 
|  | 
| #ifdef SQLITE_ENABLE_FTS1 | 
| @@ -2016,8 +2664,6 @@ static int openDatabase( | 
| } | 
| #endif | 
|  | 
| -  sqlite3Error(db, rc, 0); | 
| - | 
| /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking | 
| ** mode.  -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking | 
| ** mode.  Doing nothing at all also makes NORMAL the default. | 
| @@ -2028,6 +2674,8 @@ static int openDatabase( | 
| SQLITE_DEFAULT_LOCKING_MODE); | 
| #endif | 
|  | 
| +  if( rc ) sqlite3Error(db, rc); | 
| + | 
| /* Enable the lookaside-malloc subsystem */ | 
| setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside, | 
| sqlite3GlobalConfig.nLookaside); | 
| @@ -2035,11 +2683,13 @@ static int openDatabase( | 
| sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT); | 
|  | 
| opendb_out: | 
| +  sqlite3_free(zOpen); | 
| if( db ){ | 
| assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 ); | 
| sqlite3_mutex_leave(db->mutex); | 
| } | 
| rc = sqlite3_errcode(db); | 
| +  assert( db!=0 || rc==SQLITE_NOMEM ); | 
| if( rc==SQLITE_NOMEM ){ | 
| sqlite3_close(db); | 
| db = 0; | 
| @@ -2047,6 +2697,13 @@ opendb_out: | 
| db->magic = SQLITE_MAGIC_SICK; | 
| } | 
| *ppDb = db; | 
| +#ifdef SQLITE_ENABLE_SQLLOG | 
| +  if( sqlite3GlobalConfig.xSqllog ){ | 
| +    /* Opening a db handle. Fourth parameter is passed 0. */ | 
| +    void *pArg = sqlite3GlobalConfig.pSqllogArg; | 
| +    sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0); | 
| +  } | 
| +#endif | 
| return sqlite3ApiExit(0, rc); | 
| } | 
|  | 
| @@ -2066,7 +2723,7 @@ int sqlite3_open_v2( | 
| int flags,              /* Flags */ | 
| const char *zVfs        /* Name of VFS module to use */ | 
| ){ | 
| -  return openDatabase(filename, ppDb, flags, zVfs); | 
| +  return openDatabase(filename, ppDb, (unsigned int)flags, zVfs); | 
| } | 
|  | 
| #ifndef SQLITE_OMIT_UTF16 | 
| @@ -2120,7 +2777,7 @@ int sqlite3_create_collation( | 
| int rc; | 
| sqlite3_mutex_enter(db->mutex); | 
| assert( !db->mallocFailed ); | 
| -  rc = createCollation(db, zName, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, 0); | 
| +  rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, 0); | 
| rc = sqlite3ApiExit(db, rc); | 
| sqlite3_mutex_leave(db->mutex); | 
| return rc; | 
| @@ -2140,7 +2797,7 @@ int sqlite3_create_collation_v2( | 
| int rc; | 
| sqlite3_mutex_enter(db->mutex); | 
| assert( !db->mallocFailed ); | 
| -  rc = createCollation(db, zName, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, xDel); | 
| +  rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, xDel); | 
| rc = sqlite3ApiExit(db, rc); | 
| sqlite3_mutex_leave(db->mutex); | 
| return rc; | 
| @@ -2163,7 +2820,7 @@ int sqlite3_create_collation16( | 
| assert( !db->mallocFailed ); | 
| zName8 = sqlite3Utf16to8(db, zName, -1, SQLITE_UTF16NATIVE); | 
| if( zName8 ){ | 
| -    rc = createCollation(db, zName8, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, 0); | 
| +    rc = createCollation(db, zName8, (u8)enc, pCtx, xCompare, 0); | 
| sqlite3DbFree(db, zName8); | 
| } | 
| rc = sqlite3ApiExit(db, rc); | 
| @@ -2223,17 +2880,15 @@ int sqlite3_global_recover(void){ | 
| ** mode.  Return TRUE if it is and FALSE if not.  Autocommit mode is on | 
| ** by default.  Autocommit is disabled by a BEGIN statement and reenabled | 
| ** by the next COMMIT or ROLLBACK. | 
| -** | 
| -******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ****** | 
| */ | 
| int sqlite3_get_autocommit(sqlite3 *db){ | 
| return db->autoCommit; | 
| } | 
|  | 
| /* | 
| -** The following routines are subtitutes for constants SQLITE_CORRUPT, | 
| +** The following routines are substitutes for constants SQLITE_CORRUPT, | 
| ** SQLITE_MISUSE, SQLITE_CANTOPEN, SQLITE_IOERR and possibly other error | 
| -** constants.  They server two purposes: | 
| +** constants.  They serve two purposes: | 
| ** | 
| **   1.  Serve as a convenient place to set a breakpoint in a debugger | 
| **       to detect when version error conditions occurs. | 
| @@ -2352,7 +3007,7 @@ int sqlite3_table_column_metadata( | 
| zDataType = pCol->zType; | 
| zCollSeq = pCol->zColl; | 
| notnull = pCol->notNull!=0; | 
| -    primarykey  = pCol->isPrimKey!=0; | 
| +    primarykey  = (pCol->colFlags & COLFLAG_PRIMKEY)!=0; | 
| autoinc = pTab->iPKey==iCol && (pTab->tabFlags & TF_Autoincrement)!=0; | 
| }else{ | 
| zDataType = "INTEGER"; | 
| @@ -2381,7 +3036,7 @@ error_out: | 
| zColumnName); | 
| rc = SQLITE_ERROR; | 
| } | 
| -  sqlite3Error(db, rc, (zErrMsg?"%s":0), zErrMsg); | 
| +  sqlite3ErrorWithMsg(db, rc, (zErrMsg?"%s":0), zErrMsg); | 
| sqlite3DbFree(db, zErrMsg); | 
| rc = sqlite3ApiExit(db, rc); | 
| sqlite3_mutex_leave(db->mutex); | 
| @@ -2420,35 +3075,27 @@ int sqlite3_extended_result_codes(sqlite3 *db, int onoff){ | 
| */ | 
| int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){ | 
| int rc = SQLITE_ERROR; | 
| -  int iDb; | 
| +  Btree *pBtree; | 
| + | 
| sqlite3_mutex_enter(db->mutex); | 
| -  if( zDbName==0 ){ | 
| -    iDb = 0; | 
| -  }else{ | 
| -    for(iDb=0; iDb<db->nDb; iDb++){ | 
| -      if( strcmp(db->aDb[iDb].zName, zDbName)==0 ) break; | 
| -    } | 
| -  } | 
| -  if( iDb<db->nDb ){ | 
| -    Btree *pBtree = db->aDb[iDb].pBt; | 
| -    if( pBtree ){ | 
| -      Pager *pPager; | 
| -      sqlite3_file *fd; | 
| -      sqlite3BtreeEnter(pBtree); | 
| -      pPager = sqlite3BtreePager(pBtree); | 
| -      assert( pPager!=0 ); | 
| -      fd = sqlite3PagerFile(pPager); | 
| -      assert( fd!=0 ); | 
| -      if( op==SQLITE_FCNTL_FILE_POINTER ){ | 
| -        *(sqlite3_file**)pArg = fd; | 
| -        rc = SQLITE_OK; | 
| -      }else if( fd->pMethods ){ | 
| -        rc = sqlite3OsFileControl(fd, op, pArg); | 
| -      }else{ | 
| -        rc = SQLITE_NOTFOUND; | 
| -      } | 
| -      sqlite3BtreeLeave(pBtree); | 
| +  pBtree = sqlite3DbNameToBtree(db, zDbName); | 
| +  if( pBtree ){ | 
| +    Pager *pPager; | 
| +    sqlite3_file *fd; | 
| +    sqlite3BtreeEnter(pBtree); | 
| +    pPager = sqlite3BtreePager(pBtree); | 
| +    assert( pPager!=0 ); | 
| +    fd = sqlite3PagerFile(pPager); | 
| +    assert( fd!=0 ); | 
| +    if( op==SQLITE_FCNTL_FILE_POINTER ){ | 
| +      *(sqlite3_file**)pArg = fd; | 
| +      rc = SQLITE_OK; | 
| +    }else if( fd->pMethods ){ | 
| +      rc = sqlite3OsFileControl(fd, op, pArg); | 
| +    }else{ | 
| +      rc = SQLITE_NOTFOUND; | 
| } | 
| +    sqlite3BtreeLeave(pBtree); | 
| } | 
| sqlite3_mutex_leave(db->mutex); | 
| return rc; | 
| @@ -2488,7 +3135,7 @@ int sqlite3_test_control(int op, ...){ | 
| ** to the xRandomness method of the default VFS. | 
| */ | 
| case SQLITE_TESTCTRL_PRNG_RESET: { | 
| -      sqlite3PrngResetState(); | 
| +      sqlite3_randomness(0,0); | 
| break; | 
| } | 
|  | 
| @@ -2508,6 +3155,28 @@ int sqlite3_test_control(int op, ...){ | 
| } | 
|  | 
| /* | 
| +    **  sqlite3_test_control(FAULT_INSTALL, xCallback) | 
| +    ** | 
| +    ** Arrange to invoke xCallback() whenever sqlite3FaultSim() is called, | 
| +    ** if xCallback is not NULL. | 
| +    ** | 
| +    ** As a test of the fault simulator mechanism itself, sqlite3FaultSim(0) | 
| +    ** is called immediately after installing the new callback and the return | 
| +    ** value from sqlite3FaultSim(0) becomes the return from | 
| +    ** sqlite3_test_control(). | 
| +    */ | 
| +    case SQLITE_TESTCTRL_FAULT_INSTALL: { | 
| +      /* MSVC is picky about pulling func ptrs from va lists. | 
| +      ** http://support.microsoft.com/kb/47961 | 
| +      ** sqlite3GlobalConfig.xTestCallback = va_arg(ap, int(*)(int)); | 
| +      */ | 
| +      typedef int(*TESTCALLBACKFUNC_t)(int); | 
| +      sqlite3GlobalConfig.xTestCallback = va_arg(ap, TESTCALLBACKFUNC_t); | 
| +      rc = sqlite3FaultSim(0); | 
| +      break; | 
| +    } | 
| + | 
| +    /* | 
| **  sqlite3_test_control(BENIGN_MALLOC_HOOKS, xBegin, xEnd) | 
| ** | 
| ** Register hooks to call to indicate which malloc() failures | 
| @@ -2533,7 +3202,7 @@ int sqlite3_test_control(int op, ...){ | 
| ** IMPORTANT:  Changing the PENDING byte from 0x40000000 results in | 
| ** an incompatible database file format.  Changing the PENDING byte | 
| ** while any database connection is open results in undefined and | 
| -    ** dileterious behavior. | 
| +    ** deleterious behavior. | 
| */ | 
| case SQLITE_TESTCTRL_PENDING_BYTE: { | 
| rc = PENDING_BYTE; | 
| @@ -2598,6 +3267,22 @@ int sqlite3_test_control(int op, ...){ | 
| break; | 
| } | 
|  | 
| +    /* | 
| +    **   sqlite3_test_control(SQLITE_TESTCTRL_BYTEORDER); | 
| +    ** | 
| +    ** The integer returned reveals the byte-order of the computer on which | 
| +    ** SQLite is running: | 
| +    ** | 
| +    **       1     big-endian,    determined at run-time | 
| +    **      10     little-endian, determined at run-time | 
| +    **  432101     big-endian,    determined at compile-time | 
| +    **  123410     little-endian, determined at compile-time | 
| +    */ | 
| +    case SQLITE_TESTCTRL_BYTEORDER: { | 
| +      rc = SQLITE_BYTEORDER*100 + SQLITE_LITTLEENDIAN*10 + SQLITE_BIGENDIAN; | 
| +      break; | 
| +    } | 
| + | 
| /*   sqlite3_test_control(SQLITE_TESTCTRL_RESERVE, sqlite3 *db, int N) | 
| ** | 
| ** Set the nReserve size to N for the main database on the database | 
| @@ -2623,8 +3308,7 @@ int sqlite3_test_control(int op, ...){ | 
| */ | 
| case SQLITE_TESTCTRL_OPTIMIZATIONS: { | 
| sqlite3 *db = va_arg(ap, sqlite3*); | 
| -      int x = va_arg(ap,int); | 
| -      db->flags = (x & SQLITE_OptMask) | (db->flags & ~SQLITE_OptMask); | 
| +      db->dbOptFlags = (u16)(va_arg(ap, int) & 0xffff); | 
| break; | 
| } | 
|  | 
| @@ -2646,15 +3330,6 @@ int sqlite3_test_control(int op, ...){ | 
| } | 
| #endif | 
|  | 
| -    /* sqlite3_test_control(SQLITE_TESTCTRL_PGHDRSZ) | 
| -    ** | 
| -    ** Return the size of a pcache header in bytes. | 
| -    */ | 
| -    case SQLITE_TESTCTRL_PGHDRSZ: { | 
| -      rc = sizeof(PgHdr); | 
| -      break; | 
| -    } | 
| - | 
| /* sqlite3_test_control(SQLITE_TESTCTRL_SCRATCHMALLOC, sz, &pNew, pFree); | 
| ** | 
| ** Pass pFree into sqlite3ScratchFree(). | 
| @@ -2671,8 +3346,144 @@ int sqlite3_test_control(int op, ...){ | 
| break; | 
| } | 
|  | 
| +    /*   sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff); | 
| +    ** | 
| +    ** If parameter onoff is non-zero, configure the wrappers so that all | 
| +    ** subsequent calls to localtime() and variants fail. If onoff is zero, | 
| +    ** undo this setting. | 
| +    */ | 
| +    case SQLITE_TESTCTRL_LOCALTIME_FAULT: { | 
| +      sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int); | 
| +      break; | 
| +    } | 
| + | 
| +    /*   sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int); | 
| +    ** | 
| +    ** Set or clear a flag that indicates that the database file is always well- | 
| +    ** formed and never corrupt.  This flag is clear by default, indicating that | 
| +    ** database files might have arbitrary corruption.  Setting the flag during | 
| +    ** testing causes certain assert() statements in the code to be activated | 
| +    ** that demonstrat invariants on well-formed database files. | 
| +    */ | 
| +    case SQLITE_TESTCTRL_NEVER_CORRUPT: { | 
| +      sqlite3GlobalConfig.neverCorrupt = va_arg(ap, int); | 
| +      break; | 
| +    } | 
| + | 
| + | 
| +    /*   sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, xCallback, ptr); | 
| +    ** | 
| +    ** Set the VDBE coverage callback function to xCallback with context | 
| +    ** pointer ptr. | 
| +    */ | 
| +    case SQLITE_TESTCTRL_VDBE_COVERAGE: { | 
| +#ifdef SQLITE_VDBE_COVERAGE | 
| +      typedef void (*branch_callback)(void*,int,u8,u8); | 
| +      sqlite3GlobalConfig.xVdbeBranch = va_arg(ap,branch_callback); | 
| +      sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*); | 
| +#endif | 
| +      break; | 
| +    } | 
| + | 
| +    /*   sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, nMax); */ | 
| +    case SQLITE_TESTCTRL_SORTER_MMAP: { | 
| +      sqlite3 *db = va_arg(ap, sqlite3*); | 
| +      db->nMaxSorterMmap = va_arg(ap, int); | 
| +      break; | 
| +    } | 
| + | 
| +    /*   sqlite3_test_control(SQLITE_TESTCTRL_ISINIT); | 
| +    ** | 
| +    ** Return SQLITE_OK if SQLite has been initialized and SQLITE_ERROR if | 
| +    ** not. | 
| +    */ | 
| +    case SQLITE_TESTCTRL_ISINIT: { | 
| +      if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR; | 
| +      break; | 
| +    } | 
| } | 
| va_end(ap); | 
| #endif /* SQLITE_OMIT_BUILTIN_TEST */ | 
| return rc; | 
| } | 
| + | 
| +/* | 
| +** This is a utility routine, useful to VFS implementations, that checks | 
| +** to see if a database file was a URI that contained a specific query | 
| +** parameter, and if so obtains the value of the query parameter. | 
| +** | 
| +** The zFilename argument is the filename pointer passed into the xOpen() | 
| +** method of a VFS implementation.  The zParam argument is the name of the | 
| +** query parameter we seek.  This routine returns the value of the zParam | 
| +** parameter if it exists.  If the parameter does not exist, this routine | 
| +** returns a NULL pointer. | 
| +*/ | 
| +const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){ | 
| +  if( zFilename==0 ) return 0; | 
| +  zFilename += sqlite3Strlen30(zFilename) + 1; | 
| +  while( zFilename[0] ){ | 
| +    int x = strcmp(zFilename, zParam); | 
| +    zFilename += sqlite3Strlen30(zFilename) + 1; | 
| +    if( x==0 ) return zFilename; | 
| +    zFilename += sqlite3Strlen30(zFilename) + 1; | 
| +  } | 
| +  return 0; | 
| +} | 
| + | 
| +/* | 
| +** Return a boolean value for a query parameter. | 
| +*/ | 
| +int sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){ | 
| +  const char *z = sqlite3_uri_parameter(zFilename, zParam); | 
| +  bDflt = bDflt!=0; | 
| +  return z ? sqlite3GetBoolean(z, bDflt) : bDflt; | 
| +} | 
| + | 
| +/* | 
| +** Return a 64-bit integer value for a query parameter. | 
| +*/ | 
| +sqlite3_int64 sqlite3_uri_int64( | 
| +  const char *zFilename,    /* Filename as passed to xOpen */ | 
| +  const char *zParam,       /* URI parameter sought */ | 
| +  sqlite3_int64 bDflt       /* return if parameter is missing */ | 
| +){ | 
| +  const char *z = sqlite3_uri_parameter(zFilename, zParam); | 
| +  sqlite3_int64 v; | 
| +  if( z && sqlite3DecOrHexToI64(z, &v)==SQLITE_OK ){ | 
| +    bDflt = v; | 
| +  } | 
| +  return bDflt; | 
| +} | 
| + | 
| +/* | 
| +** Return the Btree pointer identified by zDbName.  Return NULL if not found. | 
| +*/ | 
| +Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){ | 
| +  int i; | 
| +  for(i=0; i<db->nDb; i++){ | 
| +    if( db->aDb[i].pBt | 
| +     && (zDbName==0 || sqlite3StrICmp(zDbName, db->aDb[i].zName)==0) | 
| +    ){ | 
| +      return db->aDb[i].pBt; | 
| +    } | 
| +  } | 
| +  return 0; | 
| +} | 
| + | 
| +/* | 
| +** Return the filename of the database associated with a database | 
| +** connection. | 
| +*/ | 
| +const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){ | 
| +  Btree *pBt = sqlite3DbNameToBtree(db, zDbName); | 
| +  return pBt ? sqlite3BtreeGetFilename(pBt) : 0; | 
| +} | 
| + | 
| +/* | 
| +** Return 1 if database is read-only or 0 if read/write.  Return -1 if | 
| +** no such database exists. | 
| +*/ | 
| +int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){ | 
| +  Btree *pBt = sqlite3DbNameToBtree(db, zDbName); | 
| +  return pBt ? sqlite3BtreeIsReadonly(pBt) : -1; | 
| +} | 
|  |