| Index: third_party/sqlite/sqlite-src-3100200/src/main.c
|
| diff --git a/third_party/sqlite/src/src/main.c b/third_party/sqlite/sqlite-src-3100200/src/main.c
|
| similarity index 84%
|
| copy from third_party/sqlite/src/src/main.c
|
| copy to third_party/sqlite/sqlite-src-3100200/src/main.c
|
| index d15ab9bba11209516be4110a6fd542906939c3bc..3be7c7795280eb21c1150d68b1fb5b96834cbb38 100644
|
| --- a/third_party/sqlite/src/src/main.c
|
| +++ b/third_party/sqlite/sqlite-src-3100200/src/main.c
|
| @@ -25,6 +25,12 @@
|
| #ifdef SQLITE_ENABLE_ICU
|
| # include "sqliteicu.h"
|
| #endif
|
| +#ifdef SQLITE_ENABLE_JSON1
|
| +int sqlite3Json1Init(sqlite3*);
|
| +#endif
|
| +#ifdef SQLITE_ENABLE_FTS5
|
| +int sqlite3Fts5Init(sqlite3*);
|
| +#endif
|
|
|
| #ifndef SQLITE_AMALGAMATION
|
| /* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant
|
| @@ -55,6 +61,18 @@ int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
|
| */
|
| int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }
|
|
|
| +/*
|
| +** When compiling the test fixture or with debugging enabled (on Win32),
|
| +** this variable being set to non-zero will cause OSTRACE macros to emit
|
| +** extra diagnostic information.
|
| +*/
|
| +#ifdef SQLITE_HAVE_OS_TRACE
|
| +# ifndef SQLITE_DEBUG_OS_TRACE
|
| +# define SQLITE_DEBUG_OS_TRACE 0
|
| +# endif
|
| + int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE;
|
| +#endif
|
| +
|
| #if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
|
| /*
|
| ** If the following function pointer is not NULL and if
|
| @@ -62,7 +80,7 @@ int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }
|
| ** I/O active are written using this function. These messages
|
| ** are intended for debugging activity only.
|
| */
|
| -void (*sqlite3IoTrace)(const char*, ...) = 0;
|
| +SQLITE_API void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...) = 0;
|
| #endif
|
|
|
| /*
|
| @@ -128,6 +146,11 @@ int sqlite3_initialize(void){
|
| }
|
| #endif
|
|
|
| + /* If the following assert() fails on some obscure processor/compiler
|
| + ** combination, the work-around is to set the correct pointer
|
| + ** size at compile-time using -DSQLITE_PTRSIZE=n compile-time option */
|
| + assert( SQLITE_PTRSIZE==sizeof(char*) );
|
| +
|
| /* If SQLite is already completely initialized, then this call
|
| ** to sqlite3_initialize() should be a no-op. But the initialization
|
| ** must be complete. So isInit must not be set until the very end
|
| @@ -197,6 +220,12 @@ int sqlite3_initialize(void){
|
| if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){
|
| FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
|
| sqlite3GlobalConfig.inProgress = 1;
|
| +#ifdef SQLITE_ENABLE_SQLLOG
|
| + {
|
| + extern void sqlite3_init_sqllog(void);
|
| + sqlite3_init_sqllog();
|
| + }
|
| +#endif
|
| memset(pHash, 0, sizeof(sqlite3GlobalFunctions));
|
| sqlite3RegisterGlobalFunctions();
|
| if( sqlite3GlobalConfig.isPCacheInit==0 ){
|
| @@ -271,6 +300,13 @@ int sqlite3_initialize(void){
|
| ** when this routine is invoked, then this routine is a harmless no-op.
|
| */
|
| int sqlite3_shutdown(void){
|
| +#ifdef SQLITE_OMIT_WSD
|
| + int rc = sqlite3_wsd_init(4096, 24);
|
| + if( rc!=SQLITE_OK ){
|
| + return rc;
|
| + }
|
| +#endif
|
| +
|
| if( sqlite3GlobalConfig.isInit ){
|
| #ifdef SQLITE_EXTRA_SHUTDOWN
|
| void SQLITE_EXTRA_SHUTDOWN(void);
|
| @@ -329,33 +365,43 @@ int sqlite3_config(int op, ...){
|
| switch( op ){
|
|
|
| /* Mutex configuration options are only available in a threadsafe
|
| - ** compile.
|
| + ** compile.
|
| */
|
| -#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0
|
| +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-54466-46756 */
|
| case SQLITE_CONFIG_SINGLETHREAD: {
|
| - /* Disable all mutexing */
|
| - sqlite3GlobalConfig.bCoreMutex = 0;
|
| - sqlite3GlobalConfig.bFullMutex = 0;
|
| + /* EVIDENCE-OF: R-02748-19096 This option sets the threading mode to
|
| + ** Single-thread. */
|
| + sqlite3GlobalConfig.bCoreMutex = 0; /* Disable mutex on core */
|
| + sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */
|
| break;
|
| }
|
| +#endif
|
| +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-20520-54086 */
|
| case SQLITE_CONFIG_MULTITHREAD: {
|
| - /* Disable mutexing of database connections */
|
| - /* Enable mutexing of core data structures */
|
| - sqlite3GlobalConfig.bCoreMutex = 1;
|
| - sqlite3GlobalConfig.bFullMutex = 0;
|
| + /* EVIDENCE-OF: R-14374-42468 This option sets the threading mode to
|
| + ** Multi-thread. */
|
| + sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */
|
| + sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */
|
| break;
|
| }
|
| +#endif
|
| +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-59593-21810 */
|
| case SQLITE_CONFIG_SERIALIZED: {
|
| - /* Enable all mutexing */
|
| - sqlite3GlobalConfig.bCoreMutex = 1;
|
| - sqlite3GlobalConfig.bFullMutex = 1;
|
| + /* EVIDENCE-OF: R-41220-51800 This option sets the threading mode to
|
| + ** Serialized. */
|
| + sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */
|
| + sqlite3GlobalConfig.bFullMutex = 1; /* Enable mutex on connections */
|
| break;
|
| }
|
| +#endif
|
| +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-63666-48755 */
|
| case SQLITE_CONFIG_MUTEX: {
|
| /* Specify an alternative mutex implementation */
|
| sqlite3GlobalConfig.mutex = *va_arg(ap, sqlite3_mutex_methods*);
|
| break;
|
| }
|
| +#endif
|
| +#if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-14450-37597 */
|
| case SQLITE_CONFIG_GETMUTEX: {
|
| /* Retrieve the current mutex implementation */
|
| *va_arg(ap, sqlite3_mutex_methods*) = sqlite3GlobalConfig.mutex;
|
| @@ -363,37 +409,62 @@ int sqlite3_config(int op, ...){
|
| }
|
| #endif
|
|
|
| -
|
| case SQLITE_CONFIG_MALLOC: {
|
| - /* Specify an alternative malloc implementation */
|
| + /* EVIDENCE-OF: R-55594-21030 The SQLITE_CONFIG_MALLOC option takes a
|
| + ** single argument which is a pointer to an instance of the
|
| + ** sqlite3_mem_methods structure. The argument specifies alternative
|
| + ** low-level memory allocation routines to be used in place of the memory
|
| + ** allocation routines built into SQLite. */
|
| sqlite3GlobalConfig.m = *va_arg(ap, sqlite3_mem_methods*);
|
| break;
|
| }
|
| case SQLITE_CONFIG_GETMALLOC: {
|
| - /* Retrieve the current malloc() implementation */
|
| + /* EVIDENCE-OF: R-51213-46414 The SQLITE_CONFIG_GETMALLOC option takes a
|
| + ** single argument which is a pointer to an instance of the
|
| + ** sqlite3_mem_methods structure. The sqlite3_mem_methods structure is
|
| + ** filled with the currently defined memory allocation routines. */
|
| if( sqlite3GlobalConfig.m.xMalloc==0 ) sqlite3MemSetDefault();
|
| *va_arg(ap, sqlite3_mem_methods*) = sqlite3GlobalConfig.m;
|
| break;
|
| }
|
| case SQLITE_CONFIG_MEMSTATUS: {
|
| - /* Enable or disable the malloc status collection */
|
| + /* EVIDENCE-OF: R-61275-35157 The SQLITE_CONFIG_MEMSTATUS option takes
|
| + ** single argument of type int, interpreted as a boolean, which enables
|
| + ** or disables the collection of memory allocation statistics. */
|
| sqlite3GlobalConfig.bMemstat = va_arg(ap, int);
|
| break;
|
| }
|
| case SQLITE_CONFIG_SCRATCH: {
|
| - /* Designate a buffer for scratch memory space */
|
| + /* EVIDENCE-OF: R-08404-60887 There are three arguments to
|
| + ** SQLITE_CONFIG_SCRATCH: A pointer an 8-byte aligned memory buffer from
|
| + ** which the scratch allocations will be drawn, the size of each scratch
|
| + ** allocation (sz), and the maximum number of scratch allocations (N). */
|
| sqlite3GlobalConfig.pScratch = va_arg(ap, void*);
|
| sqlite3GlobalConfig.szScratch = va_arg(ap, int);
|
| sqlite3GlobalConfig.nScratch = va_arg(ap, int);
|
| break;
|
| }
|
| case SQLITE_CONFIG_PAGECACHE: {
|
| - /* Designate a buffer for page cache memory space */
|
| + /* EVIDENCE-OF: R-18761-36601 There are three arguments to
|
| + ** SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned memory (pMem),
|
| + ** the size of each page cache line (sz), and the number of cache lines
|
| + ** (N). */
|
| sqlite3GlobalConfig.pPage = va_arg(ap, void*);
|
| sqlite3GlobalConfig.szPage = va_arg(ap, int);
|
| sqlite3GlobalConfig.nPage = va_arg(ap, int);
|
| break;
|
| }
|
| + case SQLITE_CONFIG_PCACHE_HDRSZ: {
|
| + /* EVIDENCE-OF: R-39100-27317 The SQLITE_CONFIG_PCACHE_HDRSZ option takes
|
| + ** a single parameter which is a pointer to an integer and writes into
|
| + ** that integer the number of extra bytes per page required for each page
|
| + ** in SQLITE_CONFIG_PAGECACHE. */
|
| + *va_arg(ap, int*) =
|
| + sqlite3HeaderSizeBtree() +
|
| + sqlite3HeaderSizePcache() +
|
| + sqlite3HeaderSizePcache1();
|
| + break;
|
| + }
|
|
|
| case SQLITE_CONFIG_PCACHE: {
|
| /* no-op */
|
| @@ -406,11 +477,18 @@ int sqlite3_config(int op, ...){
|
| }
|
|
|
| case SQLITE_CONFIG_PCACHE2: {
|
| - /* Specify an alternative page cache implementation */
|
| + /* EVIDENCE-OF: R-63325-48378 The SQLITE_CONFIG_PCACHE2 option takes a
|
| + ** single argument which is a pointer to an sqlite3_pcache_methods2
|
| + ** object. This object specifies the interface to a custom page cache
|
| + ** implementation. */
|
| sqlite3GlobalConfig.pcache2 = *va_arg(ap, sqlite3_pcache_methods2*);
|
| break;
|
| }
|
| case SQLITE_CONFIG_GETPCACHE2: {
|
| + /* EVIDENCE-OF: R-22035-46182 The SQLITE_CONFIG_GETPCACHE2 option takes a
|
| + ** single argument which is a pointer to an sqlite3_pcache_methods2
|
| + ** object. SQLite copies of the current page cache implementation into
|
| + ** that object. */
|
| if( sqlite3GlobalConfig.pcache2.xInit==0 ){
|
| sqlite3PCacheSetDefault();
|
| }
|
| @@ -418,9 +496,15 @@ int sqlite3_config(int op, ...){
|
| break;
|
| }
|
|
|
| +/* EVIDENCE-OF: R-06626-12911 The SQLITE_CONFIG_HEAP option is only
|
| +** available if SQLite is compiled with either SQLITE_ENABLE_MEMSYS3 or
|
| +** SQLITE_ENABLE_MEMSYS5 and returns SQLITE_ERROR if invoked otherwise. */
|
| #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
|
| case SQLITE_CONFIG_HEAP: {
|
| - /* Designate a buffer for heap memory space */
|
| + /* EVIDENCE-OF: R-19854-42126 There are three arguments to
|
| + ** SQLITE_CONFIG_HEAP: An 8-byte aligned pointer to the memory, the
|
| + ** number of bytes in the memory buffer, and the minimum allocation size.
|
| + */
|
| sqlite3GlobalConfig.pHeap = va_arg(ap, void*);
|
| sqlite3GlobalConfig.nHeap = va_arg(ap, int);
|
| sqlite3GlobalConfig.mnReq = va_arg(ap, int);
|
| @@ -433,17 +517,19 @@ int sqlite3_config(int op, ...){
|
| }
|
|
|
| if( sqlite3GlobalConfig.pHeap==0 ){
|
| - /* If the heap pointer is NULL, then restore the malloc implementation
|
| - ** back to NULL pointers too. This will cause the malloc to go
|
| - ** back to its default implementation when sqlite3_initialize() is
|
| - ** run.
|
| + /* EVIDENCE-OF: R-49920-60189 If the first pointer (the memory pointer)
|
| + ** is NULL, then SQLite reverts to using its default memory allocator
|
| + ** (the system malloc() implementation), undoing any prior invocation of
|
| + ** SQLITE_CONFIG_MALLOC.
|
| + **
|
| + ** Setting sqlite3GlobalConfig.m to all zeros will cause malloc to
|
| + ** revert to its default implementation when sqlite3_initialize() is run
|
| */
|
| memset(&sqlite3GlobalConfig.m, 0, sizeof(sqlite3GlobalConfig.m));
|
| }else{
|
| - /* The heap pointer is not NULL, then install one of the
|
| - ** mem5.c/mem3.c methods. The enclosing #if guarantees at
|
| - ** least one of these methods is currently enabled.
|
| - */
|
| + /* EVIDENCE-OF: R-61006-08918 If the memory pointer is not NULL then the
|
| + ** alternative memory allocator is engaged to handle all of SQLites
|
| + ** memory allocation needs. */
|
| #ifdef SQLITE_ENABLE_MEMSYS3
|
| sqlite3GlobalConfig.m = *sqlite3MemGetMemsys3();
|
| #endif
|
| @@ -482,11 +568,19 @@ int sqlite3_config(int op, ...){
|
| ** sqlite3_config(SQLITE_CONFIG_URI,0) configuration calls.
|
| */
|
| case SQLITE_CONFIG_URI: {
|
| + /* EVIDENCE-OF: R-25451-61125 The SQLITE_CONFIG_URI option takes a single
|
| + ** argument of type int. If non-zero, then URI handling is globally
|
| + ** enabled. If the parameter is zero, then URI handling is globally
|
| + ** disabled. */
|
| sqlite3GlobalConfig.bOpenUri = va_arg(ap, int);
|
| break;
|
| }
|
|
|
| case SQLITE_CONFIG_COVERING_INDEX_SCAN: {
|
| + /* EVIDENCE-OF: R-36592-02772 The SQLITE_CONFIG_COVERING_INDEX_SCAN
|
| + ** option takes a single integer argument which is interpreted as a
|
| + ** boolean in order to enable or disable the use of covering indices for
|
| + ** full table scans in the query optimizer. */
|
| sqlite3GlobalConfig.bUseCis = va_arg(ap, int);
|
| break;
|
| }
|
| @@ -501,25 +595,45 @@ int sqlite3_config(int op, ...){
|
| #endif
|
|
|
| case SQLITE_CONFIG_MMAP_SIZE: {
|
| + /* EVIDENCE-OF: R-58063-38258 SQLITE_CONFIG_MMAP_SIZE takes two 64-bit
|
| + ** integer (sqlite3_int64) values that are the default mmap size limit
|
| + ** (the default setting for PRAGMA mmap_size) and the maximum allowed
|
| + ** mmap size limit. */
|
| sqlite3_int64 szMmap = va_arg(ap, sqlite3_int64);
|
| sqlite3_int64 mxMmap = va_arg(ap, sqlite3_int64);
|
| + /* EVIDENCE-OF: R-53367-43190 If either argument to this option is
|
| + ** negative, then that argument is changed to its compile-time default.
|
| + **
|
| + ** EVIDENCE-OF: R-34993-45031 The maximum allowed mmap size will be
|
| + ** silently truncated if necessary so that it does not exceed the
|
| + ** compile-time maximum mmap size set by the SQLITE_MAX_MMAP_SIZE
|
| + ** compile-time option.
|
| + */
|
| 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.mxMmap = mxMmap;
|
| sqlite3GlobalConfig.szMmap = szMmap;
|
| break;
|
| }
|
|
|
| -#if SQLITE_OS_WIN && defined(SQLITE_WIN32_MALLOC)
|
| +#if SQLITE_OS_WIN && defined(SQLITE_WIN32_MALLOC) /* IMP: R-04780-55815 */
|
| case SQLITE_CONFIG_WIN32_HEAPSIZE: {
|
| + /* EVIDENCE-OF: R-34926-03360 SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit
|
| + ** unsigned integer value that specifies the maximum size of the created
|
| + ** heap. */
|
| sqlite3GlobalConfig.nHeap = va_arg(ap, int);
|
| break;
|
| }
|
| #endif
|
|
|
| + case SQLITE_CONFIG_PMASZ: {
|
| + sqlite3GlobalConfig.szPma = va_arg(ap, unsigned int);
|
| + break;
|
| + }
|
| +
|
| default: {
|
| rc = SQLITE_ERROR;
|
| break;
|
| @@ -541,6 +655,7 @@ int sqlite3_config(int op, ...){
|
| ** the lookaside memory.
|
| */
|
| static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
|
| +#ifndef SQLITE_OMIT_LOOKASIDE
|
| void *pStart;
|
| if( db->lookaside.nOut ){
|
| return SQLITE_BUSY;
|
| @@ -591,6 +706,7 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
|
| db->lookaside.bEnabled = 0;
|
| db->lookaside.bMalloced = 0;
|
| }
|
| +#endif /* SQLITE_OMIT_LOOKASIDE */
|
| return SQLITE_OK;
|
| }
|
|
|
| @@ -598,6 +714,12 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
|
| ** Return the mutex associated with a database connection.
|
| */
|
| sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ){
|
| + (void)SQLITE_MISUSE_BKPT;
|
| + return 0;
|
| + }
|
| +#endif
|
| return db->mutex;
|
| }
|
|
|
| @@ -607,6 +729,10 @@ sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){
|
| */
|
| int sqlite3_db_release_memory(sqlite3 *db){
|
| int i;
|
| +
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
| +#endif
|
| sqlite3_mutex_enter(db->mutex);
|
| sqlite3BtreeEnterAll(db);
|
| for(i=0; i<db->nDb; i++){
|
| @@ -622,6 +748,36 @@ int sqlite3_db_release_memory(sqlite3 *db){
|
| }
|
|
|
| /*
|
| +** Flush any dirty pages in the pager-cache for any attached database
|
| +** to disk.
|
| +*/
|
| +int sqlite3_db_cacheflush(sqlite3 *db){
|
| + int i;
|
| + int rc = SQLITE_OK;
|
| + int bSeenBusy = 0;
|
| +
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
| +#endif
|
| + sqlite3_mutex_enter(db->mutex);
|
| + sqlite3BtreeEnterAll(db);
|
| + for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
|
| + Btree *pBt = db->aDb[i].pBt;
|
| + if( pBt && sqlite3BtreeIsInTrans(pBt) ){
|
| + Pager *pPager = sqlite3BtreePager(pBt);
|
| + rc = sqlite3PagerFlush(pPager);
|
| + if( rc==SQLITE_BUSY ){
|
| + bSeenBusy = 1;
|
| + rc = SQLITE_OK;
|
| + }
|
| + }
|
| + }
|
| + sqlite3BtreeLeaveAll(db);
|
| + sqlite3_mutex_leave(db->mutex);
|
| + return ((rc==SQLITE_OK && bSeenBusy) ? SQLITE_BUSY : rc);
|
| +}
|
| +
|
| +/*
|
| ** Configuration settings for an individual database connection
|
| */
|
| int sqlite3_db_config(sqlite3 *db, int op, ...){
|
| @@ -696,13 +852,20 @@ static int binCollFunc(
|
| ){
|
| int rc, n;
|
| n = nKey1<nKey2 ? nKey1 : nKey2;
|
| + /* EVIDENCE-OF: R-65033-28449 The built-in BINARY collation compares
|
| + ** strings byte by byte using the memcmp() function from the standard C
|
| + ** library. */
|
| rc = memcmp(pKey1, pKey2, n);
|
| if( rc==0 ){
|
| if( padFlag
|
| && allSpaces(((char*)pKey1)+n, nKey1-n)
|
| && allSpaces(((char*)pKey2)+n, nKey2-n)
|
| ){
|
| - /* Leave rc unchanged at 0 */
|
| + /* EVIDENCE-OF: R-31624-24737 RTRIM is like BINARY except that extra
|
| + ** spaces at the end of either string do not change the result. In other
|
| + ** words, strings will compare equal to one another as long as they
|
| + ** differ only in the number of spaces at the end.
|
| + */
|
| }else{
|
| rc = nKey1 - nKey2;
|
| }
|
| @@ -737,6 +900,12 @@ static int nocaseCollatingFunc(
|
| ** Return the ROWID of the most recent insert
|
| */
|
| sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ){
|
| + (void)SQLITE_MISUSE_BKPT;
|
| + return 0;
|
| + }
|
| +#endif
|
| return db->lastRowid;
|
| }
|
|
|
| @@ -744,6 +913,12 @@ sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){
|
| ** Return the number of changes in the most recent call to sqlite3_exec().
|
| */
|
| int sqlite3_changes(sqlite3 *db){
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ){
|
| + (void)SQLITE_MISUSE_BKPT;
|
| + return 0;
|
| + }
|
| +#endif
|
| return db->nChange;
|
| }
|
|
|
| @@ -751,6 +926,12 @@ int sqlite3_changes(sqlite3 *db){
|
| ** Return the number of changes since the database handle was opened.
|
| */
|
| int sqlite3_total_changes(sqlite3 *db){
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ){
|
| + (void)SQLITE_MISUSE_BKPT;
|
| + return 0;
|
| + }
|
| +#endif
|
| return db->nTotalChange;
|
| }
|
|
|
| @@ -794,17 +975,23 @@ static void functionDestroy(sqlite3 *db, FuncDef *p){
|
| static void disconnectAllVtab(sqlite3 *db){
|
| #ifndef SQLITE_OMIT_VIRTUALTABLE
|
| int i;
|
| + HashElem *p;
|
| 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);
|
| }
|
| }
|
| }
|
| + for(p=sqliteHashFirst(&db->aModule); p; p=sqliteHashNext(p)){
|
| + Module *pMod = (Module *)sqliteHashData(p);
|
| + if( pMod->pEpoTab ){
|
| + sqlite3VtabDisconnect(db, pMod->pEpoTab);
|
| + }
|
| + }
|
| sqlite3VtabUnlockList(db);
|
| sqlite3BtreeLeaveAll(db);
|
| #else
|
| @@ -930,16 +1117,6 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
|
| 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 ){
|
| @@ -992,6 +1169,7 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
|
| if( pMod->xDestroy ){
|
| pMod->xDestroy(pMod->pAux);
|
| }
|
| + sqlite3VtabEponymousTableClear(db, pMod);
|
| sqlite3DbFree(db, pMod);
|
| }
|
| sqlite3HashClear(&db->aModule);
|
| @@ -1080,7 +1258,7 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){
|
| ** 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)
|
| +#if defined(SQLITE_NEED_ERR_NAME)
|
| const char *sqlite3ErrName(int rc){
|
| const char *zName = 0;
|
| int i, origRc = rc;
|
| @@ -1246,7 +1424,7 @@ static int sqliteDefaultBusyCallback(
|
| void *ptr, /* Database connection */
|
| int count /* Number of times table has been busy */
|
| ){
|
| -#if SQLITE_OS_WIN || (defined(HAVE_USLEEP) && HAVE_USLEEP)
|
| +#if SQLITE_OS_WIN || HAVE_USLEEP
|
| static const u8 delays[] =
|
| { 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 };
|
| static const u8 totals[] =
|
| @@ -1309,6 +1487,9 @@ int sqlite3_busy_handler(
|
| int (*xBusy)(void*,int),
|
| void *pArg
|
| ){
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
| +#endif
|
| sqlite3_mutex_enter(db->mutex);
|
| db->busyHandler.xFunc = xBusy;
|
| db->busyHandler.pArg = pArg;
|
| @@ -1330,6 +1511,12 @@ void sqlite3_progress_handler(
|
| int (*xProgress)(void*),
|
| void *pArg
|
| ){
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ){
|
| + (void)SQLITE_MISUSE_BKPT;
|
| + return;
|
| + }
|
| +#endif
|
| sqlite3_mutex_enter(db->mutex);
|
| if( nOps>0 ){
|
| db->xProgress = xProgress;
|
| @@ -1350,6 +1537,9 @@ void sqlite3_progress_handler(
|
| ** specified number of milliseconds before returning 0.
|
| */
|
| int sqlite3_busy_timeout(sqlite3 *db, int ms){
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
| +#endif
|
| if( ms>0 ){
|
| sqlite3_busy_handler(db, sqliteDefaultBusyCallback, (void*)db);
|
| db->busyTimeout = ms;
|
| @@ -1363,6 +1553,12 @@ int sqlite3_busy_timeout(sqlite3 *db, int ms){
|
| ** Cause any pending operation to stop at its earliest opportunity.
|
| */
|
| void sqlite3_interrupt(sqlite3 *db){
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ){
|
| + (void)SQLITE_MISUSE_BKPT;
|
| + return;
|
| + }
|
| +#endif
|
| db->u1.isInterrupted = 1;
|
| }
|
|
|
| @@ -1500,6 +1696,12 @@ int sqlite3_create_function_v2(
|
| ){
|
| int rc = SQLITE_ERROR;
|
| FuncDestructor *pArg = 0;
|
| +
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ){
|
| + return SQLITE_MISUSE_BKPT;
|
| + }
|
| +#endif
|
| sqlite3_mutex_enter(db->mutex);
|
| if( xDestroy ){
|
| pArg = (FuncDestructor *)sqlite3DbMallocZero(db, sizeof(FuncDestructor));
|
| @@ -1536,6 +1738,10 @@ int sqlite3_create_function16(
|
| ){
|
| int rc;
|
| char *zFunc8;
|
| +
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) || zFunctionName==0 ) return SQLITE_MISUSE_BKPT;
|
| +#endif
|
| sqlite3_mutex_enter(db->mutex);
|
| assert( !db->mallocFailed );
|
| zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE);
|
| @@ -1567,6 +1773,12 @@ int sqlite3_overload_function(
|
| ){
|
| int nName = sqlite3Strlen30(zName);
|
| int rc = SQLITE_OK;
|
| +
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) || zName==0 || nArg<-2 ){
|
| + return SQLITE_MISUSE_BKPT;
|
| + }
|
| +#endif
|
| sqlite3_mutex_enter(db->mutex);
|
| if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
|
| rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
|
| @@ -1588,6 +1800,13 @@ int sqlite3_overload_function(
|
| */
|
| void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
|
| void *pOld;
|
| +
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ){
|
| + (void)SQLITE_MISUSE_BKPT;
|
| + return 0;
|
| + }
|
| +#endif
|
| sqlite3_mutex_enter(db->mutex);
|
| pOld = db->pTraceArg;
|
| db->xTrace = xTrace;
|
| @@ -1609,6 +1828,13 @@ void *sqlite3_profile(
|
| void *pArg
|
| ){
|
| void *pOld;
|
| +
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ){
|
| + (void)SQLITE_MISUSE_BKPT;
|
| + return 0;
|
| + }
|
| +#endif
|
| sqlite3_mutex_enter(db->mutex);
|
| pOld = db->pProfileArg;
|
| db->xProfile = xProfile;
|
| @@ -1629,6 +1855,13 @@ void *sqlite3_commit_hook(
|
| void *pArg /* Argument to the function */
|
| ){
|
| void *pOld;
|
| +
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ){
|
| + (void)SQLITE_MISUSE_BKPT;
|
| + return 0;
|
| + }
|
| +#endif
|
| sqlite3_mutex_enter(db->mutex);
|
| pOld = db->pCommitArg;
|
| db->xCommitCallback = xCallback;
|
| @@ -1647,6 +1880,13 @@ void *sqlite3_update_hook(
|
| void *pArg /* Argument to the function */
|
| ){
|
| void *pRet;
|
| +
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ){
|
| + (void)SQLITE_MISUSE_BKPT;
|
| + return 0;
|
| + }
|
| +#endif
|
| sqlite3_mutex_enter(db->mutex);
|
| pRet = db->pUpdateArg;
|
| db->xUpdateCallback = xCallback;
|
| @@ -1665,6 +1905,13 @@ void *sqlite3_rollback_hook(
|
| void *pArg /* Argument to the function */
|
| ){
|
| void *pRet;
|
| +
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ){
|
| + (void)SQLITE_MISUSE_BKPT;
|
| + return 0;
|
| + }
|
| +#endif
|
| sqlite3_mutex_enter(db->mutex);
|
| pRet = db->pRollbackArg;
|
| db->xRollbackCallback = xCallback;
|
| @@ -1711,6 +1958,9 @@ int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
|
| UNUSED_PARAMETER(db);
|
| UNUSED_PARAMETER(nFrame);
|
| #else
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
| +#endif
|
| if( nFrame>0 ){
|
| sqlite3_wal_hook(db, sqlite3WalDefaultHook, SQLITE_INT_TO_PTR(nFrame));
|
| }else{
|
| @@ -1731,6 +1981,12 @@ void *sqlite3_wal_hook(
|
| ){
|
| #ifndef SQLITE_OMIT_WAL
|
| void *pRet;
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ){
|
| + (void)SQLITE_MISUSE_BKPT;
|
| + return 0;
|
| + }
|
| +#endif
|
| sqlite3_mutex_enter(db->mutex);
|
| pRet = db->pWalArg;
|
| db->xWalCallback = xCallback;
|
| @@ -1758,14 +2014,21 @@ int sqlite3_wal_checkpoint_v2(
|
| int rc; /* Return code */
|
| int iDb = SQLITE_MAX_ATTACHED; /* sqlite3.aDb[] index of db to checkpoint */
|
|
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
| +#endif
|
| +
|
| /* Initialize the output variables to -1 in case an error occurs. */
|
| if( pnLog ) *pnLog = -1;
|
| if( pnCkpt ) *pnCkpt = -1;
|
|
|
| - assert( SQLITE_CHECKPOINT_FULL>SQLITE_CHECKPOINT_PASSIVE );
|
| - assert( SQLITE_CHECKPOINT_FULL<SQLITE_CHECKPOINT_RESTART );
|
| - assert( SQLITE_CHECKPOINT_PASSIVE+2==SQLITE_CHECKPOINT_RESTART );
|
| - if( eMode<SQLITE_CHECKPOINT_PASSIVE || eMode>SQLITE_CHECKPOINT_RESTART ){
|
| + assert( SQLITE_CHECKPOINT_PASSIVE==0 );
|
| + assert( SQLITE_CHECKPOINT_FULL==1 );
|
| + assert( SQLITE_CHECKPOINT_RESTART==2 );
|
| + assert( SQLITE_CHECKPOINT_TRUNCATE==3 );
|
| + if( eMode<SQLITE_CHECKPOINT_PASSIVE || eMode>SQLITE_CHECKPOINT_TRUNCATE ){
|
| + /* EVIDENCE-OF: R-03996-12088 The M parameter must be a valid checkpoint
|
| + ** mode: */
|
| return SQLITE_MISUSE;
|
| }
|
|
|
| @@ -1777,6 +2040,7 @@ int sqlite3_wal_checkpoint_v2(
|
| rc = SQLITE_ERROR;
|
| sqlite3ErrorWithMsg(db, SQLITE_ERROR, "unknown database: %s", zDb);
|
| }else{
|
| + db->busyHandler.nBusy = 0;
|
| rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt);
|
| sqlite3Error(db, rc);
|
| }
|
| @@ -1793,7 +2057,9 @@ int sqlite3_wal_checkpoint_v2(
|
| ** checkpointed.
|
| */
|
| int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
|
| - return sqlite3_wal_checkpoint_v2(db, zDb, SQLITE_CHECKPOINT_PASSIVE, 0, 0);
|
| + /* EVIDENCE-OF: R-41613-20553 The sqlite3_wal_checkpoint(D,X) is equivalent to
|
| + ** sqlite3_wal_checkpoint_v2(D,X,SQLITE_CHECKPOINT_PASSIVE,0,0). */
|
| + return sqlite3_wal_checkpoint_v2(db,zDb,SQLITE_CHECKPOINT_PASSIVE,0,0);
|
| }
|
|
|
| #ifndef SQLITE_OMIT_WAL
|
| @@ -1868,9 +2134,11 @@ int sqlite3TempInMemory(const sqlite3 *db){
|
| return ( db->temp_store!=1 );
|
| #endif
|
| #if SQLITE_TEMP_STORE==3
|
| + UNUSED_PARAMETER(db);
|
| return 1;
|
| #endif
|
| #if SQLITE_TEMP_STORE<1 || SQLITE_TEMP_STORE>3
|
| + UNUSED_PARAMETER(db);
|
| return 0;
|
| #endif
|
| }
|
| @@ -1981,32 +2249,6 @@ const char *sqlite3_errstr(int 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.
|
| */
|
| @@ -2049,7 +2291,6 @@ static int createCollation(
|
| 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(),
|
| @@ -2154,6 +2395,12 @@ static const int aHardLimit[] = {
|
| int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
|
| int oldLimit;
|
|
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ){
|
| + (void)SQLITE_MISUSE_BKPT;
|
| + return -1;
|
| + }
|
| +#endif
|
|
|
| /* EVIDENCE-OF: R-30189-54097 For each limit category SQLITE_LIMIT_NAME
|
| ** there is a hard upper bound set at compile-time by a C preprocessor
|
| @@ -2230,25 +2477,38 @@ int sqlite3ParseUri(
|
|
|
| assert( *pzErrMsg==0 );
|
|
|
| - if( ((flags & SQLITE_OPEN_URI) || sqlite3GlobalConfig.bOpenUri)
|
| + if( ((flags & SQLITE_OPEN_URI) /* IMP: R-48725-32206 */
|
| + || sqlite3GlobalConfig.bOpenUri) /* IMP: R-51689-46548 */
|
| && 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 */
|
| + u64 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);
|
| + zFile = sqlite3_malloc64(nByte);
|
| if( !zFile ) return SQLITE_NOMEM;
|
|
|
| iIn = 5;
|
| -#ifndef SQLITE_ALLOW_URI_AUTHORITY
|
| +#ifdef SQLITE_ALLOW_URI_AUTHORITY
|
| + if( strncmp(zUri+5, "///", 3)==0 ){
|
| + iIn = 7;
|
| + /* The following condition causes URIs with five leading / characters
|
| + ** like file://///host/path to be converted into UNCs like //host/path.
|
| + ** The correct URI for that UNC has only two or four leading / characters
|
| + ** file://host/path or file:////host/path. But 5 leading slashes is a
|
| + ** common error, we are told, so we handle it as a special case. */
|
| + if( strncmp(zUri+7, "///", 3)==0 ){ iIn++; }
|
| + }else if( strncmp(zUri+5, "//localhost/", 12)==0 ){
|
| + iIn = 16;
|
| + }
|
| +#else
|
| /* Discard the scheme and authority segments of the URI. */
|
| if( zUri[5]=='/' && zUri[6]=='/' ){
|
| iIn = 7;
|
| @@ -2398,7 +2658,7 @@ int sqlite3ParseUri(
|
| }
|
|
|
| }else{
|
| - zFile = sqlite3_malloc(nUri+2);
|
| + zFile = sqlite3_malloc64(nUri+2);
|
| if( !zFile ) return SQLITE_NOMEM;
|
| memcpy(zFile, zUri, nUri);
|
| zFile[nUri] = '\0';
|
| @@ -2439,6 +2699,9 @@ static int openDatabase(
|
| char *zOpen = 0; /* Filename argument to pass to BtreeOpen() */
|
| char *zErrMsg = 0; /* Error message from sqlite3ParseUri() */
|
|
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( ppDb==0 ) return SQLITE_MISUSE_BKPT;
|
| +#endif
|
| *ppDb = 0;
|
| #ifndef SQLITE_OMIT_AUTOINIT
|
| rc = sqlite3_initialize();
|
| @@ -2532,6 +2795,9 @@ static int openDatabase(
|
| #if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
|
| | SQLITE_AutoIndex
|
| #endif
|
| +#if SQLITE_DEFAULT_CKPTFULLFSYNC
|
| + | SQLITE_CkptFullFSync
|
| +#endif
|
| #if SQLITE_DEFAULT_FILE_FORMAT<4
|
| | SQLITE_LegacyFileFmt
|
| #endif
|
| @@ -2544,6 +2810,12 @@ static int openDatabase(
|
| #if defined(SQLITE_DEFAULT_FOREIGN_KEYS) && SQLITE_DEFAULT_FOREIGN_KEYS
|
| | SQLITE_ForeignKeys
|
| #endif
|
| +#if defined(SQLITE_REVERSE_UNORDERED_SELECTS)
|
| + | SQLITE_ReverseOrder
|
| +#endif
|
| +#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
|
| + | SQLITE_CellSizeCk
|
| +#endif
|
| ;
|
| sqlite3HashInit(&db->aCollSeq);
|
| #ifndef SQLITE_OMIT_VIRTUALTABLE
|
| @@ -2553,20 +2825,24 @@ static int openDatabase(
|
| /* 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.
|
| + **
|
| + ** EVIDENCE-OF: R-52786-44878 SQLite defines three built-in collating
|
| + ** functions:
|
| */
|
| - 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, sqlite3StrBINARY, SQLITE_UTF8, 0, binCollFunc, 0);
|
| + createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, binCollFunc, 0);
|
| + createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, binCollFunc, 0);
|
| + createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
|
| createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0);
|
| if( db->mallocFailed ){
|
| goto opendb_out;
|
| }
|
| - db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 0);
|
| + /* EVIDENCE-OF: R-08308-17224 The default collating function for all
|
| + ** strings is BINARY.
|
| + */
|
| + db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, sqlite3StrBINARY, 0);
|
| assert( db->pDfltColl!=0 );
|
|
|
| - /* Also add a UTF-8 case-insensitive collation sequence. */
|
| - createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
|
| -
|
| /* Parse the filename/URI argument. */
|
| db->openFlags = flags;
|
| rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
|
| @@ -2589,6 +2865,7 @@ static int openDatabase(
|
| }
|
| sqlite3BtreeEnter(db->aDb[0].pBt);
|
| db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt);
|
| + if( !db->mallocFailed ) ENC(db) = SCHEMA_ENC(db);
|
| sqlite3BtreeLeave(db->aDb[0].pBt);
|
| db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);
|
|
|
| @@ -2638,17 +2915,15 @@ static int openDatabase(
|
| }
|
| #endif
|
|
|
| -#ifdef SQLITE_ENABLE_FTS3
|
| +#ifdef SQLITE_ENABLE_FTS3 /* automatically defined by SQLITE_ENABLE_FTS4 */
|
| if( !db->mallocFailed && rc==SQLITE_OK ){
|
| rc = sqlite3Fts3Init(db);
|
| }
|
| #endif
|
|
|
| -#ifdef DEFAULT_ENABLE_RECOVER
|
| - /* Initialize recover virtual table for testing. */
|
| - extern int recoverVtableInit(sqlite3 *db);
|
| +#ifdef SQLITE_ENABLE_FTS5
|
| if( !db->mallocFailed && rc==SQLITE_OK ){
|
| - rc = recoverVtableInit(db);
|
| + rc = sqlite3Fts5Init(db);
|
| }
|
| #endif
|
|
|
| @@ -2664,6 +2939,18 @@ static int openDatabase(
|
| }
|
| #endif
|
|
|
| +#ifdef SQLITE_ENABLE_DBSTAT_VTAB
|
| + if( !db->mallocFailed && rc==SQLITE_OK){
|
| + rc = sqlite3DbstatRegister(db);
|
| + }
|
| +#endif
|
| +
|
| +#ifdef SQLITE_ENABLE_JSON1
|
| + if( !db->mallocFailed && rc==SQLITE_OK){
|
| + rc = sqlite3Json1Init(db);
|
| + }
|
| +#endif
|
| +
|
| /* -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.
|
| @@ -2683,9 +2970,9 @@ 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 );
|
| + assert( db->mutex!=0 || isThreadsafe==0
|
| + || sqlite3GlobalConfig.bFullMutex==0 );
|
| sqlite3_mutex_leave(db->mutex);
|
| }
|
| rc = sqlite3_errcode(db);
|
| @@ -2704,7 +2991,23 @@ opendb_out:
|
| sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
|
| }
|
| #endif
|
| - return sqlite3ApiExit(0, rc);
|
| +#if defined(SQLITE_HAS_CODEC)
|
| + if( rc==SQLITE_OK ){
|
| + const char *zHexKey = sqlite3_uri_parameter(zOpen, "hexkey");
|
| + if( zHexKey && zHexKey[0] ){
|
| + u8 iByte;
|
| + int i;
|
| + char zKey[40];
|
| + for(i=0, iByte=0; i<sizeof(zKey)*2 && sqlite3Isxdigit(zHexKey[i]); i++){
|
| + iByte = (iByte<<4) + sqlite3HexToInt(zHexKey[i]);
|
| + if( (i&1)!=0 ) zKey[i/2] = iByte;
|
| + }
|
| + sqlite3_key_v2(db, 0, zKey, i/2);
|
| + }
|
| + }
|
| +#endif
|
| + sqlite3_free(zOpen);
|
| + return rc & 0xff;
|
| }
|
|
|
| /*
|
| @@ -2738,13 +3041,15 @@ int sqlite3_open16(
|
| sqlite3_value *pVal;
|
| int rc;
|
|
|
| - assert( zFilename );
|
| - assert( ppDb );
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( ppDb==0 ) return SQLITE_MISUSE_BKPT;
|
| +#endif
|
| *ppDb = 0;
|
| #ifndef SQLITE_OMIT_AUTOINIT
|
| rc = sqlite3_initialize();
|
| if( rc ) return rc;
|
| #endif
|
| + if( zFilename==0 ) zFilename = "\000\000";
|
| pVal = sqlite3ValueNew(0);
|
| sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC);
|
| zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8);
|
| @@ -2753,14 +3058,14 @@ int sqlite3_open16(
|
| SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
|
| assert( *ppDb || rc==SQLITE_NOMEM );
|
| if( rc==SQLITE_OK && !DbHasProperty(*ppDb, 0, DB_SchemaLoaded) ){
|
| - ENC(*ppDb) = SQLITE_UTF16NATIVE;
|
| + SCHEMA_ENC(*ppDb) = ENC(*ppDb) = SQLITE_UTF16NATIVE;
|
| }
|
| }else{
|
| rc = SQLITE_NOMEM;
|
| }
|
| sqlite3ValueFree(pVal);
|
|
|
| - return sqlite3ApiExit(0, rc);
|
| + return rc & 0xff;
|
| }
|
| #endif /* SQLITE_OMIT_UTF16 */
|
|
|
| @@ -2774,13 +3079,7 @@ int sqlite3_create_collation(
|
| void* pCtx,
|
| int(*xCompare)(void*,int,const void*,int,const void*)
|
| ){
|
| - int rc;
|
| - sqlite3_mutex_enter(db->mutex);
|
| - assert( !db->mallocFailed );
|
| - rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, 0);
|
| - rc = sqlite3ApiExit(db, rc);
|
| - sqlite3_mutex_leave(db->mutex);
|
| - return rc;
|
| + return sqlite3_create_collation_v2(db, zName, enc, pCtx, xCompare, 0);
|
| }
|
|
|
| /*
|
| @@ -2795,6 +3094,10 @@ int sqlite3_create_collation_v2(
|
| void(*xDel)(void*)
|
| ){
|
| int rc;
|
| +
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
|
| +#endif
|
| sqlite3_mutex_enter(db->mutex);
|
| assert( !db->mallocFailed );
|
| rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, xDel);
|
| @@ -2816,6 +3119,10 @@ int sqlite3_create_collation16(
|
| ){
|
| int rc = SQLITE_OK;
|
| char *zName8;
|
| +
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
|
| +#endif
|
| sqlite3_mutex_enter(db->mutex);
|
| assert( !db->mallocFailed );
|
| zName8 = sqlite3Utf16to8(db, zName, -1, SQLITE_UTF16NATIVE);
|
| @@ -2838,6 +3145,9 @@ int sqlite3_collation_needed(
|
| void *pCollNeededArg,
|
| void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*)
|
| ){
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
| +#endif
|
| sqlite3_mutex_enter(db->mutex);
|
| db->xCollNeeded = xCollNeeded;
|
| db->xCollNeeded16 = 0;
|
| @@ -2856,6 +3166,9 @@ int sqlite3_collation_needed16(
|
| void *pCollNeededArg,
|
| void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*)
|
| ){
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
| +#endif
|
| sqlite3_mutex_enter(db->mutex);
|
| db->xCollNeeded = 0;
|
| db->xCollNeeded16 = xCollNeeded16;
|
| @@ -2882,6 +3195,12 @@ int sqlite3_global_recover(void){
|
| ** by the next COMMIT or ROLLBACK.
|
| */
|
| int sqlite3_get_autocommit(sqlite3 *db){
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ){
|
| + (void)SQLITE_MISUSE_BKPT;
|
| + return 0;
|
| + }
|
| +#endif
|
| return db->autoCommit;
|
| }
|
|
|
| @@ -2935,7 +3254,6 @@ void sqlite3_thread_cleanup(void){
|
| ** Return meta information about a specific column of a database table.
|
| ** See comment in sqlite3.h (sqlite.h.in) for details.
|
| */
|
| -#ifdef SQLITE_ENABLE_COLUMN_METADATA
|
| int sqlite3_table_column_metadata(
|
| sqlite3 *db, /* Connection handle */
|
| const char *zDbName, /* Database name or NULL */
|
| @@ -2951,14 +3269,20 @@ int sqlite3_table_column_metadata(
|
| char *zErrMsg = 0;
|
| Table *pTab = 0;
|
| Column *pCol = 0;
|
| - int iCol;
|
| -
|
| + int iCol = 0;
|
| char const *zDataType = 0;
|
| char const *zCollSeq = 0;
|
| int notnull = 0;
|
| int primarykey = 0;
|
| int autoinc = 0;
|
|
|
| +
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) || zTableName==0 ){
|
| + return SQLITE_MISUSE_BKPT;
|
| + }
|
| +#endif
|
| +
|
| /* Ensure the database schema has been loaded */
|
| sqlite3_mutex_enter(db->mutex);
|
| sqlite3BtreeEnterAll(db);
|
| @@ -2975,11 +3299,8 @@ int sqlite3_table_column_metadata(
|
| }
|
|
|
| /* Find the column for which info is requested */
|
| - if( sqlite3IsRowid(zColumnName) ){
|
| - iCol = pTab->iPKey;
|
| - if( iCol>=0 ){
|
| - pCol = &pTab->aCol[iCol];
|
| - }
|
| + if( zColumnName==0 ){
|
| + /* Query for existance of table only */
|
| }else{
|
| for(iCol=0; iCol<pTab->nCol; iCol++){
|
| pCol = &pTab->aCol[iCol];
|
| @@ -2988,8 +3309,13 @@ int sqlite3_table_column_metadata(
|
| }
|
| }
|
| if( iCol==pTab->nCol ){
|
| - pTab = 0;
|
| - goto error_out;
|
| + if( HasRowid(pTab) && sqlite3IsRowid(zColumnName) ){
|
| + iCol = pTab->iPKey;
|
| + pCol = iCol>=0 ? &pTab->aCol[iCol] : 0;
|
| + }else{
|
| + pTab = 0;
|
| + goto error_out;
|
| + }
|
| }
|
| }
|
|
|
| @@ -3014,7 +3340,7 @@ int sqlite3_table_column_metadata(
|
| primarykey = 1;
|
| }
|
| if( !zCollSeq ){
|
| - zCollSeq = "BINARY";
|
| + zCollSeq = sqlite3StrBINARY;
|
| }
|
|
|
| error_out:
|
| @@ -3042,7 +3368,6 @@ error_out:
|
| sqlite3_mutex_leave(db->mutex);
|
| return rc;
|
| }
|
| -#endif
|
|
|
| /*
|
| ** Sleep for a little while. Return the amount of time slept.
|
| @@ -3064,6 +3389,9 @@ int sqlite3_sleep(int ms){
|
| ** Enable or disable the extended result codes.
|
| */
|
| int sqlite3_extended_result_codes(sqlite3 *db, int onoff){
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
| +#endif
|
| sqlite3_mutex_enter(db->mutex);
|
| db->errMask = onoff ? 0xffffffff : 0xff;
|
| sqlite3_mutex_leave(db->mutex);
|
| @@ -3077,6 +3405,9 @@ int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
|
| int rc = SQLITE_ERROR;
|
| Btree *pBtree;
|
|
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
| +#endif
|
| sqlite3_mutex_enter(db->mutex);
|
| pBtree = sqlite3DbNameToBtree(db, zDbName);
|
| if( pBtree ){
|
| @@ -3090,6 +3421,12 @@ int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
|
| if( op==SQLITE_FCNTL_FILE_POINTER ){
|
| *(sqlite3_file**)pArg = fd;
|
| rc = SQLITE_OK;
|
| + }else if( op==SQLITE_FCNTL_VFS_POINTER ){
|
| + *(sqlite3_vfs**)pArg = sqlite3PagerVfs(pPager);
|
| + rc = SQLITE_OK;
|
| + }else if( op==SQLITE_FCNTL_JOURNAL_POINTER ){
|
| + *(sqlite3_file**)pArg = sqlite3PagerJrnlFile(pPager);
|
| + rc = SQLITE_OK;
|
| }else if( fd->pMethods ){
|
| rc = sqlite3OsFileControl(fd, op, pArg);
|
| }else{
|
| @@ -3098,7 +3435,7 @@ int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
|
| sqlite3BtreeLeave(pBtree);
|
| }
|
| sqlite3_mutex_leave(db->mutex);
|
| - return rc;
|
| + return rc;
|
| }
|
|
|
| /*
|
| @@ -3106,7 +3443,9 @@ int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
|
| */
|
| int sqlite3_test_control(int op, ...){
|
| int rc = 0;
|
| -#ifndef SQLITE_OMIT_BUILTIN_TEST
|
| +#ifdef SQLITE_OMIT_BUILTIN_TEST
|
| + UNUSED_PARAMETER(op);
|
| +#else
|
| va_list ap;
|
| va_start(ap, op);
|
| switch( op ){
|
| @@ -3401,6 +3740,35 @@ int sqlite3_test_control(int op, ...){
|
| if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR;
|
| break;
|
| }
|
| +
|
| + /* sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, dbName, onOff, tnum);
|
| + **
|
| + ** This test control is used to create imposter tables. "db" is a pointer
|
| + ** to the database connection. dbName is the database name (ex: "main" or
|
| + ** "temp") which will receive the imposter. "onOff" turns imposter mode on
|
| + ** or off. "tnum" is the root page of the b-tree to which the imposter
|
| + ** table should connect.
|
| + **
|
| + ** Enable imposter mode only when the schema has already been parsed. Then
|
| + ** run a single CREATE TABLE statement to construct the imposter table in
|
| + ** the parsed schema. Then turn imposter mode back off again.
|
| + **
|
| + ** If onOff==0 and tnum>0 then reset the schema for all databases, causing
|
| + ** the schema to be reparsed the next time it is needed. This has the
|
| + ** effect of erasing all imposter tables.
|
| + */
|
| + case SQLITE_TESTCTRL_IMPOSTER: {
|
| + sqlite3 *db = va_arg(ap, sqlite3*);
|
| + sqlite3_mutex_enter(db->mutex);
|
| + db->init.iDb = sqlite3FindDbName(db, va_arg(ap,const char*));
|
| + db->init.busy = db->init.imposterTable = va_arg(ap,int);
|
| + db->init.newTnum = va_arg(ap,int);
|
| + if( db->init.busy==0 && db->init.newTnum>0 ){
|
| + sqlite3ResetAllSchemasOfConnection(db);
|
| + }
|
| + sqlite3_mutex_leave(db->mutex);
|
| + break;
|
| + }
|
| }
|
| va_end(ap);
|
| #endif /* SQLITE_OMIT_BUILTIN_TEST */
|
| @@ -3419,7 +3787,7 @@ int sqlite3_test_control(int op, ...){
|
| ** returns a NULL pointer.
|
| */
|
| const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){
|
| - if( zFilename==0 ) return 0;
|
| + if( zFilename==0 || zParam==0 ) return 0;
|
| zFilename += sqlite3Strlen30(zFilename) + 1;
|
| while( zFilename[0] ){
|
| int x = strcmp(zFilename, zParam);
|
| @@ -3475,7 +3843,14 @@ Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){
|
| ** connection.
|
| */
|
| const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){
|
| - Btree *pBt = sqlite3DbNameToBtree(db, zDbName);
|
| + Btree *pBt;
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ){
|
| + (void)SQLITE_MISUSE_BKPT;
|
| + return 0;
|
| + }
|
| +#endif
|
| + pBt = sqlite3DbNameToBtree(db, zDbName);
|
| return pBt ? sqlite3BtreeGetFilename(pBt) : 0;
|
| }
|
|
|
| @@ -3484,6 +3859,95 @@ const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){
|
| ** no such database exists.
|
| */
|
| int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
|
| - Btree *pBt = sqlite3DbNameToBtree(db, zDbName);
|
| + Btree *pBt;
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ){
|
| + (void)SQLITE_MISUSE_BKPT;
|
| + return -1;
|
| + }
|
| +#endif
|
| + pBt = sqlite3DbNameToBtree(db, zDbName);
|
| return pBt ? sqlite3BtreeIsReadonly(pBt) : -1;
|
| }
|
| +
|
| +#ifdef SQLITE_ENABLE_SNAPSHOT
|
| +/*
|
| +** Obtain a snapshot handle for the snapshot of database zDb currently
|
| +** being read by handle db.
|
| +*/
|
| +int sqlite3_snapshot_get(
|
| + sqlite3 *db,
|
| + const char *zDb,
|
| + sqlite3_snapshot **ppSnapshot
|
| +){
|
| + int rc = SQLITE_ERROR;
|
| +#ifndef SQLITE_OMIT_WAL
|
| + int iDb;
|
| +
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ){
|
| + return SQLITE_MISUSE_BKPT;
|
| + }
|
| +#endif
|
| + sqlite3_mutex_enter(db->mutex);
|
| +
|
| + iDb = sqlite3FindDbName(db, zDb);
|
| + if( iDb==0 || iDb>1 ){
|
| + Btree *pBt = db->aDb[iDb].pBt;
|
| + if( 0==sqlite3BtreeIsInTrans(pBt) ){
|
| + rc = sqlite3BtreeBeginTrans(pBt, 0);
|
| + if( rc==SQLITE_OK ){
|
| + rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot);
|
| + }
|
| + }
|
| + }
|
| +
|
| + sqlite3_mutex_leave(db->mutex);
|
| +#endif /* SQLITE_OMIT_WAL */
|
| + return rc;
|
| +}
|
| +
|
| +/*
|
| +** Open a read-transaction on the snapshot idendified by pSnapshot.
|
| +*/
|
| +int sqlite3_snapshot_open(
|
| + sqlite3 *db,
|
| + const char *zDb,
|
| + sqlite3_snapshot *pSnapshot
|
| +){
|
| + int rc = SQLITE_ERROR;
|
| +#ifndef SQLITE_OMIT_WAL
|
| +
|
| +#ifdef SQLITE_ENABLE_API_ARMOR
|
| + if( !sqlite3SafetyCheckOk(db) ){
|
| + return SQLITE_MISUSE_BKPT;
|
| + }
|
| +#endif
|
| + sqlite3_mutex_enter(db->mutex);
|
| + if( db->autoCommit==0 ){
|
| + int iDb;
|
| + iDb = sqlite3FindDbName(db, zDb);
|
| + if( iDb==0 || iDb>1 ){
|
| + Btree *pBt = db->aDb[iDb].pBt;
|
| + if( 0==sqlite3BtreeIsInReadTrans(pBt) ){
|
| + rc = sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), pSnapshot);
|
| + if( rc==SQLITE_OK ){
|
| + rc = sqlite3BtreeBeginTrans(pBt, 0);
|
| + sqlite3PagerSnapshotOpen(sqlite3BtreePager(pBt), 0);
|
| + }
|
| + }
|
| + }
|
| + }
|
| +
|
| + sqlite3_mutex_leave(db->mutex);
|
| +#endif /* SQLITE_OMIT_WAL */
|
| + return rc;
|
| +}
|
| +
|
| +/*
|
| +** Free a snapshot handle obtained from sqlite3_snapshot_get().
|
| +*/
|
| +void sqlite3_snapshot_free(sqlite3_snapshot *pSnapshot){
|
| + sqlite3_free(pSnapshot);
|
| +}
|
| +#endif /* SQLITE_ENABLE_SNAPSHOT */
|
|
|