[libgda] Upgraded to Sqlite 3.8.10.2 & SqlCipher 3.3.1



commit dde55cf1b965e291d007015094e95d1187641898
Author: Vivien Malerba <malerba gnome-db org>
Date:   Wed Mar 9 17:33:52 2016 +0100

    Upgraded to Sqlite 3.8.10.2 & SqlCipher 3.3.1

 libgda/sqlite/sqlite-src/PragmasPatch |    8 +-
 libgda/sqlite/sqlite-src/sqlite3.c    |20454 ++++++++++++------
 libgda/sqlite/sqlite-src/sqlite3.h    | 1607 +-
 providers/sqlcipher/sqlcipher.patch   |39053 ++++++++++++++++++++++++++++++---
 4 files changed, 51095 insertions(+), 10027 deletions(-)
---
diff --git a/libgda/sqlite/sqlite-src/PragmasPatch b/libgda/sqlite/sqlite-src/PragmasPatch
index f5e88df..9f6cfbe 100644
--- a/libgda/sqlite/sqlite-src/PragmasPatch
+++ b/libgda/sqlite/sqlite-src/PragmasPatch
@@ -1,6 +1,6 @@
---- sqlite3.c.orig     2014-11-08 15:04:07.918458139 +0100
-+++ sqlite3.c  2014-11-08 15:04:12.087540578 +0100
-@@ -98888,6 +98888,24 @@
+--- sqlite3.c.orig     2016-03-09 15:37:00.631202362 +0100
++++ sqlite3.c  2016-03-09 15:37:05.456314760 +0100
+@@ -103838,6 +103838,24 @@
    return azModeName[eMode];
  }
  
@@ -25,7 +25,7 @@
  /*
  ** Process a pragma statement.  
  **
-@@ -99614,6 +99632,54 @@
+@@ -104584,6 +104602,54 @@
  
  #ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
    /*
diff --git a/libgda/sqlite/sqlite-src/sqlite3.c b/libgda/sqlite/sqlite-src/sqlite3.c
index db49726..c974749 100644
--- a/libgda/sqlite/sqlite-src/sqlite3.c
+++ b/libgda/sqlite/sqlite-src/sqlite3.c
@@ -1,6 +1,6 @@
 /******************************************************************************
 ** This file is an amalgamation of many separate C source files from SQLite
-** version 3.8.6.  By combining all the individual C code files into this 
+** version 3.8.10.2.  By combining all the individual C code files into this 
 ** single large file, the entire code can be compiled as a single translation
 ** unit.  This allows many compilers to do optimizations that would not be
 ** possible if the files were compiled separately.  Performance improvements
@@ -22,9 +22,6 @@
 #ifndef SQLITE_PRIVATE
 # define SQLITE_PRIVATE static
 #endif
-#ifndef SQLITE_API
-# define SQLITE_API
-#endif
 /************** Begin file sqliteInt.h ***************************************/
 /*
 ** 2001 September 15
@@ -44,6 +41,92 @@
 #define _SQLITEINT_H_
 
 /*
+** Include the header file used to customize the compiler options for MSVC.
+** This should be done first so that it can successfully prevent spurious
+** compiler warnings due to subsequent content in this file and other files
+** that are included by this file.
+*/
+/************** Include msvc.h in the middle of sqliteInt.h ******************/
+/************** Begin file msvc.h ********************************************/
+/*
+** 2015 January 12
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+******************************************************************************
+**
+** This file contains code that is specific to MSVC.
+*/
+#ifndef _MSVC_H_
+#define _MSVC_H_
+
+#if defined(_MSC_VER)
+#pragma warning(disable : 4054)
+#pragma warning(disable : 4055)
+#pragma warning(disable : 4100)
+#pragma warning(disable : 4127)
+#pragma warning(disable : 4130)
+#pragma warning(disable : 4152)
+#pragma warning(disable : 4189)
+#pragma warning(disable : 4206)
+#pragma warning(disable : 4210)
+#pragma warning(disable : 4232)
+#pragma warning(disable : 4244)
+#pragma warning(disable : 4305)
+#pragma warning(disable : 4306)
+#pragma warning(disable : 4702)
+#pragma warning(disable : 4706)
+#endif /* defined(_MSC_VER) */
+
+#endif /* _MSVC_H_ */
+
+/************** End of msvc.h ************************************************/
+/************** Continuing where we left off in sqliteInt.h ******************/
+
+/*
+** Special setup for VxWorks
+*/
+/************** Include vxworks.h in the middle of sqliteInt.h ***************/
+/************** Begin file vxworks.h *****************************************/
+/*
+** 2015-03-02
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+******************************************************************************
+**
+** This file contains code that is specific to Wind River's VxWorks
+*/
+#if defined(__RTP__) || defined(_WRS_KERNEL)
+/* This is VxWorks.  Set up things specially for that OS
+*/
+#include <vxWorks.h>
+#include <pthread.h>  /* amalgamator: dontcache */
+#define OS_VXWORKS 1
+#define SQLITE_OS_OTHER 0
+#define SQLITE_HOMEGROWN_RECURSIVE_MUTEX 1
+#define SQLITE_OMIT_LOAD_EXTENSION 1
+#define SQLITE_ENABLE_LOCKING_STYLE 0
+#define HAVE_UTIME 1
+#else
+/* This is not VxWorks. */
+#define OS_VXWORKS 0
+#endif /* defined(_WRS_KERNEL) */
+
+/************** End of vxworks.h *********************************************/
+/************** Continuing where we left off in sqliteInt.h ******************/
+
+/*
 ** These #defines should enable >2GB file support on POSIX if the
 ** underlying operating system supports it.  If the OS lacks
 ** large file support, or if the OS is windows, these should be no-ops.
@@ -75,6 +158,15 @@
 # define _LARGEFILE_SOURCE 1
 #endif
 
+/* Needed for various definitions... */
+#if defined(__GNUC__) && !defined(_GNU_SOURCE)
+# define _GNU_SOURCE
+#endif
+
+#if defined(__OpenBSD__) && !defined(_BSD_SOURCE)
+# define _BSD_SOURCE
+#endif
+
 /*
 ** For MinGW, check to see if we can include the header file containing its
 ** version information, among other things.  Normally, this internal MinGW
@@ -158,21 +250,25 @@ extern "C" {
 
 
 /*
-** Add the ability to override 'extern'
+** Provide the ability to override linkage features of the interface.
 */
 #ifndef SQLITE_EXTERN
 # define SQLITE_EXTERN extern
 #endif
-
 #ifndef SQLITE_API
 # define SQLITE_API
 #endif
-
+#ifndef SQLITE_CDECL
+# define SQLITE_CDECL
+#endif
+#ifndef SQLITE_STDCALL
+# define SQLITE_STDCALL
+#endif
 
 /*
 ** These no-op macros are used in front of interfaces to mark those
 ** interfaces as either deprecated or experimental.  New applications
-** should not use deprecated interfaces - they are support for backwards
+** should not use deprecated interfaces - they are supported for backwards
 ** compatibility only.  Application writers should be aware that
 ** experimental interfaces are subject to change in point releases.
 **
@@ -222,9 +318,9 @@ extern "C" {
 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
 ** [sqlite_version()] and [sqlite_source_id()].
 */
-#define SQLITE_VERSION        "3.8.6"
-#define SQLITE_VERSION_NUMBER 3008006
-#define SQLITE_SOURCE_ID      "2014-08-15 11:46:33 9491ba7d738528f168657adb43a198238abde19e"
+#define SQLITE_VERSION        "3.8.10.2"
+#define SQLITE_VERSION_NUMBER 3008010
+#define SQLITE_SOURCE_ID      "2015-05-20 18:17:19 2ef4f3a5b1d1d0c4338f8243d40a2452cc1f7fe4"
 
 /*
 ** CAPI3REF: Run-Time Library Version Numbers
@@ -257,9 +353,9 @@ extern "C" {
 ** See also: [sqlite_version()] and [sqlite_source_id()].
 */
 SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
-SQLITE_API const char *sqlite3_libversion(void);
-SQLITE_API const char *sqlite3_sourceid(void);
-SQLITE_API int sqlite3_libversion_number(void);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_libversion(void);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_sourceid(void);
+SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void);
 
 /*
 ** CAPI3REF: Run-Time Library Compilation Options Diagnostics
@@ -284,8 +380,8 @@ SQLITE_API int sqlite3_libversion_number(void);
 ** [sqlite_compileoption_get()] and the [compile_options pragma].
 */
 #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
-SQLITE_API int sqlite3_compileoption_used(const char *zOptName);
-SQLITE_API const char *sqlite3_compileoption_get(int N);
+SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N);
 #endif
 
 /*
@@ -316,7 +412,7 @@ SQLITE_API const char *sqlite3_compileoption_get(int N);
 ** SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but
 ** can be fully or partially disabled using a call to [sqlite3_config()]
 ** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD],
-** or [SQLITE_CONFIG_MUTEX].  ^(The return value of the
+** or [SQLITE_CONFIG_SERIALIZED].  ^(The return value of the
 ** sqlite3_threadsafe() function shows only the compile-time setting of
 ** thread safety, not any run-time changes to that setting made by
 ** sqlite3_config(). In other words, the return value from sqlite3_threadsafe()
@@ -324,7 +420,7 @@ SQLITE_API const char *sqlite3_compileoption_get(int N);
 **
 ** See the [threading mode] documentation for additional information.
 */
-SQLITE_API int sqlite3_threadsafe(void);
+SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void);
 
 /*
 ** CAPI3REF: Database Connection Handle
@@ -381,6 +477,7 @@ typedef sqlite_uint64 sqlite3_uint64;
 
 /*
 ** CAPI3REF: Closing A Database Connection
+** DESTRUCTOR: sqlite3
 **
 ** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors
 ** for the [sqlite3] object.
@@ -420,8 +517,8 @@ typedef sqlite_uint64 sqlite3_uint64;
 ** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer
 ** argument is a harmless no-op.
 */
-SQLITE_API int sqlite3_close(sqlite3*);
-SQLITE_API int sqlite3_close_v2(sqlite3*);
+SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3*);
+SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3*);
 
 /*
 ** The type for a callback function.
@@ -432,6 +529,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
 
 /*
 ** CAPI3REF: One-Step Query Execution Interface
+** METHOD: sqlite3
 **
 ** The sqlite3_exec() interface is a convenience wrapper around
 ** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()],
@@ -491,7 +589,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
 **      the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
 ** </ul>
 */
-SQLITE_API int sqlite3_exec(
+SQLITE_API int SQLITE_STDCALL sqlite3_exec(
   sqlite3*,                                  /* An open database */
   const char *sql,                           /* SQL to be evaluated */
   int (*callback)(void*,int,char**,char**),  /* Callback function */
@@ -612,6 +710,7 @@ SQLITE_API int sqlite3_exec(
 #define SQLITE_NOTICE_RECOVER_WAL      (SQLITE_NOTICE | (1<<8))
 #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
 #define SQLITE_WARNING_AUTOINDEX       (SQLITE_WARNING | (1<<8))
+#define SQLITE_AUTH_USER               (SQLITE_AUTH | (1<<8))
 
 /*
 ** CAPI3REF: Flags For File Open Operations
@@ -870,14 +969,16 @@ struct sqlite3_io_methods {
 ** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()]
 ** interface.
 **
+** <ul>
+** <li>[[SQLITE_FCNTL_LOCKSTATE]]
 ** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging.  This
 ** opcode causes the xFileControl method to write the current state of
 ** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED],
 ** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE])
 ** into an integer that the pArg argument points to. This capability
-** is used during testing and only needs to be supported when SQLITE_TEST
-** is defined.
-** <ul>
+** is used during testing and is only available when the SQLITE_TEST
+** compile-time option is used.
+**
 ** <li>[[SQLITE_FCNTL_SIZE_HINT]]
 ** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS
 ** layer a hint of how large the database file will grow to be during the
@@ -1002,7 +1103,9 @@ struct sqlite3_io_methods {
 ** [PRAGMA] processing continues.  ^If the [SQLITE_FCNTL_PRAGMA]
 ** file control returns [SQLITE_OK], then the parser assumes that the
 ** VFS has handled the PRAGMA itself and the parser generates a no-op
-** prepared statement.  ^If the [SQLITE_FCNTL_PRAGMA] file control returns
+** prepared statement if result string is NULL, or that returns a copy
+** of the result string if the string is non-NULL.
+** ^If the [SQLITE_FCNTL_PRAGMA] file control returns
 ** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means
 ** that the VFS encountered an error while handling the [PRAGMA] and the
 ** compilation of the PRAGMA fails with an error.  ^The [SQLITE_FCNTL_PRAGMA]
@@ -1060,12 +1163,19 @@ struct sqlite3_io_methods {
 ** pointed to by the pArg argument.  This capability is used during testing
 ** and only needs to be supported when SQLITE_TEST is defined.
 **
+** <li>[[SQLITE_FCNTL_WAL_BLOCK]]
+** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
+** be advantageous to block on the next WAL lock if the lock is not immediately
+** available.  The WAL subsystem issues this signal during rare
+** circumstances in order to fix a problem with priority inversion.
+** Applications should <em>not</em> use this file-control.
+**
 ** </ul>
 */
 #define SQLITE_FCNTL_LOCKSTATE               1
-#define SQLITE_GET_LOCKPROXYFILE             2
-#define SQLITE_SET_LOCKPROXYFILE             3
-#define SQLITE_LAST_ERRNO                    4
+#define SQLITE_FCNTL_GET_LOCKPROXYFILE       2
+#define SQLITE_FCNTL_SET_LOCKPROXYFILE       3
+#define SQLITE_FCNTL_LAST_ERRNO              4
 #define SQLITE_FCNTL_SIZE_HINT               5
 #define SQLITE_FCNTL_CHUNK_SIZE              6
 #define SQLITE_FCNTL_FILE_POINTER            7
@@ -1084,6 +1194,13 @@ struct sqlite3_io_methods {
 #define SQLITE_FCNTL_SYNC                   21
 #define SQLITE_FCNTL_COMMIT_PHASETWO        22
 #define SQLITE_FCNTL_WIN32_SET_HANDLE       23
+#define SQLITE_FCNTL_WAL_BLOCK              24
+
+/* deprecated names */
+#define SQLITE_GET_LOCKPROXYFILE      SQLITE_FCNTL_GET_LOCKPROXYFILE
+#define SQLITE_SET_LOCKPROXYFILE      SQLITE_FCNTL_SET_LOCKPROXYFILE
+#define SQLITE_LAST_ERRNO             SQLITE_FCNTL_LAST_ERRNO
+
 
 /*
 ** CAPI3REF: Mutex Handle
@@ -1335,7 +1452,7 @@ struct sqlite3_vfs {
 ** </ul>
 **
 ** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as
-** was given no the corresponding lock.  
+** was given on the corresponding lock.  
 **
 ** The xShmLock method can transition between unlocked and SHARED or
 ** between unlocked and EXCLUSIVE.  It cannot transition between SHARED
@@ -1432,10 +1549,10 @@ struct sqlite3_vfs {
 ** must return [SQLITE_OK] on success and some other [error code] upon
 ** failure.
 */
-SQLITE_API int sqlite3_initialize(void);
-SQLITE_API int sqlite3_shutdown(void);
-SQLITE_API int sqlite3_os_init(void);
-SQLITE_API int sqlite3_os_end(void);
+SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void);
+SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void);
+SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void);
+SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void);
 
 /*
 ** CAPI3REF: Configuring The SQLite Library
@@ -1466,10 +1583,11 @@ SQLITE_API int sqlite3_os_end(void);
 ** ^If the option is unknown or SQLite is unable to set the option
 ** then this routine returns a non-zero [error code].
 */
-SQLITE_API int sqlite3_config(int, ...);
+SQLITE_API int SQLITE_CDECL sqlite3_config(int, ...);
 
 /*
 ** CAPI3REF: Configure database connections
+** METHOD: sqlite3
 **
 ** The sqlite3_db_config() interface is used to make configuration
 ** changes to a [database connection].  The interface is similar to
@@ -1484,7 +1602,7 @@ SQLITE_API int sqlite3_config(int, ...);
 ** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if
 ** the call is considered successful.
 */
-SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
+SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3*, int op, ...);
 
 /*
 ** CAPI3REF: Memory Allocation Routines
@@ -1618,31 +1736,33 @@ struct sqlite3_mem_methods {
 ** SQLITE_CONFIG_SERIALIZED configuration option.</dd>
 **
 ** [[SQLITE_CONFIG_MALLOC]] <dt>SQLITE_CONFIG_MALLOC</dt>
-** <dd> ^(This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mem_methods] structure.  The argument specifies
+** <dd> ^(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.)^ ^SQLite makes
 ** its own private copy of the content of the [sqlite3_mem_methods] structure
 ** before the [sqlite3_config()] call returns.</dd>
 **
 ** [[SQLITE_CONFIG_GETMALLOC]] <dt>SQLITE_CONFIG_GETMALLOC</dt>
-** <dd> ^(This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mem_methods] structure.  The [sqlite3_mem_methods]
+** <dd> ^(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.)^
 ** This option can be used to overload the default memory allocation
 ** routines with a wrapper that simulations memory allocation failure or
 ** tracks memory usage, for example. </dd>
 **
 ** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
-** <dd> ^This option takes single argument of type int, interpreted as a 
-** boolean, which enables or disables the collection of memory allocation 
-** statistics. ^(When memory allocation statistics are disabled, the 
-** following SQLite interfaces become non-operational:
+** <dd> ^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. ^(When memory allocation statistics are
+** disabled, the following SQLite interfaces become non-operational:
 **   <ul>
 **   <li> [sqlite3_memory_used()]
 **   <li> [sqlite3_memory_highwater()]
 **   <li> [sqlite3_soft_heap_limit64()]
-**   <li> [sqlite3_status()]
+**   <li> [sqlite3_status64()]
 **   </ul>)^
 ** ^Memory allocation statistics are enabled by default unless SQLite is
 ** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory
@@ -1650,53 +1770,67 @@ struct sqlite3_mem_methods {
 ** </dd>
 **
 ** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt>
-** <dd> ^This option specifies a static memory buffer that SQLite can use for
-** scratch memory.  There are three arguments:  A pointer an 8-byte
+** <dd> ^The SQLITE_CONFIG_SCRATCH option specifies a static memory buffer
+** that SQLite can use for scratch memory.  ^(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).  The sz
-** argument must be a multiple of 16.
+** and the maximum number of scratch allocations (N).)^
 ** The first argument must be a pointer to an 8-byte aligned buffer
 ** of at least sz*N bytes of memory.
-** ^SQLite will use no more than two scratch buffers per thread.  So
-** N should be set to twice the expected maximum number of threads.
-** ^SQLite will never require a scratch buffer that is more than 6
-** times the database page size. ^If SQLite needs needs additional
+** ^SQLite will not use more than one scratch buffers per thread.
+** ^SQLite will never request a scratch buffer that is more than 6
+** times the database page size.
+** ^If SQLite needs needs additional
 ** scratch memory beyond what is provided by this configuration option, then 
-** [sqlite3_malloc()] will be used to obtain the memory needed.</dd>
+** [sqlite3_malloc()] will be used to obtain the memory needed.<p>
+** ^When the application provides any amount of scratch memory using
+** SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary large
+** [sqlite3_malloc|heap allocations].
+** This can help [Robson proof|prevent memory allocation failures] due to heap
+** fragmentation in low-memory embedded systems.
+** </dd>
 **
 ** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
-** <dd> ^This option specifies a static memory buffer that SQLite can use for
-** the database page cache with the default page cache implementation.  
+** <dd> ^The SQLITE_CONFIG_PAGECACHE option specifies a static memory buffer
+** that SQLite can use for the database page cache with the default page
+** cache implementation.  
 ** This configuration should not be used if an application-define page
-** cache implementation is loaded using the SQLITE_CONFIG_PCACHE2 option.
-** There are three arguments to this option: A pointer to 8-byte aligned
+** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2]
+** configuration option.
+** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to
+** 8-byte aligned
 ** memory, the size of each page buffer (sz), and the number of pages (N).
 ** The sz argument should be the size of the largest database page
-** (a power of two between 512 and 32768) plus a little extra for each
-** page header.  ^The page header size is 20 to 40 bytes depending on
-** the host architecture.  ^It is harmless, apart from the wasted memory,
-** to make sz a little too large.  The first
-** argument should point to an allocation of at least sz*N bytes of memory.
+** (a power of two between 512 and 65536) plus some extra bytes for each
+** page header.  ^The number of extra bytes needed by the page header
+** can be determined using the [SQLITE_CONFIG_PCACHE_HDRSZ] option 
+** to [sqlite3_config()].
+** ^It is harmless, apart from the wasted memory,
+** for the sz parameter to be larger than necessary.  The first
+** argument should pointer to an 8-byte aligned block of memory that
+** is at least sz*N bytes of memory, otherwise subsequent behavior is
+** undefined.
 ** ^SQLite will use the memory provided by the first argument to satisfy its
 ** memory needs for the first N pages that it adds to cache.  ^If additional
 ** page cache memory is needed beyond what is provided by this option, then
-** SQLite goes to [sqlite3_malloc()] for the additional storage space.
-** The pointer in the first argument must
-** be aligned to an 8-byte boundary or subsequent behavior of SQLite
-** will be undefined.</dd>
+** SQLite goes to [sqlite3_malloc()] for the additional storage space.</dd>
 **
 ** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
-** <dd> ^This option specifies a static memory buffer that SQLite will use
-** for all of its dynamic memory allocation needs beyond those provided
-** for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE].
-** There are three arguments: An 8-byte aligned pointer to the memory,
+** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer 
+** that SQLite will use for all of its dynamic memory allocation needs
+** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and
+** [SQLITE_CONFIG_PAGECACHE].
+** ^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.
+** ^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.
 ** ^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].  ^If the
-** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
-** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
+** memory pointer is not NULL then the alternative memory
 ** allocator is engaged to handle all of SQLites memory allocation needs.
 ** The first pointer (the memory pointer) must be aligned to an 8-byte
 ** boundary or subsequent behavior of SQLite will be undefined.
@@ -1704,11 +1838,11 @@ struct sqlite3_mem_methods {
 ** for the minimum allocation size are 2**5 through 2**8.</dd>
 **
 ** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
-** <dd> ^(This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mutex_methods] structure.  The argument specifies
-** alternative low-level mutex routines to be used in place
-** the mutex routines built into SQLite.)^  ^SQLite makes a copy of the
-** content of the [sqlite3_mutex_methods] structure before the call to
+** <dd> ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a
+** pointer to an instance of the [sqlite3_mutex_methods] structure.
+** The argument specifies alternative low-level mutex routines to be used
+** in place the mutex routines built into SQLite.)^  ^SQLite makes a copy of
+** the content of the [sqlite3_mutex_methods] structure before the call to
 ** [sqlite3_config()] returns. ^If SQLite is compiled with
 ** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
 ** the entire mutexing subsystem is omitted from the build and hence calls to
@@ -1716,8 +1850,8 @@ struct sqlite3_mem_methods {
 ** return [SQLITE_ERROR].</dd>
 **
 ** [[SQLITE_CONFIG_GETMUTEX]] <dt>SQLITE_CONFIG_GETMUTEX</dt>
-** <dd> ^(This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mutex_methods] structure.  The
+** <dd> ^(The SQLITE_CONFIG_GETMUTEX option takes a single argument which
+** is a pointer to an instance of the [sqlite3_mutex_methods] structure.  The
 ** [sqlite3_mutex_methods]
 ** structure is filled with the currently defined mutex routines.)^
 ** This option can be used to overload the default mutex allocation
@@ -1729,25 +1863,25 @@ struct sqlite3_mem_methods {
 ** return [SQLITE_ERROR].</dd>
 **
 ** [[SQLITE_CONFIG_LOOKASIDE]] <dt>SQLITE_CONFIG_LOOKASIDE</dt>
-** <dd> ^(This option takes two arguments that determine the default
-** memory allocation for the lookaside memory allocator on each
-** [database connection].  The first argument is the
+** <dd> ^(The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine
+** the default size of lookaside memory on each [database connection].
+** The first argument is the
 ** size of each lookaside buffer slot and the second is the number of
-** slots allocated to each database connection.)^  ^(This option sets the
-** <i>default</i> lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE]
-** verb to [sqlite3_db_config()] can be used to change the lookaside
+** slots allocated to each database connection.)^  ^(SQLITE_CONFIG_LOOKASIDE
+** sets the <i>default</i> lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE]
+** option to [sqlite3_db_config()] can be used to change the lookaside
 ** configuration on individual connections.)^ </dd>
 **
 ** [[SQLITE_CONFIG_PCACHE2]] <dt>SQLITE_CONFIG_PCACHE2</dt>
-** <dd> ^(This 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.)^  ^SQLite makes a copy of the
-** object and uses it for page cache memory allocations.</dd>
+** <dd> ^(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.)^
+** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.</dd>
 **
 ** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt>
-** <dd> ^(This 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.)^ </dd>
+** <dd> ^(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.)^ </dd>
 **
 ** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt>
 ** <dd> The SQLITE_CONFIG_LOG option is used to configure the SQLite
@@ -1770,10 +1904,11 @@ struct sqlite3_mem_methods {
 ** function must be threadsafe. </dd>
 **
 ** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI
-** <dd>^(This 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.)^ ^If URI handling is globally enabled, all filenames
-** passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or
+** <dd>^(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.)^ ^If URI handling is globally
+** enabled, all filenames passed to [sqlite3_open()], [sqlite3_open_v2()],
+** [sqlite3_open16()] or
 ** specified as part of [ATTACH] commands are interpreted as URIs, regardless
 ** of whether or not the [SQLITE_OPEN_URI] flag is set when the database
 ** connection is opened. ^If it is globally disabled, filenames are
@@ -1783,9 +1918,10 @@ struct sqlite3_mem_methods {
 ** [SQLITE_USE_URI] symbol defined.)^
 **
 ** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
-** <dd>^This 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.  ^The default setting is determined
+** <dd>^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.
+** ^The default setting is determined
 ** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
 ** if that compile-time option is omitted.
 ** The ability to disable the use of covering indices for full table scans
@@ -1825,18 +1961,37 @@ struct sqlite3_mem_methods {
 ** ^The default setting can be overridden by each database connection using
 ** either the [PRAGMA mmap_size] command, or by using the
 ** [SQLITE_FCNTL_MMAP_SIZE] file control.  ^(The maximum allowed mmap size
-** cannot be changed at run-time.  Nor may the maximum allowed mmap size
-** exceed the compile-time maximum mmap size set by the
+** 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 either argument to this option is negative, then that argument is
 ** changed to its compile-time default.
 **
 ** [[SQLITE_CONFIG_WIN32_HEAPSIZE]]
 ** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE
-** <dd>^This option is only available if SQLite is compiled for Windows
-** with the [SQLITE_WIN32_MALLOC] pre-processor macro defined.
-** SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
+** <dd>^The SQLITE_CONFIG_WIN32_HEAPSIZE option is only available if SQLite is
+** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro
+** defined. ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
 ** that specifies the maximum size of the created heap.
+**
+** [[SQLITE_CONFIG_PCACHE_HDRSZ]]
+** <dt>SQLITE_CONFIG_PCACHE_HDRSZ
+** <dd>^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].
+** The amount of extra space required can change depending on the compiler,
+** target platform, and SQLite version.
+**
+** [[SQLITE_CONFIG_PMASZ]]
+** <dt>SQLITE_CONFIG_PMASZ
+** <dd>^The SQLITE_CONFIG_PMASZ option takes a single parameter which
+** is an unsigned integer and sets the "Minimum PMA Size" for the multithreaded
+** sorter to that integer.  The default minimum PMA Size is set by the
+** [SQLITE_SORTER_PMASZ] compile-time option.  New threads are launched
+** to help with sort operations when multithreaded sorting
+** is enabled (using the [PRAGMA threads] command) and the amount of content
+** to be sorted exceeds the page size times the minimum of the
+** [PRAGMA cache_size] setting and this value.
 ** </dl>
 */
 #define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
@@ -1862,6 +2017,8 @@ struct sqlite3_mem_methods {
 #define SQLITE_CONFIG_SQLLOG       21  /* xSqllog, void* */
 #define SQLITE_CONFIG_MMAP_SIZE    22  /* sqlite3_int64, sqlite3_int64 */
 #define SQLITE_CONFIG_WIN32_HEAPSIZE      23  /* int nByte */
+#define SQLITE_CONFIG_PCACHE_HDRSZ        24  /* int *psz */
+#define SQLITE_CONFIG_PMASZ               25  /* unsigned int szPma */
 
 /*
 ** CAPI3REF: Database Connection Configuration Options
@@ -1928,15 +2085,17 @@ struct sqlite3_mem_methods {
 
 /*
 ** CAPI3REF: Enable Or Disable Extended Result Codes
+** METHOD: sqlite3
 **
 ** ^The sqlite3_extended_result_codes() routine enables or disables the
 ** [extended result codes] feature of SQLite. ^The extended result
 ** codes are disabled by default for historical compatibility.
 */
-SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
+SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3*, int onoff);
 
 /*
 ** CAPI3REF: Last Insert Rowid
+** METHOD: sqlite3
 **
 ** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables)
 ** has a unique 64-bit signed
@@ -1984,52 +2143,51 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
 ** unpredictable and might not equal either the old or the new
 ** last insert [rowid].
 */
-SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3*);
 
 /*
 ** CAPI3REF: Count The Number Of Rows Modified
+** METHOD: sqlite3
+**
+** ^This function returns the number of rows modified, inserted or
+** deleted by the most recently completed INSERT, UPDATE or DELETE
+** statement on the database connection specified by the only parameter.
+** ^Executing any other type of SQL statement does not modify the value
+** returned by this function.
 **
-** ^This function returns the number of database rows that were changed
-** or inserted or deleted by the most recently completed SQL statement
-** on the [database connection] specified by the first parameter.
-** ^(Only changes that are directly specified by the [INSERT], [UPDATE],
-** or [DELETE] statement are counted.  Auxiliary changes caused by
-** triggers or [foreign key actions] are not counted.)^ Use the
-** [sqlite3_total_changes()] function to find the total number of changes
-** including changes caused by triggers and foreign key actions.
-**
-** ^Changes to a view that are simulated by an [INSTEAD OF trigger]
-** are not counted.  Only real table changes are counted.
-**
-** ^(A "row change" is a change to a single row of a single table
-** caused by an INSERT, DELETE, or UPDATE statement.  Rows that
-** are changed as side effects of [REPLACE] constraint resolution,
-** rollback, ABORT processing, [DROP TABLE], or by any other
-** mechanisms do not count as direct row changes.)^
-**
-** A "trigger context" is a scope of execution that begins and
-** ends with the script of a [CREATE TRIGGER | trigger]. 
-** Most SQL statements are
-** evaluated outside of any trigger.  This is the "top level"
-** trigger context.  If a trigger fires from the top level, a
-** new trigger context is entered for the duration of that one
-** trigger.  Subtriggers create subcontexts for their duration.
-**
-** ^Calling [sqlite3_exec()] or [sqlite3_step()] recursively does
-** not create a new trigger context.
-**
-** ^This function returns the number of direct row changes in the
-** most recent INSERT, UPDATE, or DELETE statement within the same
-** trigger context.
-**
-** ^Thus, when called from the top level, this function returns the
-** number of changes in the most recent INSERT, UPDATE, or DELETE
-** that also occurred at the top level.  ^(Within the body of a trigger,
-** the sqlite3_changes() interface can be called to find the number of
-** changes in the most recently completed INSERT, UPDATE, or DELETE
-** statement within the body of the same trigger.
-** However, the number returned does not include changes
-** caused by subtriggers since those have their own context.)^
+** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are
+** considered - auxiliary changes caused by [CREATE TRIGGER | triggers], 
+** [foreign key actions] or [REPLACE] constraint resolution are not counted.
+** 
+** Changes to a view that are intercepted by 
+** [INSTEAD OF trigger | INSTEAD OF triggers] are not counted. ^The value 
+** returned by sqlite3_changes() immediately after an INSERT, UPDATE or 
+** DELETE statement run on a view is always zero. Only changes made to real 
+** tables are counted.
+**
+** Things are more complicated if the sqlite3_changes() function is
+** executed while a trigger program is running. This may happen if the
+** program uses the [changes() SQL function], or if some other callback
+** function invokes sqlite3_changes() directly. Essentially:
+** 
+** <ul>
+**   <li> ^(Before entering a trigger program the value returned by
+**        sqlite3_changes() function is saved. After the trigger program 
+**        has finished, the original value is restored.)^
+** 
+**   <li> ^(Within a trigger program each INSERT, UPDATE and DELETE 
+**        statement sets the value returned by sqlite3_changes() 
+**        upon completion as normal. Of course, this value will not include 
+**        any changes performed by sub-triggers, as the sqlite3_changes() 
+**        value will be saved and restored after each sub-trigger has run.)^
+** </ul>
+** 
+** ^This means that if the changes() SQL function (or similar) is used
+** by the first INSERT, UPDATE or DELETE statement within a trigger, it 
+** returns the value as set when the calling statement began executing.
+** ^If it is used by the second or subsequent such statement within a trigger 
+** program, the value returned reflects the number of rows modified by the 
+** previous INSERT, UPDATE or DELETE statement within the same trigger.
 **
 ** See also the [sqlite3_total_changes()] interface, the
 ** [count_changes pragma], and the [changes() SQL function].
@@ -2038,25 +2196,23 @@ SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
 ** while [sqlite3_changes()] is running then the value returned
 ** is unpredictable and not meaningful.
 */
-SQLITE_API int sqlite3_changes(sqlite3*);
+SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3*);
 
 /*
 ** CAPI3REF: Total Number Of Rows Modified
+** METHOD: sqlite3
 **
-** ^This function returns the number of row changes caused by [INSERT],
-** [UPDATE] or [DELETE] statements since the [database connection] was opened.
-** ^(The count returned by sqlite3_total_changes() includes all changes
-** from all [CREATE TRIGGER | trigger] contexts and changes made by
-** [foreign key actions]. However,
-** the count does not include changes used to implement [REPLACE] constraints,
-** do rollbacks or ABORT processing, or [DROP TABLE] processing.  The
-** count does not include rows of views that fire an [INSTEAD OF trigger],
-** though if the INSTEAD OF trigger makes changes of its own, those changes 
-** are counted.)^
-** ^The sqlite3_total_changes() function counts the changes as soon as
-** the statement that makes them is completed (when the statement handle
-** is passed to [sqlite3_reset()] or [sqlite3_finalize()]).
-**
+** ^This function returns the total number of rows inserted, modified or
+** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed
+** since the database connection was opened, including those executed as
+** part of trigger programs. ^Executing any other type of SQL statement
+** does not affect the value returned by sqlite3_total_changes().
+** 
+** ^Changes made as part of [foreign key actions] are included in the
+** count, but those made as part of REPLACE constraint resolution are
+** not. ^Changes to a view that are intercepted by INSTEAD OF triggers 
+** are not counted.
+** 
 ** See also the [sqlite3_changes()] interface, the
 ** [count_changes pragma], and the [total_changes() SQL function].
 **
@@ -2064,10 +2220,11 @@ SQLITE_API int sqlite3_changes(sqlite3*);
 ** while [sqlite3_total_changes()] is running then the value
 ** returned is unpredictable and not meaningful.
 */
-SQLITE_API int sqlite3_total_changes(sqlite3*);
+SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3*);
 
 /*
 ** CAPI3REF: Interrupt A Long-Running Query
+** METHOD: sqlite3
 **
 ** ^This function causes any pending database operation to abort and
 ** return at its earliest opportunity. This routine is typically
@@ -2103,7 +2260,7 @@ SQLITE_API int sqlite3_total_changes(sqlite3*);
 ** If the database connection closes while [sqlite3_interrupt()]
 ** is running then bad things will likely happen.
 */
-SQLITE_API void sqlite3_interrupt(sqlite3*);
+SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3*);
 
 /*
 ** CAPI3REF: Determine If An SQL Statement Is Complete
@@ -2138,11 +2295,13 @@ SQLITE_API void sqlite3_interrupt(sqlite3*);
 ** The input to [sqlite3_complete16()] must be a zero-terminated
 ** UTF-16 string in native byte order.
 */
-SQLITE_API int sqlite3_complete(const char *sql);
-SQLITE_API int sqlite3_complete16(const void *sql);
+SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *sql);
+SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *sql);
 
 /*
 ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
+** KEYWORDS: {busy-handler callback} {busy handler}
+** METHOD: sqlite3
 **
 ** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X
 ** that might be invoked with argument P whenever
@@ -2159,7 +2318,7 @@ SQLITE_API int sqlite3_complete16(const void *sql);
 ** ^The first argument to the busy handler is a copy of the void* pointer which
 ** is the third argument to sqlite3_busy_handler().  ^The second argument to
 ** the busy handler callback is the number of times that the busy handler has
-** been invoked for the same locking event.  ^If the
+** been invoked previously for the same locking event.  ^If the
 ** busy callback returns 0, then no additional attempts are made to
 ** access the database and [SQLITE_BUSY] is returned
 ** to the application.
@@ -2198,10 +2357,11 @@ SQLITE_API int sqlite3_complete16(const void *sql);
 ** A busy handler must not close the database connection
 ** or [prepared statement] that invoked the busy handler.
 */
-SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
+SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
 
 /*
 ** CAPI3REF: Set A Busy Timeout
+** METHOD: sqlite3
 **
 ** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps
 ** for a specified amount of time when a table is locked.  ^The handler
@@ -2214,16 +2374,17 @@ SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
 ** turns off all busy handlers.
 **
 ** ^(There can only be a single busy handler for a particular
-** [database connection] any any given moment.  If another busy handler
+** [database connection] at any given moment.  If another busy handler
 ** was defined  (using [sqlite3_busy_handler()]) prior to calling
 ** this routine, that other busy handler is cleared.)^
 **
 ** See also:  [PRAGMA busy_timeout]
 */
-SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
+SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3*, int ms);
 
 /*
 ** CAPI3REF: Convenience Routines For Running Queries
+** METHOD: sqlite3
 **
 ** This is a legacy interface that is preserved for backwards compatibility.
 ** Use of this interface is not recommended.
@@ -2294,7 +2455,7 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
 ** reflected in subsequent calls to [sqlite3_errcode()] or
 ** [sqlite3_errmsg()].
 */
-SQLITE_API int sqlite3_get_table(
+SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
   sqlite3 *db,          /* An open database */
   const char *zSql,     /* SQL to be evaluated */
   char ***pazResult,    /* Results of the query */
@@ -2302,13 +2463,17 @@ SQLITE_API int sqlite3_get_table(
   int *pnColumn,        /* Number of result columns written here */
   char **pzErrmsg       /* Error msg written here */
 );
-SQLITE_API void sqlite3_free_table(char **result);
+SQLITE_API void SQLITE_STDCALL sqlite3_free_table(char **result);
 
 /*
 ** CAPI3REF: Formatted String Printing Functions
 **
 ** These routines are work-alikes of the "printf()" family of functions
 ** from the standard C library.
+** These routines understand most of the common K&R formatting options,
+** plus some additional non-standard formats, detailed below.
+** Note that some of the more obscure formatting options from recent
+** C-library standards are omitted from this implementation.
 **
 ** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
 ** results into memory obtained from [sqlite3_malloc()].
@@ -2341,7 +2506,7 @@ SQLITE_API void sqlite3_free_table(char **result);
 ** These routines all implement some additional formatting
 ** options that are useful for constructing SQL statements.
 ** All of the usual printf() formatting options apply.  In addition, there
-** is are "%q", "%Q", and "%z" options.
+** is are "%q", "%Q", "%w" and "%z" options.
 **
 ** ^(The %q option works like %s in that it substitutes a nul-terminated
 ** string from the argument list.  But %q also doubles every '\'' character.
@@ -2394,14 +2559,20 @@ SQLITE_API void sqlite3_free_table(char **result);
 ** The code above will render a correct SQL statement in the zSQL
 ** variable even if the zText variable is a NULL pointer.
 **
+** ^(The "%w" formatting option is like "%q" except that it expects to
+** be contained within double-quotes instead of single quotes, and it
+** escapes the double-quote character instead of the single-quote
+** character.)^  The "%w" formatting option is intended for safely inserting
+** table and column names into a constructed SQL statement.
+**
 ** ^(The "%z" formatting option works like "%s" but with the
 ** addition that after the string has been read and copied into
 ** the result, [sqlite3_free()] is called on the input string.)^
 */
-SQLITE_API char *sqlite3_mprintf(const char*,...);
-SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
-SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...);
-SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
+SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char*,...);
+SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char*, va_list);
+SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int,char*,const char*, ...);
+SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int,char*,const char*, va_list);
 
 /*
 ** CAPI3REF: Memory Allocation Subsystem
@@ -2418,6 +2589,10 @@ SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
 ** sqlite3_malloc() is zero or negative then sqlite3_malloc() returns
 ** a NULL pointer.
 **
+** ^The sqlite3_malloc64(N) routine works just like
+** sqlite3_malloc(N) except that N is an unsigned 64-bit integer instead
+** of a signed 32-bit integer.
+**
 ** ^Calling sqlite3_free() with a pointer previously returned
 ** by sqlite3_malloc() or sqlite3_realloc() releases that memory so
 ** that it might be reused.  ^The sqlite3_free() routine is
@@ -2429,24 +2604,38 @@ SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
 ** might result if sqlite3_free() is called with a non-NULL pointer that
 ** was not obtained from sqlite3_malloc() or sqlite3_realloc().
 **
-** ^(The sqlite3_realloc() interface attempts to resize a
-** prior memory allocation to be at least N bytes, where N is the
-** second parameter.  The memory allocation to be resized is the first
-** parameter.)^ ^ If the first parameter to sqlite3_realloc()
+** ^The sqlite3_realloc(X,N) interface attempts to resize a
+** prior memory allocation X to be at least N bytes.
+** ^If the X parameter to sqlite3_realloc(X,N)
 ** is a NULL pointer then its behavior is identical to calling
-** sqlite3_malloc(N) where N is the second parameter to sqlite3_realloc().
-** ^If the second parameter to sqlite3_realloc() is zero or
+** sqlite3_malloc(N).
+** ^If the N parameter to sqlite3_realloc(X,N) is zero or
 ** negative then the behavior is exactly the same as calling
-** sqlite3_free(P) where P is the first parameter to sqlite3_realloc().
-** ^sqlite3_realloc() returns a pointer to a memory allocation
-** of at least N bytes in size or NULL if sufficient memory is unavailable.
+** sqlite3_free(X).
+** ^sqlite3_realloc(X,N) returns a pointer to a memory allocation
+** of at least N bytes in size or NULL if insufficient memory is available.
 ** ^If M is the size of the prior allocation, then min(N,M) bytes
 ** of the prior allocation are copied into the beginning of buffer returned
-** by sqlite3_realloc() and the prior allocation is freed.
-** ^If sqlite3_realloc() returns NULL, then the prior allocation
-** is not freed.
-**
-** ^The memory returned by sqlite3_malloc() and sqlite3_realloc()
+** by sqlite3_realloc(X,N) and the prior allocation is freed.
+** ^If sqlite3_realloc(X,N) returns NULL and N is positive, then the
+** prior allocation is not freed.
+**
+** ^The sqlite3_realloc64(X,N) interfaces works the same as
+** sqlite3_realloc(X,N) except that N is a 64-bit unsigned integer instead
+** of a 32-bit signed integer.
+**
+** ^If X is a memory allocation previously obtained from sqlite3_malloc(),
+** sqlite3_malloc64(), sqlite3_realloc(), or sqlite3_realloc64(), then
+** sqlite3_msize(X) returns the size of that memory allocation in bytes.
+** ^The value returned by sqlite3_msize(X) might be larger than the number
+** of bytes requested when X was allocated.  ^If X is a NULL pointer then
+** sqlite3_msize(X) returns zero.  If X points to something that is not
+** the beginning of memory allocation, or if it points to a formerly
+** valid memory allocation that has now been freed, then the behavior
+** of sqlite3_msize(X) is undefined and possibly harmful.
+**
+** ^The memory returned by sqlite3_malloc(), sqlite3_realloc(),
+** sqlite3_malloc64(), and sqlite3_realloc64()
 ** is always aligned to at least an 8 byte boundary, or to a
 ** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time
 ** option is used.
@@ -2473,9 +2662,12 @@ SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
 ** a block of memory after it has been released using
 ** [sqlite3_free()] or [sqlite3_realloc()].
 */
-SQLITE_API void *sqlite3_malloc(int);
-SQLITE_API void *sqlite3_realloc(void*, int);
-SQLITE_API void sqlite3_free(void*);
+SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int);
+SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64);
+SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void*, int);
+SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void*, sqlite3_uint64);
+SQLITE_API void SQLITE_STDCALL sqlite3_free(void*);
+SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void*);
 
 /*
 ** CAPI3REF: Memory Allocator Statistics
@@ -2500,8 +2692,8 @@ SQLITE_API void sqlite3_free(void*);
 ** by [sqlite3_memory_highwater(1)] is the high-water mark
 ** prior to the reset.
 */
-SQLITE_API sqlite3_int64 sqlite3_memory_used(void);
-SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag);
 
 /*
 ** CAPI3REF: Pseudo-Random Number Generator
@@ -2513,20 +2705,22 @@ SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
 ** applications to access the same PRNG for other purposes.
 **
 ** ^A call to this routine stores N bytes of randomness into buffer P.
-** ^If N is less than one, then P can be a NULL pointer.
+** ^The P parameter can be a NULL pointer.
 **
 ** ^If this routine has not been previously called or if the previous
-** call had N less than one, then the PRNG is seeded using randomness
-** obtained from the xRandomness method of the default [sqlite3_vfs] object.
-** ^If the previous call to this routine had an N of 1 or more then
-** the pseudo-randomness is generated
+** call had N less than one or a NULL pointer for P, then the PRNG is
+** seeded using randomness obtained from the xRandomness method of
+** the default [sqlite3_vfs] object.
+** ^If the previous call to this routine had an N of 1 or more and a
+** non-NULL P then the pseudo-randomness is generated
 ** internally and without recourse to the [sqlite3_vfs] xRandomness
 ** method.
 */
-SQLITE_API void sqlite3_randomness(int N, void *P);
+SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *P);
 
 /*
 ** CAPI3REF: Compile-Time Authorization Callbacks
+** METHOD: sqlite3
 **
 ** ^This routine registers an authorizer callback with a particular
 ** [database connection], supplied in the first argument.
@@ -2605,7 +2799,7 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
 ** as stated in the previous paragraph, sqlite3_step() invokes
 ** sqlite3_prepare_v2() to reprepare a statement after a schema change.
 */
-SQLITE_API int sqlite3_set_authorizer(
+SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer(
   sqlite3*,
   int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
   void *pUserData
@@ -2683,6 +2877,7 @@ SQLITE_API int sqlite3_set_authorizer(
 
 /*
 ** CAPI3REF: Tracing And Profiling Functions
+** METHOD: sqlite3
 **
 ** These routines register callback functions that can be used for
 ** tracing and profiling the execution of SQL statements.
@@ -2709,12 +2904,13 @@ SQLITE_API int sqlite3_set_authorizer(
 ** sqlite3_profile() function is considered experimental and is
 ** subject to change in future versions of SQLite.
 */
-SQLITE_API void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
-SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
+SQLITE_API void *SQLITE_STDCALL sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
+SQLITE_API SQLITE_EXPERIMENTAL void *SQLITE_STDCALL sqlite3_profile(sqlite3*,
    void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
 
 /*
 ** CAPI3REF: Query Progress Callbacks
+** METHOD: sqlite3
 **
 ** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback
 ** function X to be invoked periodically during long running calls to
@@ -2744,10 +2940,11 @@ SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
 ** database connections for the meaning of "modify" in this paragraph.
 **
 */
-SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
+SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
 
 /*
 ** CAPI3REF: Opening A New Database Connection
+** CONSTRUCTOR: sqlite3
 **
 ** ^These routines open an SQLite database file as specified by the 
 ** filename argument. ^The filename argument is interpreted as UTF-8 for
@@ -2762,9 +2959,9 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
 ** an English language description of the error following a failure of any
 ** of the sqlite3_open() routines.
 **
-** ^The default encoding for the database will be UTF-8 if
-** sqlite3_open() or sqlite3_open_v2() is called and
-** UTF-16 in the native byte order if sqlite3_open16() is used.
+** ^The default encoding will be UTF-8 for databases created using
+** sqlite3_open() or sqlite3_open_v2().  ^The default encoding for databases
+** created using sqlite3_open16() will be UTF-16 in the native byte order.
 **
 ** Whether or not an error occurs when it is opened, resources
 ** associated with the [database connection] handle should be released by
@@ -2852,13 +3049,14 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
 ** then it is interpreted as an absolute path. ^If the path does not begin 
 ** with a '/' (meaning that the authority section is omitted from the URI)
 ** then the path is interpreted as a relative path. 
-** ^On windows, the first component of an absolute path 
-** is a drive specification (e.g. "C:").
+** ^(On windows, the first component of an absolute path 
+** is a drive specification (e.g. "C:").)^
 **
 ** [[core URI query parameters]]
 ** The query component of a URI may contain parameters that are interpreted
 ** either by SQLite itself, or by a [VFS | custom VFS implementation].
-** SQLite interprets the following three query parameters:
+** SQLite and its built-in [VFSes] interpret the
+** following query parameters:
 **
 ** <ul>
 **   <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of
@@ -2893,11 +3091,9 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
 **     a URI filename, its value overrides any behavior requested by setting
 **     SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
 **
-**  <li> <b>psow</b>: ^The psow parameter may be "true" (or "on" or "yes" or
-**     "1") or "false" (or "off" or "no" or "0") to indicate that the
+**  <li> <b>psow</b>: ^The psow parameter indicates whether or not the
 **     [powersafe overwrite] property does or does not apply to the
-**     storage media on which the database file resides.  ^The psow query
-**     parameter only works for the built-in unix and Windows VFSes.
+**     storage media on which the database file resides.
 **
 **  <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter
 **     which if set disables file locking in rollback journal modes.  This
@@ -2973,15 +3169,15 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
 **
 ** See also: [sqlite3_temp_directory]
 */
-SQLITE_API int sqlite3_open(
+SQLITE_API int SQLITE_STDCALL sqlite3_open(
   const char *filename,   /* Database filename (UTF-8) */
   sqlite3 **ppDb          /* OUT: SQLite db handle */
 );
-SQLITE_API int sqlite3_open16(
+SQLITE_API int SQLITE_STDCALL sqlite3_open16(
   const void *filename,   /* Database filename (UTF-16) */
   sqlite3 **ppDb          /* OUT: SQLite db handle */
 );
-SQLITE_API int sqlite3_open_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_open_v2(
   const char *filename,   /* Database filename (UTF-8) */
   sqlite3 **ppDb,         /* OUT: SQLite db handle */
   int flags,              /* Flags */
@@ -3027,19 +3223,22 @@ SQLITE_API int sqlite3_open_v2(
 ** VFS method, then the behavior of this routine is undefined and probably
 ** undesirable.
 */
-SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
-SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
-SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam);
+SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
 
 
 /*
 ** CAPI3REF: Error Codes And Messages
-**
-** ^The sqlite3_errcode() interface returns the numeric [result code] or
-** [extended result code] for the most recent failed sqlite3_* API call
-** associated with a [database connection]. If a prior API call failed
-** but the most recent API call succeeded, the return value from
-** sqlite3_errcode() is undefined.  ^The sqlite3_extended_errcode()
+** METHOD: sqlite3
+**
+** ^If the most recent sqlite3_* API call associated with 
+** [database connection] D failed, then the sqlite3_errcode(D) interface
+** returns the numeric [result code] or [extended result code] for that
+** API call.
+** If the most recent API call was successful,
+** then the return value from sqlite3_errcode() is undefined.
+** ^The sqlite3_extended_errcode()
 ** interface is the same except that it always returns the 
 ** [extended result code] even when extended result codes are
 ** disabled.
@@ -3070,40 +3269,41 @@ SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int
 ** was invoked incorrectly by the application.  In that case, the
 ** error code and message may or may not be set.
 */
-SQLITE_API int sqlite3_errcode(sqlite3 *db);
-SQLITE_API int sqlite3_extended_errcode(sqlite3 *db);
-SQLITE_API const char *sqlite3_errmsg(sqlite3*);
-SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
-SQLITE_API const char *sqlite3_errstr(int);
+SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db);
+SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3*);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3*);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_errstr(int);
 
 /*
-** CAPI3REF: SQL Statement Object
+** CAPI3REF: Prepared Statement Object
 ** KEYWORDS: {prepared statement} {prepared statements}
 **
-** An instance of this object represents a single SQL statement.
-** This object is variously known as a "prepared statement" or a
-** "compiled SQL statement" or simply as a "statement".
+** An instance of this object represents a single SQL statement that
+** has been compiled into binary form and is ready to be evaluated.
 **
-** The life of a statement object goes something like this:
+** Think of each SQL statement as a separate computer program.  The
+** original SQL text is source code.  A prepared statement object 
+** is the compiled object code.  All SQL must be converted into a
+** prepared statement before it can be run.
+**
+** The life-cycle of a prepared statement object usually goes like this:
 **
 ** <ol>
-** <li> Create the object using [sqlite3_prepare_v2()] or a related
-**      function.
-** <li> Bind values to [host parameters] using the sqlite3_bind_*()
+** <li> Create the prepared statement object using [sqlite3_prepare_v2()].
+** <li> Bind values to [parameters] using the sqlite3_bind_*()
 **      interfaces.
 ** <li> Run the SQL by calling [sqlite3_step()] one or more times.
-** <li> Reset the statement using [sqlite3_reset()] then go back
+** <li> Reset the prepared statement using [sqlite3_reset()] then go back
 **      to step 2.  Do this zero or more times.
 ** <li> Destroy the object using [sqlite3_finalize()].
 ** </ol>
-**
-** Refer to documentation on individual methods above for additional
-** information.
 */
 typedef struct sqlite3_stmt sqlite3_stmt;
 
 /*
 ** CAPI3REF: Run-time Limits
+** METHOD: sqlite3
 **
 ** ^(This interface allows the size of various constructs to be limited
 ** on a connection by connection basis.  The first parameter is the
@@ -3141,7 +3341,7 @@ typedef struct sqlite3_stmt sqlite3_stmt;
 **
 ** New run-time limit categories may be added in future releases.
 */
-SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
+SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal);
 
 /*
 ** CAPI3REF: Run-Time Limit Categories
@@ -3193,6 +3393,10 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
 **
 ** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
 ** <dd>The maximum depth of recursion for triggers.</dd>)^
+**
+** [[SQLITE_LIMIT_WORKER_THREADS]] ^(<dt>SQLITE_LIMIT_WORKER_THREADS</dt>
+** <dd>The maximum number of auxiliary worker threads that a single
+** [prepared statement] may start.</dd>)^
 ** </dl>
 */
 #define SQLITE_LIMIT_LENGTH                    0
@@ -3206,10 +3410,13 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
 #define SQLITE_LIMIT_LIKE_PATTERN_LENGTH       8
 #define SQLITE_LIMIT_VARIABLE_NUMBER           9
 #define SQLITE_LIMIT_TRIGGER_DEPTH            10
+#define SQLITE_LIMIT_WORKER_THREADS           11
 
 /*
 ** CAPI3REF: Compiling An SQL Statement
 ** KEYWORDS: {SQL statement compiler}
+** METHOD: sqlite3
+** CONSTRUCTOR: sqlite3_stmt
 **
 ** To execute an SQL query, it must first be compiled into a byte-code
 ** program using one of these routines.
@@ -3223,16 +3430,14 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
 ** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2()
 ** use UTF-16.
 **
-** ^If the nByte argument is less than zero, then zSql is read up to the
-** first zero terminator. ^If nByte is non-negative, then it is the maximum
-** number of  bytes read from zSql.  ^When nByte is non-negative, the
-** zSql string ends at either the first '\000' or '\u0000' character or
-** the nByte-th byte, whichever comes first. If the caller knows
-** that the supplied string is nul-terminated, then there is a small
-** performance advantage to be gained by passing an nByte parameter that
-** is equal to the number of bytes in the input string <i>including</i>
-** the nul-terminator bytes as this saves SQLite from having to
-** make a copy of the input string.
+** ^If the nByte argument is negative, then zSql is read up to the
+** first zero terminator. ^If nByte is positive, then it is the
+** number of bytes read from zSql.  ^If nByte is zero, then no prepared
+** statement is generated.
+** If the caller knows that the supplied string is nul-terminated, then
+** there is a small performance advantage to passing an nByte parameter that
+** is the number of bytes in the input string <i>including</i>
+** the nul-terminator.
 **
 ** ^If pzTail is not NULL then *pzTail is made to point to the first byte
 ** past the end of the first SQL statement in zSql.  These routines only
@@ -3288,28 +3493,28 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
 ** </li>
 ** </ol>
 */
-SQLITE_API int sqlite3_prepare(
+SQLITE_API int SQLITE_STDCALL sqlite3_prepare(
   sqlite3 *db,            /* Database handle */
   const char *zSql,       /* SQL statement, UTF-8 encoded */
   int nByte,              /* Maximum length of zSql in bytes. */
   sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
   const char **pzTail     /* OUT: Pointer to unused portion of zSql */
 );
-SQLITE_API int sqlite3_prepare_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2(
   sqlite3 *db,            /* Database handle */
   const char *zSql,       /* SQL statement, UTF-8 encoded */
   int nByte,              /* Maximum length of zSql in bytes. */
   sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
   const char **pzTail     /* OUT: Pointer to unused portion of zSql */
 );
-SQLITE_API int sqlite3_prepare16(
+SQLITE_API int SQLITE_STDCALL sqlite3_prepare16(
   sqlite3 *db,            /* Database handle */
   const void *zSql,       /* SQL statement, UTF-16 encoded */
   int nByte,              /* Maximum length of zSql in bytes. */
   sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
   const void **pzTail     /* OUT: Pointer to unused portion of zSql */
 );
-SQLITE_API int sqlite3_prepare16_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2(
   sqlite3 *db,            /* Database handle */
   const void *zSql,       /* SQL statement, UTF-16 encoded */
   int nByte,              /* Maximum length of zSql in bytes. */
@@ -3319,15 +3524,17 @@ SQLITE_API int sqlite3_prepare16_v2(
 
 /*
 ** CAPI3REF: Retrieving Statement SQL
+** METHOD: sqlite3_stmt
 **
 ** ^This interface can be used to retrieve a saved copy of the original
 ** SQL text used to create a [prepared statement] if that statement was
 ** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
 */
-SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt);
 
 /*
 ** CAPI3REF: Determine If An SQL Statement Writes The Database
+** METHOD: sqlite3_stmt
 **
 ** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if
 ** and only if the [prepared statement] X makes no direct changes to
@@ -3355,10 +3562,11 @@ SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
 ** change the configuration of a database connection, they do not make 
 ** changes to the content of the database files on disk.
 */
-SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
+SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
 
 /*
 ** CAPI3REF: Determine If A Prepared Statement Has Been Reset
+** METHOD: sqlite3_stmt
 **
 ** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
 ** [prepared statement] S has been stepped at least once using 
@@ -3374,7 +3582,7 @@ SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
 ** for example, in diagnostic routines to search for prepared 
 ** statements that are holding a transaction open.
 */
-SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
+SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt*);
 
 /*
 ** CAPI3REF: Dynamically Typed Value Object
@@ -3433,6 +3641,7 @@ typedef struct sqlite3_context sqlite3_context;
 ** CAPI3REF: Binding Values To Prepared Statements
 ** KEYWORDS: {host parameter} {host parameters} {host parameter name}
 ** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
+** METHOD: sqlite3_stmt
 **
 ** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants,
 ** literals may be replaced by a [parameter] that matches one of following
@@ -3479,18 +3688,18 @@ typedef struct sqlite3_context sqlite3_context;
 ** If the fourth parameter to sqlite3_bind_blob() is negative, then
 ** the behavior is undefined.
 ** If a non-negative fourth parameter is provided to sqlite3_bind_text()
-** or sqlite3_bind_text16() then that parameter must be the byte offset
+** or sqlite3_bind_text16() or sqlite3_bind_text64() then
+** that parameter must be the byte offset
 ** where the NUL terminator would occur assuming the string were NUL
 ** terminated.  If any NUL characters occur at byte offsets less than 
 ** the value of the fourth parameter then the resulting string value will
 ** contain embedded NULs.  The result of expressions involving strings
 ** with embedded NULs is undefined.
 **
-** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
-** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
+** ^The fifth argument to the BLOB and string binding interfaces
+** is a destructor used to dispose of the BLOB or
 ** string after SQLite has finished with it.  ^The destructor is called
-** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(),
-** sqlite3_bind_text(), or sqlite3_bind_text16() fails.  
+** to dispose of the BLOB or string even if the call to bind API fails.
 ** ^If the fifth argument is
 ** the special value [SQLITE_STATIC], then SQLite assumes that the
 ** information is in static, unmanaged space and does not need to be freed.
@@ -3498,6 +3707,14 @@ typedef struct sqlite3_context sqlite3_context;
 ** SQLite makes its own private copy of the data immediately, before
 ** the sqlite3_bind_*() routine returns.
 **
+** ^The sixth argument to sqlite3_bind_text64() must be one of
+** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]
+** to specify the encoding of the text in the third parameter.  If
+** the sixth argument to sqlite3_bind_text64() is not one of the
+** allowed values shown above, or if the text encoding is different
+** from the encoding specified by the sixth parameter, then the behavior
+** is undefined.
+**
 ** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that
 ** is filled with zeroes.  ^A zeroblob uses a fixed amount of memory
 ** (just an integer to hold its size) while it is being processed.
@@ -3518,24 +3735,32 @@ typedef struct sqlite3_context sqlite3_context;
 **
 ** ^The sqlite3_bind_* routines return [SQLITE_OK] on success or an
 ** [error code] if anything goes wrong.
+** ^[SQLITE_TOOBIG] might be returned if the size of a string or BLOB
+** exceeds limits imposed by [sqlite3_limit]([SQLITE_LIMIT_LENGTH]) or
+** [SQLITE_MAX_LENGTH].
 ** ^[SQLITE_RANGE] is returned if the parameter
 ** index is out of range.  ^[SQLITE_NOMEM] is returned if malloc() fails.
 **
 ** See also: [sqlite3_bind_parameter_count()],
 ** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()].
 */
-SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
-SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);
-SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int);
-SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
-SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int);
-SQLITE_API int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
-SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
-SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
-SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
+                        void(*)(void*));
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt*, int, double);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt*, int, int);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt*, int);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
+                         void(*)(void*), unsigned char encoding);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
 
 /*
 ** CAPI3REF: Number Of SQL Parameters
+** METHOD: sqlite3_stmt
 **
 ** ^This routine can be used to find the number of [SQL parameters]
 ** in a [prepared statement].  SQL parameters are tokens of the
@@ -3552,10 +3777,11 @@ SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
 ** [sqlite3_bind_parameter_name()], and
 ** [sqlite3_bind_parameter_index()].
 */
-SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt*);
 
 /*
 ** CAPI3REF: Name Of A Host Parameter
+** METHOD: sqlite3_stmt
 **
 ** ^The sqlite3_bind_parameter_name(P,N) interface returns
 ** the name of the N-th [SQL parameter] in the [prepared statement] P.
@@ -3579,10 +3805,11 @@ SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
 ** [sqlite3_bind_parameter_count()], and
 ** [sqlite3_bind_parameter_index()].
 */
-SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt*, int);
 
 /*
 ** CAPI3REF: Index Of A Parameter With A Given Name
+** METHOD: sqlite3_stmt
 **
 ** ^Return the index of an SQL parameter given its name.  ^The
 ** index value returned is suitable for use as the second
@@ -3595,19 +3822,21 @@ SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
 ** [sqlite3_bind_parameter_count()], and
 ** [sqlite3_bind_parameter_index()].
 */
-SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
 
 /*
 ** CAPI3REF: Reset All Bindings On A Prepared Statement
+** METHOD: sqlite3_stmt
 **
 ** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset
 ** the [sqlite3_bind_blob | bindings] on a [prepared statement].
 ** ^Use this routine to reset all host parameters to NULL.
 */
-SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
+SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt*);
 
 /*
 ** CAPI3REF: Number Of Columns In A Result Set
+** METHOD: sqlite3_stmt
 **
 ** ^Return the number of columns in the result set returned by the
 ** [prepared statement]. ^This routine returns 0 if pStmt is an SQL
@@ -3615,10 +3844,11 @@ SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
 **
 ** See also: [sqlite3_data_count()]
 */
-SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
+SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt);
 
 /*
 ** CAPI3REF: Column Names In A Result Set
+** METHOD: sqlite3_stmt
 **
 ** ^These routines return the name assigned to a particular column
 ** in the result set of a [SELECT] statement.  ^The sqlite3_column_name()
@@ -3643,11 +3873,12 @@ SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
 ** then the name of the column is unspecified and may change from
 ** one release of SQLite to the next.
 */
-SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N);
-SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_name(sqlite3_stmt*, int N);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt*, int N);
 
 /*
 ** CAPI3REF: Source Of Data In A Query Result
+** METHOD: sqlite3_stmt
 **
 ** ^These routines provide a means to determine the database, table, and
 ** table column that is the origin of a particular result column in
@@ -3691,15 +3922,16 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
 ** for the same [prepared statement] and result column
 ** at the same time then the results are undefined.
 */
-SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
-SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
-SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt*,int);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt*,int);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt*,int);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt*,int);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt*,int);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt*,int);
 
 /*
 ** CAPI3REF: Declared Datatype Of A Query Result
+** METHOD: sqlite3_stmt
 **
 ** ^(The first parameter is a [prepared statement].
 ** If this statement is a [SELECT] statement and the Nth column of the
@@ -3727,11 +3959,12 @@ SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
 ** is associated with individual values, not with the containers
 ** used to hold those values.
 */
-SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt*,int);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt*,int);
 
 /*
 ** CAPI3REF: Evaluate An SQL Statement
+** METHOD: sqlite3_stmt
 **
 ** After a [prepared statement] has been prepared using either
 ** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy
@@ -3807,10 +4040,11 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
 ** then the more specific [error codes] are returned directly
 ** by sqlite3_step().  The use of the "v2" interface is recommended.
 */
-SQLITE_API int sqlite3_step(sqlite3_stmt*);
+SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt*);
 
 /*
 ** CAPI3REF: Number of columns in a result set
+** METHOD: sqlite3_stmt
 **
 ** ^The sqlite3_data_count(P) interface returns the number of columns in the
 ** current row of the result set of [prepared statement] P.
@@ -3827,7 +4061,7 @@ SQLITE_API int sqlite3_step(sqlite3_stmt*);
 **
 ** See also: [sqlite3_column_count()]
 */
-SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
+SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt);
 
 /*
 ** CAPI3REF: Fundamental Datatypes
@@ -3864,6 +4098,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
 /*
 ** CAPI3REF: Result Values From A Query
 ** KEYWORDS: {column access functions}
+** METHOD: sqlite3_stmt
 **
 ** These routines form the "result set" interface.
 **
@@ -4023,19 +4258,20 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
 ** pointer.  Subsequent calls to [sqlite3_errcode()] will return
 ** [SQLITE_NOMEM].)^
 */
-SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
-SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
-SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
-SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt*, int iCol);
+SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt*, int iCol);
+SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
+SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt*, int iCol);
+SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt*, int iCol);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_column_int64(sqlite3_stmt*, int iCol);
+SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt*, int iCol);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_text16(sqlite3_stmt*, int iCol);
+SQLITE_API int SQLITE_STDCALL sqlite3_column_type(sqlite3_stmt*, int iCol);
+SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt*, int iCol);
 
 /*
 ** CAPI3REF: Destroy A Prepared Statement Object
+** DESTRUCTOR: sqlite3_stmt
 **
 ** ^The sqlite3_finalize() function is called to delete a [prepared statement].
 ** ^If the most recent evaluation of the statement encountered no errors
@@ -4059,10 +4295,11 @@ SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
 ** statement after it has been finalized can result in undefined and
 ** undesirable behavior such as segfaults and heap corruption.
 */
-SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
+SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt);
 
 /*
 ** CAPI3REF: Reset A Prepared Statement Object
+** METHOD: sqlite3_stmt
 **
 ** The sqlite3_reset() function is called to reset a [prepared statement]
 ** object back to its initial state, ready to be re-executed.
@@ -4085,13 +4322,14 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
 ** ^The [sqlite3_reset(S)] interface does not change the values
 ** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
 */
-SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
+SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt);
 
 /*
 ** CAPI3REF: Create Or Redefine SQL Functions
 ** KEYWORDS: {function creation routines}
 ** KEYWORDS: {application-defined SQL function}
 ** KEYWORDS: {application-defined SQL functions}
+** METHOD: sqlite3
 **
 ** ^These functions (collectively known as "function creation routines")
 ** are used to add SQL functions or aggregates or to redefine the behavior
@@ -4184,7 +4422,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
 ** close the database connection nor finalize or reset the prepared
 ** statement in which the function is running.
 */
-SQLITE_API int sqlite3_create_function(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_function(
   sqlite3 *db,
   const char *zFunctionName,
   int nArg,
@@ -4194,7 +4432,7 @@ SQLITE_API int sqlite3_create_function(
   void (*xStep)(sqlite3_context*,int,sqlite3_value**),
   void (*xFinal)(sqlite3_context*)
 );
-SQLITE_API int sqlite3_create_function16(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_function16(
   sqlite3 *db,
   const void *zFunctionName,
   int nArg,
@@ -4204,7 +4442,7 @@ SQLITE_API int sqlite3_create_function16(
   void (*xStep)(sqlite3_context*,int,sqlite3_value**),
   void (*xFinal)(sqlite3_context*)
 );
-SQLITE_API int sqlite3_create_function_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2(
   sqlite3 *db,
   const char *zFunctionName,
   int nArg,
@@ -4222,9 +4460,9 @@ SQLITE_API int sqlite3_create_function_v2(
 ** These constant define integer codes that represent the various
 ** text encodings supported by SQLite.
 */
-#define SQLITE_UTF8           1
-#define SQLITE_UTF16LE        2
-#define SQLITE_UTF16BE        3
+#define SQLITE_UTF8           1    /* IMP: R-37514-35566 */
+#define SQLITE_UTF16LE        2    /* IMP: R-03371-37637 */
+#define SQLITE_UTF16BE        3    /* IMP: R-51971-34154 */
 #define SQLITE_UTF16          4    /* Use native byte order */
 #define SQLITE_ANY            5    /* Deprecated */
 #define SQLITE_UTF16_ALIGNED  8    /* sqlite3_create_collation only */
@@ -4246,21 +4484,22 @@ SQLITE_API int sqlite3_create_function_v2(
 ** These functions are [deprecated].  In order to maintain
 ** backwards compatibility with older code, these functions continue 
 ** to be supported.  However, new applications should avoid
-** the use of these functions.  To help encourage people to avoid
-** using these functions, we are not going to tell you what they do.
+** the use of these functions.  To encourage programmers to avoid
+** these functions, we will not explain what they do.
 */
 #ifndef SQLITE_OMIT_DEPRECATED
-SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void);
-SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
+SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context*);
+SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt*);
+SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
+SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_global_recover(void);
+SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_thread_cleanup(void);
+SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
                       void*,sqlite3_int64);
 #endif
 
 /*
 ** CAPI3REF: Obtaining SQL Function Parameter Values
+** METHOD: sqlite3_value
 **
 ** The C-language implementation of SQL functions and aggregates uses
 ** this set of interface routines to access the parameter values on
@@ -4279,7 +4518,7 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
 ** object results in undefined behavior.
 **
 ** ^These routines work just like the corresponding [column access functions]
-** except that  these routines take a single [protected sqlite3_value] object
+** except that these routines take a single [protected sqlite3_value] object
 ** pointer instead of a [sqlite3_stmt*] pointer and an integer column number.
 **
 ** ^The sqlite3_value_text16() interface extracts a UTF-16 string
@@ -4304,21 +4543,22 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
 ** These routines must be called from the same thread as
 ** the SQL function that supplied the [sqlite3_value*] parameters.
 */
-SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
-SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
-SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
-SQLITE_API double sqlite3_value_double(sqlite3_value*);
-SQLITE_API int sqlite3_value_int(sqlite3_value*);
-SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
-SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*);
-SQLITE_API int sqlite3_value_type(sqlite3_value*);
-SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value*);
+SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value*);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value*);
+SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value*);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value*);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value*);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*);
 
 /*
 ** CAPI3REF: Obtain Aggregate Function Context
+** METHOD: sqlite3_context
 **
 ** Implementations of aggregate SQL functions use this
 ** routine to allocate memory for storing their state.
@@ -4359,10 +4599,11 @@ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
 ** This routine must be called from the same thread in which
 ** the aggregate SQL function is running.
 */
-SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
+SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context*, int nBytes);
 
 /*
 ** CAPI3REF: User Data For Functions
+** METHOD: sqlite3_context
 **
 ** ^The sqlite3_user_data() interface returns a copy of
 ** the pointer that was the pUserData parameter (the 5th parameter)
@@ -4373,10 +4614,11 @@ SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
 ** This routine must be called from the same thread in which
 ** the application-defined function is running.
 */
-SQLITE_API void *sqlite3_user_data(sqlite3_context*);
+SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context*);
 
 /*
 ** CAPI3REF: Database Connection For Functions
+** METHOD: sqlite3_context
 **
 ** ^The sqlite3_context_db_handle() interface returns a copy of
 ** the pointer to the [database connection] (the 1st parameter)
@@ -4384,10 +4626,11 @@ SQLITE_API void *sqlite3_user_data(sqlite3_context*);
 ** and [sqlite3_create_function16()] routines that originally
 ** registered the application defined function.
 */
-SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
+SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context*);
 
 /*
 ** CAPI3REF: Function Auxiliary Data
+** METHOD: sqlite3_context
 **
 ** These functions may be used by (non-aggregate) SQL functions to
 ** associate metadata with argument values. If the same value is passed to
@@ -4436,8 +4679,8 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
 ** These routines must be called from the same thread in which
 ** the SQL function is running.
 */
-SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
-SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
+SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context*, int N);
+SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
 
 
 /*
@@ -4460,6 +4703,7 @@ typedef void (*sqlite3_destructor_type)(void*);
 
 /*
 ** CAPI3REF: Setting The Result Of An SQL Function
+** METHOD: sqlite3_context
 **
 ** These routines are used by the xFunc or xFinal callbacks that
 ** implement SQL functions and aggregates.  See
@@ -4526,6 +4770,10 @@ typedef void (*sqlite3_destructor_type)(void*);
 ** set the return value of the application-defined function to be
 ** a text string which is represented as UTF-8, UTF-16 native byte order,
 ** UTF-16 little endian, or UTF-16 big endian, respectively.
+** ^The sqlite3_result_text64() interface sets the return value of an
+** application-defined function to be a text string in an encoding
+** specified by the fifth (and last) parameter, which must be one
+** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE].
 ** ^SQLite takes the text result from the application from
 ** the 2nd parameter of the sqlite3_result_text* interfaces.
 ** ^If the 3rd parameter to the sqlite3_result_text* interfaces
@@ -4568,25 +4816,30 @@ typedef void (*sqlite3_destructor_type)(void*);
 ** than the one containing the application-defined function that received
 ** the [sqlite3_context] pointer, the results are undefined.
 */
-SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
-SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
-SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int);
-SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*);
-SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*);
-SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int);
-SQLITE_API void sqlite3_result_int(sqlite3_context*, int);
-SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
-SQLITE_API void sqlite3_result_null(sqlite3_context*);
-SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
-SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64(sqlite3_context*,const void*,
+                           sqlite3_uint64,void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context*, double);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context*, const char*, int);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context*, const void*, int);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context*);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context*);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context*, int);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_int(sqlite3_context*, int);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context*);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
+                           void(*)(void*), unsigned char encoding);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context*, sqlite3_value*);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context*, int n);
 
 /*
 ** CAPI3REF: Define New Collating Sequences
+** METHOD: sqlite3
 **
 ** ^These functions add, remove, or modify a [collation] associated
 ** with the [database connection] specified as the first argument.
@@ -4664,14 +4917,14 @@ SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
 **
 ** See also:  [sqlite3_collation_needed()] and [sqlite3_collation_needed16()].
 */
-SQLITE_API int sqlite3_create_collation(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_collation(
   sqlite3*, 
   const char *zName, 
   int eTextRep, 
   void *pArg,
   int(*xCompare)(void*,int,const void*,int,const void*)
 );
-SQLITE_API int sqlite3_create_collation_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2(
   sqlite3*, 
   const char *zName, 
   int eTextRep, 
@@ -4679,7 +4932,7 @@ SQLITE_API int sqlite3_create_collation_v2(
   int(*xCompare)(void*,int,const void*,int,const void*),
   void(*xDestroy)(void*)
 );
-SQLITE_API int sqlite3_create_collation16(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16(
   sqlite3*, 
   const void *zName,
   int eTextRep, 
@@ -4689,6 +4942,7 @@ SQLITE_API int sqlite3_create_collation16(
 
 /*
 ** CAPI3REF: Collation Needed Callbacks
+** METHOD: sqlite3
 **
 ** ^To avoid having to register all collation sequences before a database
 ** can be used, a single callback function may be registered with the
@@ -4713,12 +4967,12 @@ SQLITE_API int sqlite3_create_collation16(
 ** [sqlite3_create_collation()], [sqlite3_create_collation16()], or
 ** [sqlite3_create_collation_v2()].
 */
-SQLITE_API int sqlite3_collation_needed(
+SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed(
   sqlite3*, 
   void*, 
   void(*)(void*,sqlite3*,int eTextRep,const char*)
 );
-SQLITE_API int sqlite3_collation_needed16(
+SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16(
   sqlite3*, 
   void*,
   void(*)(void*,sqlite3*,int eTextRep,const void*)
@@ -4732,11 +4986,11 @@ SQLITE_API int sqlite3_collation_needed16(
 ** The code to implement this API is not available in the public release
 ** of SQLite.
 */
-SQLITE_API int sqlite3_key(
+SQLITE_API int SQLITE_STDCALL sqlite3_key(
   sqlite3 *db,                   /* Database to be rekeyed */
   const void *pKey, int nKey     /* The key */
 );
-SQLITE_API int sqlite3_key_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_key_v2(
   sqlite3 *db,                   /* Database to be rekeyed */
   const char *zDbName,           /* Name of the database */
   const void *pKey, int nKey     /* The key */
@@ -4750,11 +5004,11 @@ SQLITE_API int sqlite3_key_v2(
 ** The code to implement this API is not available in the public release
 ** of SQLite.
 */
-SQLITE_API int sqlite3_rekey(
+SQLITE_API int SQLITE_STDCALL sqlite3_rekey(
   sqlite3 *db,                   /* Database to be rekeyed */
   const void *pKey, int nKey     /* The new key */
 );
-SQLITE_API int sqlite3_rekey_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_rekey_v2(
   sqlite3 *db,                   /* Database to be rekeyed */
   const char *zDbName,           /* Name of the database */
   const void *pKey, int nKey     /* The new key */
@@ -4764,7 +5018,7 @@ SQLITE_API int sqlite3_rekey_v2(
 ** Specify the activation key for a SEE database.  Unless 
 ** activated, none of the SEE routines will work.
 */
-SQLITE_API void sqlite3_activate_see(
+SQLITE_API void SQLITE_STDCALL sqlite3_activate_see(
   const char *zPassPhrase        /* Activation phrase */
 );
 #endif
@@ -4774,7 +5028,7 @@ SQLITE_API void sqlite3_activate_see(
 ** Specify the activation key for a CEROD database.  Unless 
 ** activated, none of the CEROD routines will work.
 */
-SQLITE_API void sqlite3_activate_cerod(
+SQLITE_API void SQLITE_STDCALL sqlite3_activate_cerod(
   const char *zPassPhrase        /* Activation phrase */
 );
 #endif
@@ -4796,7 +5050,7 @@ SQLITE_API void sqlite3_activate_cerod(
 ** all, then the behavior of sqlite3_sleep() may deviate from the description
 ** in the previous paragraphs.
 */
-SQLITE_API int sqlite3_sleep(int);
+SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int);
 
 /*
 ** CAPI3REF: Name Of The Folder Holding Temporary Files
@@ -4896,6 +5150,7 @@ SQLITE_API char *sqlite3_data_directory;
 /*
 ** CAPI3REF: Test For Auto-Commit Mode
 ** KEYWORDS: {autocommit mode}
+** METHOD: sqlite3
 **
 ** ^The sqlite3_get_autocommit() interface returns non-zero or
 ** zero if the given database connection is or is not in autocommit mode,
@@ -4914,10 +5169,11 @@ SQLITE_API char *sqlite3_data_directory;
 ** connection while this routine is running, then the return value
 ** is undefined.
 */
-SQLITE_API int sqlite3_get_autocommit(sqlite3*);
+SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3*);
 
 /*
 ** CAPI3REF: Find The Database Handle Of A Prepared Statement
+** METHOD: sqlite3_stmt
 **
 ** ^The sqlite3_db_handle interface returns the [database connection] handle
 ** to which a [prepared statement] belongs.  ^The [database connection]
@@ -4926,10 +5182,11 @@ SQLITE_API int sqlite3_get_autocommit(sqlite3*);
 ** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
 ** create the statement in the first place.
 */
-SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
+SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt*);
 
 /*
 ** CAPI3REF: Return The Filename For A Database Connection
+** METHOD: sqlite3
 **
 ** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename
 ** associated with database N of connection D.  ^The main database file
@@ -4942,19 +5199,21 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
 ** will be an absolute pathname, even if the filename used
 ** to open the database originally was a URI or relative pathname.
 */
-SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *zDbName);
 
 /*
 ** CAPI3REF: Determine if a database is read-only
+** METHOD: sqlite3
 **
 ** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N
 ** of connection D is read-only, 0 if it is read/write, or -1 if N is not
 ** the name of a database on connection D.
 */
-SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
+SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
 
 /*
 ** CAPI3REF: Find the next prepared statement
+** METHOD: sqlite3
 **
 ** ^This interface returns a pointer to the next [prepared statement] after
 ** pStmt associated with the [database connection] pDb.  ^If pStmt is NULL
@@ -4966,10 +5225,11 @@ SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
 ** [sqlite3_next_stmt(D,S)] must refer to an open database
 ** connection and in particular must not be a NULL pointer.
 */
-SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
+SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
 
 /*
 ** CAPI3REF: Commit And Rollback Notification Callbacks
+** METHOD: sqlite3
 **
 ** ^The sqlite3_commit_hook() interface registers a callback
 ** function to be invoked whenever a transaction is [COMMIT | committed].
@@ -5014,11 +5274,12 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
 **
 ** See also the [sqlite3_update_hook()] interface.
 */
-SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
-SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
+SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
+SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
 
 /*
 ** CAPI3REF: Data Change Notification Callbacks
+** METHOD: sqlite3
 **
 ** ^The sqlite3_update_hook() interface registers a callback function
 ** with the [database connection] identified by the first argument
@@ -5065,7 +5326,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
 ** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()]
 ** interfaces.
 */
-SQLITE_API void *sqlite3_update_hook(
+SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
   sqlite3*, 
   void(*)(void *,int ,char const *,char const *,sqlite3_int64),
   void*
@@ -5095,12 +5356,17 @@ SQLITE_API void *sqlite3_update_hook(
 ** future releases of SQLite.  Applications that care about shared
 ** cache setting should set it explicitly.
 **
+** Note: This method is disabled on MacOS X 10.7 and iOS version 5.0
+** and will always return SQLITE_MISUSE. On those systems, 
+** shared cache mode should be enabled per-database connection via 
+** [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE].
+**
 ** This interface is threadsafe on processors where writing a
 ** 32-bit integer is atomic.
 **
 ** See Also:  [SQLite Shared-Cache Mode]
 */
-SQLITE_API int sqlite3_enable_shared_cache(int);
+SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int);
 
 /*
 ** CAPI3REF: Attempt To Free Heap Memory
@@ -5116,10 +5382,11 @@ SQLITE_API int sqlite3_enable_shared_cache(int);
 **
 ** See also: [sqlite3_db_release_memory()]
 */
-SQLITE_API int sqlite3_release_memory(int);
+SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int);
 
 /*
 ** CAPI3REF: Free Memory Used By A Database Connection
+** METHOD: sqlite3
 **
 ** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap
 ** memory as possible from database connection D. Unlike the
@@ -5129,7 +5396,7 @@ SQLITE_API int sqlite3_release_memory(int);
 **
 ** See also: [sqlite3_release_memory()]
 */
-SQLITE_API int sqlite3_db_release_memory(sqlite3*);
+SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3*);
 
 /*
 ** CAPI3REF: Impose A Limit On Heap Size
@@ -5181,7 +5448,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*);
 ** The circumstances under which SQLite will enforce the soft heap limit may
 ** changes in future releases of SQLite.
 */
-SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 N);
 
 /*
 ** CAPI3REF: Deprecated Soft Heap Limit Interface
@@ -5192,26 +5459,34 @@ SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
 ** only.  All new applications should use the
 ** [sqlite3_soft_heap_limit64()] interface rather than this one.
 */
-SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
+SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_soft_heap_limit(int N);
 
 
 /*
 ** CAPI3REF: Extract Metadata About A Column Of A Table
-**
-** ^This routine returns metadata about a specific column of a specific
-** database table accessible using the [database connection] handle
-** passed as the first function argument.
+** METHOD: sqlite3
+**
+** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns
+** information about column C of table T in database D
+** on [database connection] X.)^  ^The sqlite3_table_column_metadata()
+** interface returns SQLITE_OK and fills in the non-NULL pointers in
+** the final five arguments with appropriate values if the specified
+** column exists.  ^The sqlite3_table_column_metadata() interface returns
+** SQLITE_ERROR and if the specified column does not exist.
+** ^If the column-name parameter to sqlite3_table_column_metadata() is a
+** NULL pointer, then this routine simply checks for the existance of the
+** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it
+** does not.
 **
 ** ^The column is identified by the second, third and fourth parameters to
-** this function. ^The second parameter is either the name of the database
+** this function. ^(The second parameter is either the name of the database
 ** (i.e. "main", "temp", or an attached database) containing the specified
-** table or NULL. ^If it is NULL, then all attached databases are searched
+** table or NULL.)^ ^If it is NULL, then all attached databases are searched
 ** for the table using the same algorithm used by the database engine to
 ** resolve unqualified table references.
 **
 ** ^The third and fourth parameters to this function are the table and column
-** name of the desired column, respectively. Neither of these parameters
-** may be NULL.
+** name of the desired column, respectively.
 **
 ** ^Metadata is returned by writing to the memory locations passed as the 5th
 ** and subsequent parameters to this function. ^Any of these arguments may be
@@ -5230,16 +5505,17 @@ SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
 ** </blockquote>)^
 **
 ** ^The memory pointed to by the character pointers returned for the
-** declaration type and collation sequence is valid only until the next
+** declaration type and collation sequence is valid until the next
 ** call to any SQLite API function.
 **
 ** ^If the specified table is actually a view, an [error code] is returned.
 **
-** ^If the specified column is "rowid", "oid" or "_rowid_" and an
+** ^If the specified column is "rowid", "oid" or "_rowid_" and the table 
+** is not a [WITHOUT ROWID] table and an
 ** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output
 ** parameters are set for the explicitly declared column. ^(If there is no
-** explicitly declared [INTEGER PRIMARY KEY] column, then the output
-** parameters are set as follows:
+** [INTEGER PRIMARY KEY] column, then the outputs
+** for the [rowid] are set as follows:
 **
 ** <pre>
 **     data type: "INTEGER"
@@ -5249,15 +5525,11 @@ SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
 **     auto increment: 0
 ** </pre>)^
 **
-** ^(This function may load one or more schemas from database files. If an
-** error occurs during this process, or if the requested table or column
-** cannot be found, an [error code] is returned and an error message left
-** in the [database connection] (to be retrieved using sqlite3_errmsg()).)^
-**
-** ^This API is only available if the library was compiled with the
-** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined.
+** ^This function causes all database schemas to be read from disk and
+** parsed, if that has not already been done, and returns an error if
+** any errors are encountered while loading the schema.
 */
-SQLITE_API int sqlite3_table_column_metadata(
+SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
   sqlite3 *db,                /* Connection handle */
   const char *zDbName,        /* Database name or NULL */
   const char *zTableName,     /* Table name */
@@ -5271,6 +5543,7 @@ SQLITE_API int sqlite3_table_column_metadata(
 
 /*
 ** CAPI3REF: Load An Extension
+** METHOD: sqlite3
 **
 ** ^This interface loads an SQLite extension library from the named file.
 **
@@ -5303,7 +5576,7 @@ SQLITE_API int sqlite3_table_column_metadata(
 **
 ** See also the [load_extension() SQL function].
 */
-SQLITE_API int sqlite3_load_extension(
+SQLITE_API int SQLITE_STDCALL sqlite3_load_extension(
   sqlite3 *db,          /* Load the extension into this database connection */
   const char *zFile,    /* Name of the shared library containing extension */
   const char *zProc,    /* Entry point.  Derived from zFile if 0 */
@@ -5312,6 +5585,7 @@ SQLITE_API int sqlite3_load_extension(
 
 /*
 ** CAPI3REF: Enable Or Disable Extension Loading
+** METHOD: sqlite3
 **
 ** ^So as not to open security holes in older applications that are
 ** unprepared to deal with [extension loading], and as a means of disabling
@@ -5323,7 +5597,7 @@ SQLITE_API int sqlite3_load_extension(
 ** to turn extension loading on and call it with onoff==0 to turn
 ** it back off again.
 */
-SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
+SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff);
 
 /*
 ** CAPI3REF: Automatically Load Statically Linked Extensions
@@ -5361,7 +5635,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
 ** See also: [sqlite3_reset_auto_extension()]
 ** and [sqlite3_cancel_auto_extension()]
 */
-SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
+SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xEntryPoint)(void));
 
 /*
 ** CAPI3REF: Cancel Automatic Extension Loading
@@ -5373,7 +5647,7 @@ SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
 ** unregistered and it returns 0 if X was not on the list of initialization
 ** routines.
 */
-SQLITE_API int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void));
+SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void (*xEntryPoint)(void));
 
 /*
 ** CAPI3REF: Reset Automatic Extension Loading
@@ -5381,7 +5655,7 @@ SQLITE_API int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void));
 ** ^This interface disables all automatic extensions previously
 ** registered using [sqlite3_auto_extension()].
 */
-SQLITE_API void sqlite3_reset_auto_extension(void);
+SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void);
 
 /*
 ** The interface to the virtual-table mechanism is currently considered
@@ -5561,6 +5835,7 @@ struct sqlite3_index_info {
 
 /*
 ** CAPI3REF: Register A Virtual Table Implementation
+** METHOD: sqlite3
 **
 ** ^These routines are used to register a new [virtual table module] name.
 ** ^Module names must be registered before
@@ -5584,13 +5859,13 @@ struct sqlite3_index_info {
 ** interface is equivalent to sqlite3_create_module_v2() with a NULL
 ** destructor.
 */
-SQLITE_API int sqlite3_create_module(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_module(
   sqlite3 *db,               /* SQLite connection to register module with */
   const char *zName,         /* Name of the module */
   const sqlite3_module *p,   /* Methods for the module */
   void *pClientData          /* Client data for xCreate/xConnect */
 );
-SQLITE_API int sqlite3_create_module_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_module_v2(
   sqlite3 *db,               /* SQLite connection to register module with */
   const char *zName,         /* Name of the module */
   const sqlite3_module *p,   /* Methods for the module */
@@ -5618,7 +5893,7 @@ SQLITE_API int sqlite3_create_module_v2(
 */
 struct sqlite3_vtab {
   const sqlite3_module *pModule;  /* The module for this virtual table */
-  int nRef;                       /* NO LONGER USED */
+  int nRef;                       /* Number of open cursors */
   char *zErrMsg;                  /* Error message from sqlite3_mprintf() */
   /* Virtual table implementations will typically add additional fields */
 };
@@ -5653,10 +5928,11 @@ struct sqlite3_vtab_cursor {
 ** to declare the format (the names and datatypes of the columns) of
 ** the virtual tables they implement.
 */
-SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
+SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3*, const char *zSQL);
 
 /*
 ** CAPI3REF: Overload A Function For A Virtual Table
+** METHOD: sqlite3
 **
 ** ^(Virtual tables can provide alternative implementations of functions
 ** using the [xFindFunction] method of the [virtual table module].  
@@ -5671,7 +5947,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
 ** purpose is to be a placeholder function that can be overloaded
 ** by a [virtual table].
 */
-SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
+SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
 
 /*
 ** The interface to the virtual-table mechanism defined above (back up
@@ -5699,6 +5975,8 @@ typedef struct sqlite3_blob sqlite3_blob;
 
 /*
 ** CAPI3REF: Open A BLOB For Incremental I/O
+** METHOD: sqlite3
+** CONSTRUCTOR: sqlite3_blob
 **
 ** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located
 ** in row iRow, column zColumn, table zTable in database zDb;
@@ -5708,26 +5986,42 @@ typedef struct sqlite3_blob sqlite3_blob;
 **     SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
 ** </pre>)^
 **
+** ^(Parameter zDb is not the filename that contains the database, but 
+** rather the symbolic name of the database. For attached databases, this is
+** the name that appears after the AS keyword in the [ATTACH] statement.
+** For the main database file, the database name is "main". For TEMP
+** tables, the database name is "temp".)^
+**
 ** ^If the flags parameter is non-zero, then the BLOB is opened for read
-** and write access. ^If it is zero, the BLOB is opened for read access.
-** ^It is not possible to open a column that is part of an index or primary 
-** key for writing. ^If [foreign key constraints] are enabled, it is 
-** not possible to open a column that is part of a [child key] for writing.
-**
-** ^Note that the database name is not the filename that contains
-** the database but rather the symbolic name of the database that
-** appears after the AS keyword when the database is connected using [ATTACH].
-** ^For the main database file, the database name is "main".
-** ^For TEMP tables, the database name is "temp".
-**
-** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is written
-** to *ppBlob. Otherwise an [error code] is returned and *ppBlob is set
-** to be a null pointer.)^
-** ^This function sets the [database connection] error code and message
-** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()] and related
-** functions. ^Note that the *ppBlob variable is always initialized in a
-** way that makes it safe to invoke [sqlite3_blob_close()] on *ppBlob
-** regardless of the success or failure of this routine.
+** and write access. ^If the flags parameter is zero, the BLOB is opened for
+** read-only access.
+**
+** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored
+** in *ppBlob. Otherwise an [error code] is returned and, unless the error
+** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided
+** the API is not misused, it is always safe to call [sqlite3_blob_close()] 
+** on *ppBlob after this function it returns.
+**
+** This function fails with SQLITE_ERROR if any of the following are true:
+** <ul>
+**   <li> ^(Database zDb does not exist)^, 
+**   <li> ^(Table zTable does not exist within database zDb)^, 
+**   <li> ^(Table zTable is a WITHOUT ROWID table)^, 
+**   <li> ^(Column zColumn does not exist)^,
+**   <li> ^(Row iRow is not present in the table)^,
+**   <li> ^(The specified column of row iRow contains a value that is not
+**         a TEXT or BLOB value)^,
+**   <li> ^(Column zColumn is part of an index, PRIMARY KEY or UNIQUE 
+**         constraint and the blob is being opened for read/write access)^,
+**   <li> ^([foreign key constraints | Foreign key constraints] are enabled, 
+**         column zColumn is part of a [child key] definition and the blob is
+**         being opened for read/write access)^.
+** </ul>
+**
+** ^Unless it returns SQLITE_MISUSE, this function sets the 
+** [database connection] error code and message accessible via 
+** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. 
+**
 **
 ** ^(If the row that a BLOB handle points to is modified by an
 ** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
@@ -5745,18 +6039,14 @@ typedef struct sqlite3_blob sqlite3_blob;
 ** interface.  Use the [UPDATE] SQL command to change the size of a
 ** blob.
 **
-** ^The [sqlite3_blob_open()] interface will fail for a [WITHOUT ROWID]
-** table.  Incremental BLOB I/O is not possible on [WITHOUT ROWID] tables.
-**
 ** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
-** and the built-in [zeroblob] SQL function can be used, if desired,
-** to create an empty, zero-filled blob in which to read or write using
-** this interface.
+** and the built-in [zeroblob] SQL function may be used to create a 
+** zero-filled blob to read or write using the incremental-blob interface.
 **
 ** To avoid a resource leak, every open [BLOB handle] should eventually
 ** be released by a call to [sqlite3_blob_close()].
 */
-SQLITE_API int sqlite3_blob_open(
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
   sqlite3*,
   const char *zDb,
   const char *zTable,
@@ -5768,6 +6058,7 @@ SQLITE_API int sqlite3_blob_open(
 
 /*
 ** CAPI3REF: Move a BLOB Handle to a New Row
+** METHOD: sqlite3_blob
 **
 ** ^This function is used to move an existing blob handle so that it points
 ** to a different row of the same database table. ^The new row is identified
@@ -5788,34 +6079,34 @@ SQLITE_API int sqlite3_blob_open(
 **
 ** ^This function sets the database handle error code and message.
 */
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
+SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
 
 /*
 ** CAPI3REF: Close A BLOB Handle
+** DESTRUCTOR: sqlite3_blob
 **
-** ^Closes an open [BLOB handle].
+** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed
+** unconditionally.  Even if this routine returns an error code, the 
+** handle is still closed.)^
 **
-** ^Closing a BLOB shall cause the current transaction to commit
-** if there are no other BLOBs, no pending prepared statements, and the
-** database connection is in [autocommit mode].
-** ^If any writes were made to the BLOB, they might be held in cache
-** until the close operation if they will fit.
+** ^If the blob handle being closed was opened for read-write access, and if
+** the database is in auto-commit mode and there are no other open read-write
+** blob handles or active write statements, the current transaction is
+** committed. ^If an error occurs while committing the transaction, an error
+** code is returned and the transaction rolled back.
 **
-** ^(Closing the BLOB often forces the changes
-** out to disk and so if any I/O errors occur, they will likely occur
-** at the time when the BLOB is closed.  Any errors that occur during
-** closing are reported as a non-zero return value.)^
-**
-** ^(The BLOB is closed unconditionally.  Even if this routine returns
-** an error code, the BLOB is still closed.)^
-**
-** ^Calling this routine with a null pointer (such as would be returned
-** by a failed call to [sqlite3_blob_open()]) is a harmless no-op.
+** Calling this function with an argument that is not a NULL pointer or an
+** open blob handle results in undefined behaviour. ^Calling this routine 
+** with a null pointer (such as would be returned by a failed call to 
+** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function
+** is passed a valid open blob handle, the values returned by the 
+** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning.
 */
-SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *);
 
 /*
 ** CAPI3REF: Return The Size Of An Open BLOB
+** METHOD: sqlite3_blob
 **
 ** ^Returns the size in bytes of the BLOB accessible via the 
 ** successfully opened [BLOB handle] in its only argument.  ^The
@@ -5827,10 +6118,11 @@ SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
 ** been closed by [sqlite3_blob_close()].  Passing any other pointer in
 ** to this routine results in undefined and probably undesirable behavior.
 */
-SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *);
 
 /*
 ** CAPI3REF: Read Data From A BLOB Incrementally
+** METHOD: sqlite3_blob
 **
 ** ^(This function is used to read data from an open [BLOB handle] into a
 ** caller-supplied buffer. N bytes of data are copied into buffer Z
@@ -5855,26 +6147,33 @@ SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
 **
 ** See also: [sqlite3_blob_write()].
 */
-SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
 
 /*
 ** CAPI3REF: Write Data Into A BLOB Incrementally
+** METHOD: sqlite3_blob
 **
-** ^This function is used to write data into an open [BLOB handle] from a
-** caller-supplied buffer. ^N bytes of data are copied from the buffer Z
-** into the open BLOB, starting at offset iOffset.
+** ^(This function is used to write data into an open [BLOB handle] from a
+** caller-supplied buffer. N bytes of data are copied from the buffer Z
+** into the open BLOB, starting at offset iOffset.)^
+**
+** ^(On success, sqlite3_blob_write() returns SQLITE_OK.
+** Otherwise, an  [error code] or an [extended error code] is returned.)^
+** ^Unless SQLITE_MISUSE is returned, this function sets the 
+** [database connection] error code and message accessible via 
+** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. 
 **
 ** ^If the [BLOB handle] passed as the first argument was not opened for
 ** writing (the flags parameter to [sqlite3_blob_open()] was zero),
 ** this function returns [SQLITE_READONLY].
 **
-** ^This function may only modify the contents of the BLOB; it is
+** This function may only modify the contents of the BLOB; it is
 ** not possible to increase the size of a BLOB using this API.
 ** ^If offset iOffset is less than N bytes from the end of the BLOB,
-** [SQLITE_ERROR] is returned and no data is written.  ^If N is
-** less than zero [SQLITE_ERROR] is returned and no data is written.
-** The size of the BLOB (and hence the maximum value of N+iOffset)
-** can be determined using the [sqlite3_blob_bytes()] interface.
+** [SQLITE_ERROR] is returned and no data is written. The size of the 
+** BLOB (and hence the maximum value of N+iOffset) can be determined 
+** using the [sqlite3_blob_bytes()] interface. ^If N or iOffset are less 
+** than zero [SQLITE_ERROR] is returned and no data is written.
 **
 ** ^An attempt to write to an expired [BLOB handle] fails with an
 ** error code of [SQLITE_ABORT].  ^Writes to the BLOB that occurred
@@ -5883,9 +6182,6 @@ SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
 ** have been overwritten by the statement that expired the BLOB handle
 ** or by other independent statements.
 **
-** ^(On success, sqlite3_blob_write() returns SQLITE_OK.
-** Otherwise, an  [error code] or an [extended error code] is returned.)^
-**
 ** This routine only works on a [BLOB handle] which has been created
 ** by a prior successful call to [sqlite3_blob_open()] and which has not
 ** been closed by [sqlite3_blob_close()].  Passing any other pointer in
@@ -5893,7 +6189,7 @@ SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
 **
 ** See also: [sqlite3_blob_read()].
 */
-SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
 
 /*
 ** CAPI3REF: Virtual File System Objects
@@ -5924,9 +6220,9 @@ SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOff
 ** ^(If the default VFS is unregistered, another VFS is chosen as
 ** the default.  The choice for the new VFS is arbitrary.)^
 */
-SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName);
-SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
-SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
+SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfsName);
+SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
+SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs*);
 
 /*
 ** CAPI3REF: Mutexes
@@ -5938,34 +6234,34 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
 **
 ** The SQLite source code contains multiple implementations
 ** of these mutex routines.  An appropriate implementation
-** is selected automatically at compile-time.  ^(The following
+** is selected automatically at compile-time.  The following
 ** implementations are available in the SQLite core:
 **
 ** <ul>
 ** <li>   SQLITE_MUTEX_PTHREADS
 ** <li>   SQLITE_MUTEX_W32
 ** <li>   SQLITE_MUTEX_NOOP
-** </ul>)^
+** </ul>
 **
-** ^The SQLITE_MUTEX_NOOP implementation is a set of routines
+** The SQLITE_MUTEX_NOOP implementation is a set of routines
 ** that does no real locking and is appropriate for use in
-** a single-threaded application.  ^The SQLITE_MUTEX_PTHREADS and
+** a single-threaded application.  The SQLITE_MUTEX_PTHREADS and
 ** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix
 ** and Windows.
 **
-** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
+** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
 ** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
 ** implementation is included with the library. In this case the
 ** application must supply a custom mutex implementation using the
 ** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function
 ** before calling sqlite3_initialize() or any other public sqlite3_
-** function that calls sqlite3_initialize().)^
+** function that calls sqlite3_initialize().
 **
 ** ^The sqlite3_mutex_alloc() routine allocates a new
-** mutex and returns a pointer to it. ^If it returns NULL
-** that means that a mutex could not be allocated.  ^SQLite
-** will unwind its stack and return an error.  ^(The argument
-** to sqlite3_mutex_alloc() is one of these integer constants:
+** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc()
+** routine returns NULL if it is unable to allocate the requested
+** mutex.  The argument to sqlite3_mutex_alloc() must one of these
+** integer constants:
 **
 ** <ul>
 ** <li>  SQLITE_MUTEX_FAST
@@ -5978,7 +6274,8 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
 ** <li>  SQLITE_MUTEX_STATIC_PMEM
 ** <li>  SQLITE_MUTEX_STATIC_APP1
 ** <li>  SQLITE_MUTEX_STATIC_APP2
-** </ul>)^
+** <li>  SQLITE_MUTEX_STATIC_APP3
+** </ul>
 **
 ** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
 ** cause sqlite3_mutex_alloc() to create
@@ -5986,14 +6283,14 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
 ** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
 ** The mutex implementation does not need to make a distinction
 ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
-** not want to.  ^SQLite will only request a recursive mutex in
-** cases where it really needs one.  ^If a faster non-recursive mutex
+** not want to.  SQLite will only request a recursive mutex in
+** cases where it really needs one.  If a faster non-recursive mutex
 ** implementation is available on the host platform, the mutex subsystem
 ** might return such a mutex in response to SQLITE_MUTEX_FAST.
 **
 ** ^The other allowed parameters to sqlite3_mutex_alloc() (anything other
 ** than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return
-** a pointer to a static preexisting mutex.  ^Six static mutexes are
+** a pointer to a static preexisting mutex.  ^Nine static mutexes are
 ** used by the current version of SQLite.  Future versions of SQLite
 ** may add additional static mutexes.  Static mutexes are for internal
 ** use by SQLite only.  Applications that use SQLite mutexes should
@@ -6002,16 +6299,13 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
 **
 ** ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
 ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
-** returns a different mutex on every call.  ^But for the static
+** returns a different mutex on every call.  ^For the static
 ** mutex types, the same mutex is returned on every call that has
 ** the same type number.
 **
 ** ^The sqlite3_mutex_free() routine deallocates a previously
-** allocated dynamic mutex.  ^SQLite is careful to deallocate every
-** dynamic mutex that it allocates.  The dynamic mutexes must not be in
-** use when they are deallocated.  Attempting to deallocate a static
-** mutex results in undefined behavior.  ^SQLite never deallocates
-** a static mutex.
+** allocated dynamic mutex.  Attempting to deallocate a static
+** mutex results in undefined behavior.
 **
 ** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
 ** to enter a mutex.  ^If another thread is already within the mutex,
@@ -6019,23 +6313,21 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
 ** SQLITE_BUSY.  ^The sqlite3_mutex_try() interface returns [SQLITE_OK]
 ** upon successful entry.  ^(Mutexes created using
 ** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread.
-** In such cases the,
+** In such cases, the
 ** mutex must be exited an equal number of times before another thread
-** can enter.)^  ^(If the same thread tries to enter any other
-** kind of mutex more than once, the behavior is undefined.
-** SQLite will never exhibit
-** such behavior in its own use of mutexes.)^
+** can enter.)^  If the same thread tries to enter any mutex other
+** than an SQLITE_MUTEX_RECURSIVE more than once, the behavior is undefined.
 **
 ** ^(Some systems (for example, Windows 95) do not support the operation
 ** implemented by sqlite3_mutex_try().  On those systems, sqlite3_mutex_try()
-** will always return SQLITE_BUSY.  The SQLite core only ever uses
-** sqlite3_mutex_try() as an optimization so this is acceptable behavior.)^
+** will always return SQLITE_BUSY. The SQLite core only ever uses
+** sqlite3_mutex_try() as an optimization so this is acceptable 
+** behavior.)^
 **
 ** ^The sqlite3_mutex_leave() routine exits a mutex that was
-** previously entered by the same thread.   ^(The behavior
+** previously entered by the same thread.   The behavior
 ** is undefined if the mutex is not currently entered by the
-** calling thread or is not currently allocated.  SQLite will
-** never do either.)^
+** calling thread or is not currently allocated.
 **
 ** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or
 ** sqlite3_mutex_leave() is a NULL pointer, then all three routines
@@ -6043,11 +6335,11 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
 **
 ** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
 */
-SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
-SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
-SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
-SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
-SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
+SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int);
+SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex*);
+SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex*);
+SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex*);
+SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex*);
 
 /*
 ** CAPI3REF: Mutex Methods Object
@@ -6056,9 +6348,9 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
 ** used to allocate and use mutexes.
 **
 ** Usually, the default mutex implementations provided by SQLite are
-** sufficient, however the user has the option of substituting a custom
+** sufficient, however the application has the option of substituting a custom
 ** implementation for specialized deployments or systems for which SQLite
-** does not provide a suitable implementation. In this case, the user
+** does not provide a suitable implementation. In this case, the application
 ** creates and populates an instance of this structure to pass
 ** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option.
 ** Additionally, an instance of this structure can be used as an
@@ -6099,13 +6391,13 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
 ** (i.e. it is acceptable to provide an implementation that segfaults if
 ** it is passed a NULL pointer).
 **
-** The xMutexInit() method must be threadsafe.  ^It must be harmless to
+** The xMutexInit() method must be threadsafe.  It must be harmless to
 ** invoke xMutexInit() multiple times within the same process and without
 ** intervening calls to xMutexEnd().  Second and subsequent calls to
 ** xMutexInit() must be no-ops.
 **
-** ^xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()]
-** and its associates).  ^Similarly, xMutexAlloc() must not use SQLite memory
+** xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()]
+** and its associates).  Similarly, xMutexAlloc() must not use SQLite memory
 ** allocation for a static mutex.  ^However xMutexAlloc() may use SQLite
 ** memory allocation for a fast or recursive mutex.
 **
@@ -6131,34 +6423,34 @@ struct sqlite3_mutex_methods {
 ** CAPI3REF: Mutex Verification Routines
 **
 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines
-** are intended for use inside assert() statements.  ^The SQLite core
+** are intended for use inside assert() statements.  The SQLite core
 ** never uses these routines except inside an assert() and applications
-** are advised to follow the lead of the core.  ^The SQLite core only
+** are advised to follow the lead of the core.  The SQLite core only
 ** provides implementations for these routines when it is compiled
-** with the SQLITE_DEBUG flag.  ^External mutex implementations
+** with the SQLITE_DEBUG flag.  External mutex implementations
 ** are only required to provide these routines if SQLITE_DEBUG is
 ** defined and if NDEBUG is not defined.
 **
-** ^These routines should return true if the mutex in their argument
+** These routines should return true if the mutex in their argument
 ** is held or not held, respectively, by the calling thread.
 **
-** ^The implementation is not required to provide versions of these
+** The implementation is not required to provide versions of these
 ** routines that actually work. If the implementation does not provide working
 ** versions of these routines, it should at least provide stubs that always
 ** return true so that one does not get spurious assertion failures.
 **
-** ^If the argument to sqlite3_mutex_held() is a NULL pointer then
+** If the argument to sqlite3_mutex_held() is a NULL pointer then
 ** the routine should return 1.   This seems counter-intuitive since
 ** clearly the mutex cannot be held if it does not exist.  But
 ** the reason the mutex does not exist is because the build is not
 ** using mutexes.  And we do not want the assert() containing the
 ** call to sqlite3_mutex_held() to fail, so a non-zero return is
-** the appropriate thing to do.  ^The sqlite3_mutex_notheld()
+** the appropriate thing to do.  The sqlite3_mutex_notheld()
 ** interface should also return 1 when given a NULL pointer.
 */
 #ifndef NDEBUG
-SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
-SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
+SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex*);
+SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex*);
 #endif
 
 /*
@@ -6187,6 +6479,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
 
 /*
 ** CAPI3REF: Retrieve the mutex for a database connection
+** METHOD: sqlite3
 **
 ** ^This interface returns a pointer the [sqlite3_mutex] object that 
 ** serializes access to the [database connection] given in the argument
@@ -6194,10 +6487,11 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
 ** ^If the [threading mode] is Single-thread or Multi-thread then this
 ** routine returns a NULL pointer.
 */
-SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
+SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3*);
 
 /*
 ** CAPI3REF: Low-Level Control Of Database Files
+** METHOD: sqlite3
 **
 ** ^The [sqlite3_file_control()] interface makes a direct call to the
 ** xFileControl method for the [sqlite3_io_methods] object associated
@@ -6228,7 +6522,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
 **
 ** See also: [SQLITE_FCNTL_LOCKSTATE]
 */
-SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
+SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
 
 /*
 ** CAPI3REF: Testing Interface
@@ -6247,7 +6541,7 @@ SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*
 ** Unlike most of the SQLite API, this function is not guaranteed to
 ** operate consistently from one release to the next.
 */
-SQLITE_API int sqlite3_test_control(int op, ...);
+SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...);
 
 /*
 ** CAPI3REF: Testing Interface Operation Codes
@@ -6275,17 +6569,19 @@ SQLITE_API int sqlite3_test_control(int op, ...);
 #define SQLITE_TESTCTRL_ISKEYWORD               16
 #define SQLITE_TESTCTRL_SCRATCHMALLOC           17
 #define SQLITE_TESTCTRL_LOCALTIME_FAULT         18
-#define SQLITE_TESTCTRL_EXPLAIN_STMT            19
+#define SQLITE_TESTCTRL_EXPLAIN_STMT            19  /* NOT USED */
 #define SQLITE_TESTCTRL_NEVER_CORRUPT           20
 #define SQLITE_TESTCTRL_VDBE_COVERAGE           21
 #define SQLITE_TESTCTRL_BYTEORDER               22
 #define SQLITE_TESTCTRL_ISINIT                  23
-#define SQLITE_TESTCTRL_LAST                    23
+#define SQLITE_TESTCTRL_SORTER_MMAP             24
+#define SQLITE_TESTCTRL_IMPOSTER                25
+#define SQLITE_TESTCTRL_LAST                    25
 
 /*
 ** CAPI3REF: SQLite Runtime Status
 **
-** ^This interface is used to retrieve runtime status information
+** ^These interfaces are used to retrieve runtime status information
 ** about the performance of SQLite, and optionally to reset various
 ** highwater marks.  ^The first argument is an integer code for
 ** the specific parameter to measure.  ^(Recognized integer codes
@@ -6299,19 +6595,22 @@ SQLITE_API int sqlite3_test_control(int op, ...);
 ** ^(Other parameters record only the highwater mark and not the current
 ** value.  For these latter parameters nothing is written into *pCurrent.)^
 **
-** ^The sqlite3_status() routine returns SQLITE_OK on success and a
-** non-zero [error code] on failure.
+** ^The sqlite3_status() and sqlite3_status64() routines return
+** SQLITE_OK on success and a non-zero [error code] on failure.
 **
-** This routine is threadsafe but is not atomic.  This routine can be
-** called while other threads are running the same or different SQLite
-** interfaces.  However the values returned in *pCurrent and
-** *pHighwater reflect the status of SQLite at different points in time
-** and it is possible that another thread might change the parameter
-** in between the times when *pCurrent and *pHighwater are written.
+** If either the current value or the highwater mark is too large to
+** be represented by a 32-bit integer, then the values returned by
+** sqlite3_status() are undefined.
 **
 ** See also: [sqlite3_db_status()]
 */
-SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
+SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
+SQLITE_API int SQLITE_STDCALL sqlite3_status64(
+  int op,
+  sqlite3_int64 *pCurrent,
+  sqlite3_int64 *pHighwater,
+  int resetFlag
+);
 
 
 /*
@@ -6409,6 +6708,7 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF
 
 /*
 ** CAPI3REF: Database Connection Status
+** METHOD: sqlite3
 **
 ** ^This interface is used to retrieve runtime status information 
 ** about a single [database connection].  ^The first argument is the
@@ -6429,7 +6729,7 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF
 **
 ** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
 */
-SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
+SQLITE_API int SQLITE_STDCALL sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
 
 /*
 ** CAPI3REF: Status Parameters for database connections
@@ -6471,12 +6771,12 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
 ** the current value is always zero.)^
 **
 ** [[SQLITE_DBSTATUS_CACHE_USED]] ^(<dt>SQLITE_DBSTATUS_CACHE_USED</dt>
-** <dd>This parameter returns the approximate number of of bytes of heap
+** <dd>This parameter returns the approximate number of bytes of heap
 ** memory used by all pager caches associated with the database connection.)^
 ** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0.
 **
 ** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt>
-** <dd>This parameter returns the approximate number of of bytes of heap
+** <dd>This parameter returns the approximate number of bytes of heap
 ** memory used to store the schema for all databases associated
 ** with the connection - main, temp, and any [ATTACH]-ed databases.)^ 
 ** ^The full amount of memory used by the schemas is reported, even if the
@@ -6485,7 +6785,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
 ** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0.
 **
 ** [[SQLITE_DBSTATUS_STMT_USED]] ^(<dt>SQLITE_DBSTATUS_STMT_USED</dt>
-** <dd>This parameter returns the approximate number of of bytes of heap
+** <dd>This parameter returns the approximate number of bytes of heap
 ** and lookaside memory used by all prepared statements associated with
 ** the database connection.)^
 ** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0.
@@ -6537,6 +6837,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
 
 /*
 ** CAPI3REF: Prepared Statement Status
+** METHOD: sqlite3_stmt
 **
 ** ^(Each prepared statement maintains various
 ** [SQLITE_STMTSTATUS counters] that measure the number
@@ -6558,7 +6859,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
 **
 ** See also: [sqlite3_status()] and [sqlite3_db_status()].
 */
-SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
+SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
 
 /*
 ** CAPI3REF: Status Parameters for prepared statements
@@ -6885,6 +7186,10 @@ typedef struct sqlite3_backup sqlite3_backup;
 ** must be different or else sqlite3_backup_init(D,N,S,M) will fail with
 ** an error.
 **
+** ^A call to sqlite3_backup_init() will fail, returning SQLITE_ERROR, if 
+** there is already a read or read-write transaction open on the 
+** destination database.
+**
 ** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is
 ** returned and an error code and error message are stored in the
 ** destination [database connection] D.
@@ -6977,20 +7282,20 @@ typedef struct sqlite3_backup sqlite3_backup;
 ** is not a permanent error and does not affect the return value of
 ** sqlite3_backup_finish().
 **
-** [[sqlite3_backup__remaining()]] [[sqlite3_backup_pagecount()]]
+** [[sqlite3_backup_remaining()]] [[sqlite3_backup_pagecount()]]
 ** <b>sqlite3_backup_remaining() and sqlite3_backup_pagecount()</b>
 **
-** ^Each call to sqlite3_backup_step() sets two values inside
-** the [sqlite3_backup] object: the number of pages still to be backed
-** up and the total number of pages in the source database file.
-** The sqlite3_backup_remaining() and sqlite3_backup_pagecount() interfaces
-** retrieve these two values, respectively.
-**
-** ^The values returned by these functions are only updated by
-** sqlite3_backup_step(). ^If the source database is modified during a backup
-** operation, then the values are not updated to account for any extra
-** pages that need to be updated or the size of the source database file
-** changing.
+** ^The sqlite3_backup_remaining() routine returns the number of pages still
+** to be backed up at the conclusion of the most recent sqlite3_backup_step().
+** ^The sqlite3_backup_pagecount() routine returns the total number of pages
+** in the source database at the conclusion of the most recent
+** sqlite3_backup_step().
+** ^(The values returned by these functions are only updated by
+** sqlite3_backup_step(). If the source database is modified in a way that
+** changes the size of the source database or the number of pages remaining,
+** those changes are not reflected in the output of sqlite3_backup_pagecount()
+** and sqlite3_backup_remaining() until after the next
+** sqlite3_backup_step().)^
 **
 ** <b>Concurrent Usage of Database Handles</b>
 **
@@ -7023,19 +7328,20 @@ typedef struct sqlite3_backup sqlite3_backup;
 ** same time as another thread is invoking sqlite3_backup_step() it is
 ** possible that they return invalid values.
 */
-SQLITE_API sqlite3_backup *sqlite3_backup_init(
+SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init(
   sqlite3 *pDest,                        /* Destination database handle */
   const char *zDestName,                 /* Destination database name */
   sqlite3 *pSource,                      /* Source database handle */
   const char *zSourceName                /* Source database name */
 );
-SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage);
-SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p);
-SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p);
-SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
+SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage);
+SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p);
+SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p);
+SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p);
 
 /*
 ** CAPI3REF: Unlock Notification
+** METHOD: sqlite3
 **
 ** ^When running in shared-cache mode, a database operation may fail with
 ** an [SQLITE_LOCKED] error if the required locks on the shared-cache or
@@ -7148,7 +7454,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
 ** the special "DROP TABLE/INDEX" case, the extended error code is just 
 ** SQLITE_LOCKED.)^
 */
-SQLITE_API int sqlite3_unlock_notify(
+SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify(
   sqlite3 *pBlocked,                          /* Waiting connection */
   void (*xNotify)(void **apArg, int nArg),    /* Callback function to invoke */
   void *pNotifyArg                            /* Argument to pass to xNotify */
@@ -7163,8 +7469,8 @@ SQLITE_API int sqlite3_unlock_notify(
 ** strings in a case-independent fashion, using the same definition of "case
 ** independence" that SQLite uses internally when comparing identifiers.
 */
-SQLITE_API int sqlite3_stricmp(const char *, const char *);
-SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
+SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *, const char *);
+SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *, const char *, int);
 
 /*
 ** CAPI3REF: String Globbing
@@ -7179,7 +7485,7 @@ SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
 ** Note that this routine returns zero on a match and non-zero if the strings
 ** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
 */
-SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr);
+SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlob, const char *zStr);
 
 /*
 ** CAPI3REF: Error Logging Interface
@@ -7202,18 +7508,17 @@ SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr);
 ** a few hundred characters, it will be truncated to the length of the
 ** buffer.
 */
-SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
+SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...);
 
 /*
 ** CAPI3REF: Write-Ahead Log Commit Hook
+** METHOD: sqlite3
 **
 ** ^The [sqlite3_wal_hook()] function is used to register a callback that
-** will be invoked each time a database connection commits data to a
-** [write-ahead log] (i.e. whenever a transaction is committed in
-** [journal_mode | journal_mode=WAL mode]). 
+** is invoked each time data is committed to a database in wal mode.
 **
-** ^The callback is invoked by SQLite after the commit has taken place and 
-** the associated write-lock on the database released, so the implementation 
+** ^(The callback is invoked by SQLite after the commit has taken place and 
+** the associated write-lock on the database released)^, so the implementation 
 ** may read, write or [checkpoint] the database as required.
 **
 ** ^The first parameter passed to the callback function when it is invoked
@@ -7239,7 +7544,7 @@ SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
 ** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
 ** those overwrite any prior [sqlite3_wal_hook()] settings.
 */
-SQLITE_API void *sqlite3_wal_hook(
+SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook(
   sqlite3*, 
   int(*)(void *,sqlite3*,const char*,int),
   void*
@@ -7247,6 +7552,7 @@ SQLITE_API void *sqlite3_wal_hook(
 
 /*
 ** CAPI3REF: Configure an auto-checkpoint
+** METHOD: sqlite3
 **
 ** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around
 ** [sqlite3_wal_hook()] that causes any database on [database connection] D
@@ -7273,104 +7579,123 @@ SQLITE_API void *sqlite3_wal_hook(
 ** is only necessary if the default setting is found to be suboptimal
 ** for a particular application.
 */
-SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
+SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
 
 /*
 ** CAPI3REF: Checkpoint a database
+** METHOD: sqlite3
 **
-** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X
-** on [database connection] D to be [checkpointed].  ^If X is NULL or an
-** empty string, then a checkpoint is run on all databases of
-** connection D.  ^If the database connection D is not in
-** [WAL | write-ahead log mode] then this interface is a harmless no-op.
-** ^The [sqlite3_wal_checkpoint(D,X)] interface initiates a
-** [sqlite3_wal_checkpoint_v2|PASSIVE] checkpoint.
-** Use the [sqlite3_wal_checkpoint_v2()] interface to get a FULL
-** or RESET checkpoint.
+** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to
+** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^
 **
-** ^The [wal_checkpoint pragma] can be used to invoke this interface
-** from SQL.  ^The [sqlite3_wal_autocheckpoint()] interface and the
-** [wal_autocheckpoint pragma] can be used to cause this interface to be
-** run whenever the WAL reaches a certain size threshold.
+** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the 
+** [write-ahead log] for database X on [database connection] D to be
+** transferred into the database file and for the write-ahead log to
+** be reset.  See the [checkpointing] documentation for addition
+** information.
 **
-** See also: [sqlite3_wal_checkpoint_v2()]
+** This interface used to be the only way to cause a checkpoint to
+** occur.  But then the newer and more powerful [sqlite3_wal_checkpoint_v2()]
+** interface was added.  This interface is retained for backwards
+** compatibility and as a convenience for applications that need to manually
+** start a callback but which do not need the full power (and corresponding
+** complication) of [sqlite3_wal_checkpoint_v2()].
 */
-SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
+SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
 
 /*
 ** CAPI3REF: Checkpoint a database
+** METHOD: sqlite3
 **
-** Run a checkpoint operation on WAL database zDb attached to database 
-** handle db. The specific operation is determined by the value of the 
-** eMode parameter:
+** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint
+** operation on database X of [database connection] D in mode M.  Status
+** information is written back into integers pointed to by L and C.)^
+** ^(The M parameter must be a valid [checkpoint mode]:)^
 **
 ** <dl>
 ** <dt>SQLITE_CHECKPOINT_PASSIVE<dd>
-**   Checkpoint as many frames as possible without waiting for any database 
-**   readers or writers to finish. Sync the db file if all frames in the log
-**   are checkpointed. This mode is the same as calling 
-**   sqlite3_wal_checkpoint(). The [sqlite3_busy_handler|busy-handler callback]
-**   is never invoked.
+**   ^Checkpoint as many frames as possible without waiting for any database 
+**   readers or writers to finish, then sync the database file if all frames 
+**   in the log were checkpointed. ^The [busy-handler callback]
+**   is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode.  
+**   ^On the other hand, passive mode might leave the checkpoint unfinished
+**   if there are concurrent readers or writers.
 **
 ** <dt>SQLITE_CHECKPOINT_FULL<dd>
-**   This mode blocks (it invokes the
+**   ^This mode blocks (it invokes the
 **   [sqlite3_busy_handler|busy-handler callback]) until there is no
 **   database writer and all readers are reading from the most recent database
-**   snapshot. It then checkpoints all frames in the log file and syncs the
-**   database file. This call blocks database writers while it is running,
-**   but not database readers.
+**   snapshot. ^It then checkpoints all frames in the log file and syncs the
+**   database file. ^This mode blocks new database writers while it is pending,
+**   but new database readers are allowed to continue unimpeded.
 **
 ** <dt>SQLITE_CHECKPOINT_RESTART<dd>
-**   This mode works the same way as SQLITE_CHECKPOINT_FULL, except after 
-**   checkpointing the log file it blocks (calls the 
-**   [sqlite3_busy_handler|busy-handler callback])
-**   until all readers are reading from the database file only. This ensures 
-**   that the next client to write to the database file restarts the log file 
-**   from the beginning. This call blocks database writers while it is running,
-**   but not database readers.
+**   ^This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition
+**   that after checkpointing the log file it blocks (calls the 
+**   [busy-handler callback])
+**   until all readers are reading from the database file only. ^This ensures 
+**   that the next writer will restart the log file from the beginning.
+**   ^Like SQLITE_CHECKPOINT_FULL, this mode blocks new
+**   database writer attempts while it is pending, but does not impede readers.
+**
+** <dt>SQLITE_CHECKPOINT_TRUNCATE<dd>
+**   ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the
+**   addition that it also truncates the log file to zero bytes just prior
+**   to a successful return.
 ** </dl>
 **
-** If pnLog is not NULL, then *pnLog is set to the total number of frames in
-** the log file before returning. If pnCkpt is not NULL, then *pnCkpt is set to
-** the total number of checkpointed frames (including any that were already
-** checkpointed when this function is called). *pnLog and *pnCkpt may be
-** populated even if sqlite3_wal_checkpoint_v2() returns other than SQLITE_OK.
-** If no values are available because of an error, they are both set to -1
-** before returning to communicate this to the caller.
-**
-** All calls obtain an exclusive "checkpoint" lock on the database file. If
+** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in
+** the log file or to -1 if the checkpoint could not run because
+** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not
+** NULL,then *pnCkpt is set to the total number of checkpointed frames in the
+** log file (including any that were already checkpointed before the function
+** was called) or to -1 if the checkpoint could not run due to an error or
+** because the database is not in WAL mode. ^Note that upon successful
+** completion of an SQLITE_CHECKPOINT_TRUNCATE, the log file will have been
+** truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero.
+**
+** ^All calls obtain an exclusive "checkpoint" lock on the database file. ^If
 ** any other process is running a checkpoint operation at the same time, the 
-** lock cannot be obtained and SQLITE_BUSY is returned. Even if there is a 
+** lock cannot be obtained and SQLITE_BUSY is returned. ^Even if there is a 
 ** busy-handler configured, it will not be invoked in this case.
 **
-** The SQLITE_CHECKPOINT_FULL and RESTART modes also obtain the exclusive 
-** "writer" lock on the database file. If the writer lock cannot be obtained
-** immediately, and a busy-handler is configured, it is invoked and the writer
-** lock retried until either the busy-handler returns 0 or the lock is
-** successfully obtained. The busy-handler is also invoked while waiting for
-** database readers as described above. If the busy-handler returns 0 before
+** ^The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the 
+** exclusive "writer" lock on the database file. ^If the writer lock cannot be
+** obtained immediately, and a busy-handler is configured, it is invoked and
+** the writer lock retried until either the busy-handler returns 0 or the lock
+** is successfully obtained. ^The busy-handler is also invoked while waiting for
+** database readers as described above. ^If the busy-handler returns 0 before
 ** the writer lock is obtained or while waiting for database readers, the
 ** checkpoint operation proceeds from that point in the same way as 
 ** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible 
-** without blocking any further. SQLITE_BUSY is returned in this case.
+** without blocking any further. ^SQLITE_BUSY is returned in this case.
 **
-** If parameter zDb is NULL or points to a zero length string, then the
-** specified operation is attempted on all WAL databases. In this case the
-** values written to output parameters *pnLog and *pnCkpt are undefined. If 
+** ^If parameter zDb is NULL or points to a zero length string, then the
+** specified operation is attempted on all WAL databases [attached] to 
+** [database connection] db.  In this case the
+** values written to output parameters *pnLog and *pnCkpt are undefined. ^If 
 ** an SQLITE_BUSY error is encountered when processing one or more of the 
 ** attached WAL databases, the operation is still attempted on any remaining 
-** attached databases and SQLITE_BUSY is returned to the caller. If any other 
+** attached databases and SQLITE_BUSY is returned at the end. ^If any other 
 ** error occurs while processing an attached database, processing is abandoned 
-** and the error code returned to the caller immediately. If no error 
+** and the error code is returned to the caller immediately. ^If no error 
 ** (SQLITE_BUSY or otherwise) is encountered while processing the attached 
 ** databases, SQLITE_OK is returned.
 **
-** If database zDb is the name of an attached database that is not in WAL
-** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. If
+** ^If database zDb is the name of an attached database that is not in WAL
+** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. ^If
 ** zDb is not NULL (or a zero length string) and is not the name of any
 ** attached database, SQLITE_ERROR is returned to the caller.
+**
+** ^Unless it returns SQLITE_MISUSE,
+** the sqlite3_wal_checkpoint_v2() interface
+** sets the error information that is queried by
+** [sqlite3_errcode()] and [sqlite3_errmsg()].
+**
+** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface
+** from SQL.
 */
-SQLITE_API int sqlite3_wal_checkpoint_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2(
   sqlite3 *db,                    /* Database handle */
   const char *zDb,                /* Name of attached database (or NULL) */
   int eMode,                      /* SQLITE_CHECKPOINT_* value */
@@ -7379,16 +7704,18 @@ SQLITE_API int sqlite3_wal_checkpoint_v2(
 );
 
 /*
-** CAPI3REF: Checkpoint operation parameters
+** CAPI3REF: Checkpoint Mode Values
+** KEYWORDS: {checkpoint mode}
 **
-** These constants can be used as the 3rd parameter to
-** [sqlite3_wal_checkpoint_v2()].  See the [sqlite3_wal_checkpoint_v2()]
-** documentation for additional information about the meaning and use of
-** each of these values.
+** These constants define all valid values for the "checkpoint mode" passed
+** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface.
+** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the
+** meaning of each of these checkpoint modes.
 */
-#define SQLITE_CHECKPOINT_PASSIVE 0
-#define SQLITE_CHECKPOINT_FULL    1
-#define SQLITE_CHECKPOINT_RESTART 2
+#define SQLITE_CHECKPOINT_PASSIVE  0  /* Do as much as possible w/o blocking */
+#define SQLITE_CHECKPOINT_FULL     1  /* Wait for writers, then checkpoint */
+#define SQLITE_CHECKPOINT_RESTART  2  /* Like FULL but wait for for readers */
+#define SQLITE_CHECKPOINT_TRUNCATE 3  /* Like RESTART but also truncate WAL */
 
 /*
 ** CAPI3REF: Virtual Table Interface Configuration
@@ -7404,7 +7731,7 @@ SQLITE_API int sqlite3_wal_checkpoint_v2(
 ** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].)  Further options
 ** may be added in the future.
 */
-SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
+SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3*, int op, ...);
 
 /*
 ** CAPI3REF: Virtual Table Configuration Options
@@ -7457,7 +7784,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
 ** of the SQL statement that triggered the call to the [xUpdate] method of the
 ** [virtual table].
 */
-SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
+SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *);
 
 /*
 ** CAPI3REF: Conflict resolution modes
@@ -7477,6 +7804,108 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
 /* #define SQLITE_ABORT 4  // Also an error code */
 #define SQLITE_REPLACE  5
 
+/*
+** CAPI3REF: Prepared Statement Scan Status Opcodes
+** KEYWORDS: {scanstatus options}
+**
+** The following constants can be used for the T parameter to the
+** [sqlite3_stmt_scanstatus(S,X,T,V)] interface.  Each constant designates a
+** different metric for sqlite3_stmt_scanstatus() to return.
+**
+** When the value returned to V is a string, space to hold that string is
+** managed by the prepared statement S and will be automatically freed when
+** S is finalized.
+**
+** <dl>
+** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt>
+** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be
+** set to the total number of times that the X-th loop has run.</dd>
+**
+** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt>
+** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set
+** to the total number of rows examined by all iterations of the X-th loop.</dd>
+**
+** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt>
+** <dd>^The "double" variable pointed to by the T parameter will be set to the
+** query planner's estimate for the average number of rows output from each
+** iteration of the X-th loop.  If the query planner's estimates was accurate,
+** then this value will approximate the quotient NVISIT/NLOOP and the
+** product of this value for all prior loops with the same SELECTID will
+** be the NLOOP value for the current loop.
+**
+** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt>
+** <dd>^The "const char *" variable pointed to by the T parameter will be set
+** to a zero-terminated UTF-8 string containing the name of the index or table
+** used for the X-th loop.
+**
+** [[SQLITE_SCANSTAT_EXPLAIN]] <dt>SQLITE_SCANSTAT_EXPLAIN</dt>
+** <dd>^The "const char *" variable pointed to by the T parameter will be set
+** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN]
+** description for the X-th loop.
+**
+** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt>
+** <dd>^The "int" variable pointed to by the T parameter will be set to the
+** "select-id" for the X-th loop.  The select-id identifies which query or
+** subquery the loop is part of.  The main query has a select-id of zero.
+** The select-id is the same value as is output in the first column
+** of an [EXPLAIN QUERY PLAN] query.
+** </dl>
+*/
+#define SQLITE_SCANSTAT_NLOOP    0
+#define SQLITE_SCANSTAT_NVISIT   1
+#define SQLITE_SCANSTAT_EST      2
+#define SQLITE_SCANSTAT_NAME     3
+#define SQLITE_SCANSTAT_EXPLAIN  4
+#define SQLITE_SCANSTAT_SELECTID 5
+
+/*
+** CAPI3REF: Prepared Statement Scan Status
+** METHOD: sqlite3_stmt
+**
+** This interface returns information about the predicted and measured
+** performance for pStmt.  Advanced applications can use this
+** interface to compare the predicted and the measured performance and
+** issue warnings and/or rerun [ANALYZE] if discrepancies are found.
+**
+** Since this interface is expected to be rarely used, it is only
+** available if SQLite is compiled using the [SQLITE_ENABLE_STMT_SCANSTATUS]
+** compile-time option.
+**
+** The "iScanStatusOp" parameter determines which status information to return.
+** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior
+** of this interface is undefined.
+** ^The requested measurement is written into a variable pointed to by
+** the "pOut" parameter.
+** Parameter "idx" identifies the specific loop to retrieve statistics for.
+** Loops are numbered starting from zero. ^If idx is out of range - less than
+** zero or greater than or equal to the total number of loops used to implement
+** the statement - a non-zero value is returned and the variable that pOut
+** points to is unchanged.
+**
+** ^Statistics might not be available for all loops in all statements. ^In cases
+** where there exist loops with no available statistics, this function behaves
+** as if the loop did not exist - it returns non-zero and leave the variable
+** that pOut points to unchanged.
+**
+** See also: [sqlite3_stmt_scanstatus_reset()]
+*/
+SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_stmt_scanstatus(
+  sqlite3_stmt *pStmt,      /* Prepared statement for which info desired */
+  int idx,                  /* Index of loop to report on */
+  int iScanStatusOp,        /* Information desired.  SQLITE_SCANSTAT_* */
+  void *pOut                /* Result written here */
+);     
+
+/*
+** CAPI3REF: Zero Scan-Status Counters
+** METHOD: sqlite3_stmt
+**
+** ^Zero all [sqlite3_stmt_scanstatus()] related event counters.
+**
+** This API is only available if the library is built with pre-processor
+** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
 
 
 /*
@@ -7531,7 +7960,7 @@ typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info;
 **
 **   SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...)
 */
-SQLITE_API int sqlite3_rtree_geometry_callback(
+SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback(
   sqlite3 *db,
   const char *zGeom,
   int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*),
@@ -7557,7 +7986,7 @@ struct sqlite3_rtree_geometry {
 **
 **   SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...)
 */
-SQLITE_API int sqlite3_rtree_query_callback(
+SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback(
   sqlite3 *db,
   const char *zQueryFunc,
   int (*xQueryFunc)(sqlite3_rtree_query_info*),
@@ -7721,15 +8150,17 @@ struct sqlite3_rtree_query_info {
 #endif
 
 /*
-** The maximum number of in-memory pages to use for the main database
-** table and for temporary tables.  The SQLITE_DEFAULT_CACHE_SIZE
+** The suggested maximum number of in-memory pages to use for
+** the main database table and for temporary tables.
+**
+** IMPLEMENTATION-OF: R-31093-59126 The default suggested cache size
+** is 2000 pages.
+** IMPLEMENTATION-OF: R-48205-43578 The default suggested cache size can be
+** altered using the SQLITE_DEFAULT_CACHE_SIZE compile-time options.
 */
 #ifndef SQLITE_DEFAULT_CACHE_SIZE
 # define SQLITE_DEFAULT_CACHE_SIZE  2000
 #endif
-#ifndef SQLITE_DEFAULT_TEMP_CACHE_SIZE
-# define SQLITE_DEFAULT_TEMP_CACHE_SIZE  500
-#endif
 
 /*
 ** The default number of frames to accumulate in the log file before
@@ -7842,15 +8273,6 @@ struct sqlite3_rtree_query_info {
 #pragma warn -spa /* Suspicious pointer arithmetic */
 #endif
 
-/* Needed for various definitions... */
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE
-#endif
-
-#if defined(__OpenBSD__) && !defined(_BSD_SOURCE)
-# define _BSD_SOURCE
-#endif
-
 /*
 ** Include standard header files as necessary
 */
@@ -7892,6 +8314,18 @@ struct sqlite3_rtree_query_info {
 #endif
 
 /*
+** A macro to hint to the compiler that a function should not be
+** inlined.
+*/
+#if defined(__GNUC__)
+#  define SQLITE_NOINLINE  __attribute__((noinline))
+#elif defined(_MSC_VER) && _MSC_VER>=1310
+#  define SQLITE_NOINLINE  __declspec(noinline)
+#else
+#  define SQLITE_NOINLINE
+#endif
+
+/*
 ** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2.
 ** 0 means mutexes are permanently disable and the library is never
 ** threadsafe.  1 means the library is serialized which is the highest
@@ -7919,10 +8353,9 @@ struct sqlite3_rtree_query_info {
 #endif
 
 /*
-** The SQLITE_DEFAULT_MEMSTATUS macro must be defined as either 0 or 1.
-** It determines whether or not the features related to 
-** SQLITE_CONFIG_MEMSTATUS are available by default or not. This value can
-** be overridden at runtime using the sqlite3_config() API.
+** EVIDENCE-OF: R-25715-37072 Memory allocation statistics are enabled by
+** default unless SQLite is compiled with SQLITE_DEFAULT_MEMSTATUS=0 in
+** which case memory allocation statistics are disabled by default.
 */
 #if !defined(SQLITE_DEFAULT_MEMSTATUS)
 # define SQLITE_DEFAULT_MEMSTATUS 1
@@ -8077,7 +8510,33 @@ SQLITE_PRIVATE   void sqlite3Coverage(int);
 #endif
 
 /*
-** Return true (non-zero) if the input is a integer that is too large
+** Declarations used for tracing the operating system interfaces.
+*/
+#if defined(SQLITE_FORCE_OS_TRACE) || defined(SQLITE_TEST) || \
+    (defined(SQLITE_DEBUG) && SQLITE_OS_WIN)
+  extern int sqlite3OSTrace;
+# define OSTRACE(X)          if( sqlite3OSTrace ) sqlite3DebugPrintf X
+# define SQLITE_HAVE_OS_TRACE
+#else
+# define OSTRACE(X)
+# undef  SQLITE_HAVE_OS_TRACE
+#endif
+
+/*
+** Is the sqlite3ErrName() function needed in the build?  Currently,
+** it is needed by "mutex_w32.c" (when debugging), "os_win.c" (when
+** OSTRACE is enabled), and by several "test*.c" files (which are
+** compiled using SQLITE_TEST).
+*/
+#if defined(SQLITE_HAVE_OS_TRACE) || defined(SQLITE_TEST) || \
+    (defined(SQLITE_DEBUG) && SQLITE_OS_WIN)
+# define SQLITE_NEED_ERR_NAME
+#else
+# undef  SQLITE_NEED_ERR_NAME
+#endif
+
+/*
+** Return true (non-zero) if the input is an integer that is too large
 ** to fit in 32-bits.  This macro is used inside of various testcase()
 ** macros to verify that we have tested SQLite for large-file support.
 */
@@ -8156,15 +8615,15 @@ struct Hash {
 struct HashElem {
   HashElem *next, *prev;       /* Next and previous elements in the table */
   void *data;                  /* Data associated with this element */
-  const char *pKey; int nKey;  /* Key associated with this element */
+  const char *pKey;            /* Key associated with this element */
 };
 
 /*
 ** Access routines.  To delete, insert a NULL pointer.
 */
 SQLITE_PRIVATE void sqlite3HashInit(Hash*);
-SQLITE_PRIVATE void *sqlite3HashInsert(Hash*, const char *pKey, int nKey, void *pData);
-SQLITE_PRIVATE void *sqlite3HashFind(const Hash*, const char *pKey, int nKey);
+SQLITE_PRIVATE void *sqlite3HashInsert(Hash*, const char *pKey, void *pData);
+SQLITE_PRIVATE void *sqlite3HashFind(const Hash*, const char *pKey);
 SQLITE_PRIVATE void sqlite3HashClear(Hash*);
 
 /*
@@ -8424,6 +8883,27 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
 #endif
 
 /*
+** If no value has been provided for SQLITE_MAX_WORKER_THREADS, or if
+** SQLITE_TEMP_STORE is set to 3 (never use temporary files), set it 
+** to zero.
+*/
+#if SQLITE_TEMP_STORE==3 || SQLITE_THREADSAFE==0
+# undef SQLITE_MAX_WORKER_THREADS
+# define SQLITE_MAX_WORKER_THREADS 0
+#endif
+#ifndef SQLITE_MAX_WORKER_THREADS
+# define SQLITE_MAX_WORKER_THREADS 8
+#endif
+#ifndef SQLITE_DEFAULT_WORKER_THREADS
+# define SQLITE_DEFAULT_WORKER_THREADS 0
+#endif
+#if SQLITE_DEFAULT_WORKER_THREADS>SQLITE_MAX_WORKER_THREADS
+# undef SQLITE_MAX_WORKER_THREADS
+# define SQLITE_MAX_WORKER_THREADS SQLITE_DEFAULT_WORKER_THREADS
+#endif
+
+
+/*
 ** GCC does not define the offsetof() macro so we'll have to do it
 ** ourselves.
 */
@@ -8438,6 +8918,11 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
 #define MAX(A,B) ((A)>(B)?(A):(B))
 
 /*
+** Swap two objects of type TYPE.
+*/
+#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
+
+/*
 ** Check to see if this machine uses EBCDIC.  (Yes, believe it or
 ** not, there are still machines out there that use EBCDIC.)
 */
@@ -8526,7 +9011,7 @@ typedef INT8_TYPE i8;              /* 1-byte signed integer */
 ** gives a possible range of values of approximately 1.0e986 to 1e-986.
 ** But the allowed values are "grainy".  Not every value is representable.
 ** For example, quantities 16 and 17 are both represented by a LogEst
-** of 40.  However, since LogEst quantaties are suppose to be estimates,
+** of 40.  However, since LogEst quantities are suppose to be estimates,
 ** not exact values, this imprecision is not a problem.
 **
 ** "LogEst" is short for "Logarithmic Estimate".
@@ -8546,6 +9031,20 @@ typedef INT8_TYPE i8;              /* 1-byte signed integer */
 typedef INT16_TYPE LogEst;
 
 /*
+** Set the SQLITE_PTRSIZE macro to the number of bytes in a pointer
+*/
+#ifndef SQLITE_PTRSIZE
+# if defined(__SIZEOF_POINTER__)
+#   define SQLITE_PTRSIZE __SIZEOF_POINTER__
+# elif defined(i386)     || defined(__i386__)   || defined(_M_IX86) ||    \
+       defined(_M_ARM)   || defined(__arm__)    || defined(__x86)
+#   define SQLITE_PTRSIZE 4
+# else
+#   define SQLITE_PTRSIZE 8
+# endif
+#endif
+
+/*
 ** Macros to determine whether the machine is big or little endian,
 ** and whether or not that determination is run-time or compile-time.
 **
@@ -8607,7 +9106,7 @@ SQLITE_PRIVATE const int sqlite3one;
 ** all alignment restrictions correct.
 **
 ** Except, if SQLITE_4_BYTE_ALIGNED_MALLOC is defined, then the
-** underlying malloc() implemention might return us 4-byte aligned
+** underlying malloc() implementation might return us 4-byte aligned
 ** pointers.  In that case, only verify 4-byte alignment.
 */
 #ifdef SQLITE_4_BYTE_ALIGNED_MALLOC
@@ -8675,6 +9174,16 @@ SQLITE_PRIVATE const int sqlite3one;
 #endif
 
 /*
+** SELECTTRACE_ENABLED will be either 1 or 0 depending on whether or not
+** the Select query generator tracing logic is turned on.
+*/
+#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_SELECTTRACE)
+# define SELECTTRACE_ENABLED 1
+#else
+# define SELECTTRACE_ENABLED 0
+#endif
+
+/*
 ** An instance of the following structure is used to store the busy-handler
 ** callback for a given sqlite handle. 
 **
@@ -8747,8 +9256,8 @@ struct BusyHandler {
   #define SQLITE_WSD const
   #define GLOBAL(t,v) (*(t*)sqlite3_wsd_find((void*)&(v), sizeof(v)))
   #define sqlite3GlobalConfig GLOBAL(struct Sqlite3Config, sqlite3Config)
-SQLITE_API   int sqlite3_wsd_init(int N, int J);
-SQLITE_API   void *sqlite3_wsd_find(void *K, int L);
+SQLITE_API int SQLITE_STDCALL sqlite3_wsd_init(int N, int J);
+SQLITE_API void *SQLITE_STDCALL sqlite3_wsd_find(void *K, int L);
 #else
   #define SQLITE_WSD 
   #define GLOBAL(t,v) v
@@ -8806,12 +9315,14 @@ typedef struct PrintfArguments PrintfArguments;
 typedef struct RowSet RowSet;
 typedef struct Savepoint Savepoint;
 typedef struct Select Select;
+typedef struct SQLiteThread SQLiteThread;
 typedef struct SelectDest SelectDest;
 typedef struct SrcList SrcList;
 typedef struct StrAccum StrAccum;
 typedef struct Table Table;
 typedef struct TableLock TableLock;
 typedef struct Token Token;
+typedef struct TreeView TreeView;
 typedef struct Trigger Trigger;
 typedef struct TriggerPrg TriggerPrg;
 typedef struct TriggerStep TriggerStep;
@@ -8850,7 +9361,7 @@ typedef struct With With;
 /* TODO: This definition is just included so other modules compile. It
 ** needs to be revisited.
 */
-#define SQLITE_N_BTREE_META 10
+#define SQLITE_N_BTREE_META 16
 
 /*
 ** If defined as non-zero, auto-vacuum is enabled by default. Otherwise
@@ -8904,17 +9415,15 @@ SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*);
 SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int);
 SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree*);
 SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree*,int);
-SQLITE_PRIVATE int sqlite3BtreeGetReserve(Btree*);
-#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG)
+SQLITE_PRIVATE int sqlite3BtreeGetOptimalReserve(Btree*);
 SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p);
-#endif
 SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int);
 SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *);
 SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int);
 SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster);
 SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*, int);
 SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*);
-SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*,int);
+SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*,int,int);
 SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree*,int);
 SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree*, int*, int flags);
 SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree*);
@@ -8947,7 +9456,7 @@ SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *);
 SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*);
 SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, int*);
 SQLITE_PRIVATE int sqlite3BtreeClearTableOfCursor(BtCursor*);
-SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree*, int);
+SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree*, int, int);
 
 SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue);
 SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
@@ -8965,6 +9474,11 @@ SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p);
 ** For example, the free-page-count field is located at byte offset 36 of
 ** the database file header. The incr-vacuum-flag field is located at
 ** byte offset 64 (== 36+4*7).
+**
+** The BTREE_DATA_VERSION value is not really a value stored in the header.
+** It is a read-only number computed by the pager.  But we merge it with
+** the header value access routines since its access pattern is the same.
+** Call it a "virtual meta value".
 */
 #define BTREE_FREE_PAGE_COUNT     0
 #define BTREE_SCHEMA_VERSION      1
@@ -8975,12 +9489,23 @@ SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p);
 #define BTREE_USER_VERSION        6
 #define BTREE_INCR_VACUUM         7
 #define BTREE_APPLICATION_ID      8
+#define BTREE_DATA_VERSION        15  /* A virtual meta-value */
 
 /*
 ** Values that may be OR'd together to form the second argument of an
 ** sqlite3BtreeCursorHints() call.
+**
+** The BTREE_BULKLOAD flag is set on index cursors when the index is going
+** to be filled with content that is already in sorted order.
+**
+** The BTREE_SEEK_EQ flag is set on cursors that will get OP_SeekGE or
+** OP_SeekLE opcodes for a range search, but where the range of entries
+** selected will all have the same key.  In other words, the cursor will
+** be used only for equality key searches.
+**
 */
-#define BTREE_BULKLOAD 0x00000001
+#define BTREE_BULKLOAD 0x00000001  /* Used to full index in sorted order */
+#define BTREE_SEEK_EQ  0x00000002  /* EQ seeks only - no range seeks */
 
 SQLITE_PRIVATE int sqlite3BtreeCursor(
   Btree*,                              /* BTree containing table to open */
@@ -9000,7 +9525,8 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
   int bias,
   int *pRes
 );
-SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor*, int*);
+SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor*);
+SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor*, int*);
 SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*);
 SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey,
                                   const void *pData, int nData,
@@ -9025,7 +9551,11 @@ SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *);
 SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *);
 SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion);
 SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask);
+#ifdef SQLITE_DEBUG
+SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask);
+#endif
 SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *pBt);
+SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void);
 
 #ifndef NDEBUG
 SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*);
@@ -9291,42 +9821,42 @@ typedef struct VdbeOpList VdbeOpList;
 #define OP_AddImm         37 /* synopsis: r[P1]=r[P1]+P2                   */
 #define OP_MustBeInt      38
 #define OP_RealAffinity   39
-#define OP_Permutation    40
-#define OP_Compare        41 /* synopsis: r[P1 P3] <-> r[P2 P3]            */
-#define OP_Jump           42
-#define OP_Once           43
-#define OP_If             44
-#define OP_IfNot          45
-#define OP_Column         46 /* synopsis: r[P3]=PX                         */
-#define OP_Affinity       47 /* synopsis: affinity(r[P1 P2])               */
-#define OP_MakeRecord     48 /* synopsis: r[P3]=mkrec(r[P1 P2])            */
-#define OP_Count          49 /* synopsis: r[P2]=count()                    */
-#define OP_ReadCookie     50
-#define OP_SetCookie      51
-#define OP_ReopenIdx      52 /* synopsis: root=P2 iDb=P3                   */
-#define OP_OpenRead       53 /* synopsis: root=P2 iDb=P3                   */
-#define OP_OpenWrite      54 /* synopsis: root=P2 iDb=P3                   */
-#define OP_OpenAutoindex  55 /* synopsis: nColumn=P2                       */
-#define OP_OpenEphemeral  56 /* synopsis: nColumn=P2                       */
-#define OP_SorterOpen     57
-#define OP_OpenPseudo     58 /* synopsis: P3 columns in r[P2]              */
-#define OP_Close          59
-#define OP_SeekLT         60 /* synopsis: key=r[P3 P4]                     */
-#define OP_SeekLE         61 /* synopsis: key=r[P3 P4]                     */
-#define OP_SeekGE         62 /* synopsis: key=r[P3 P4]                     */
-#define OP_SeekGT         63 /* synopsis: key=r[P3 P4]                     */
-#define OP_Seek           64 /* synopsis: intkey=r[P2]                     */
-#define OP_NoConflict     65 /* synopsis: key=r[P3 P4]                     */
-#define OP_NotFound       66 /* synopsis: key=r[P3 P4]                     */
-#define OP_Found          67 /* synopsis: key=r[P3 P4]                     */
-#define OP_NotExists      68 /* synopsis: intkey=r[P3]                     */
-#define OP_Sequence       69 /* synopsis: r[P2]=cursor[P1].ctr++           */
-#define OP_NewRowid       70 /* synopsis: r[P2]=rowid                      */
+#define OP_Cast           40 /* synopsis: affinity(r[P1])                  */
+#define OP_Permutation    41
+#define OP_Compare        42 /* synopsis: r[P1 P3] <-> r[P2 P3]            */
+#define OP_Jump           43
+#define OP_Once           44
+#define OP_If             45
+#define OP_IfNot          46
+#define OP_Column         47 /* synopsis: r[P3]=PX                         */
+#define OP_Affinity       48 /* synopsis: affinity(r[P1 P2])               */
+#define OP_MakeRecord     49 /* synopsis: r[P3]=mkrec(r[P1 P2])            */
+#define OP_Count          50 /* synopsis: r[P2]=count()                    */
+#define OP_ReadCookie     51
+#define OP_SetCookie      52
+#define OP_ReopenIdx      53 /* synopsis: root=P2 iDb=P3                   */
+#define OP_OpenRead       54 /* synopsis: root=P2 iDb=P3                   */
+#define OP_OpenWrite      55 /* synopsis: root=P2 iDb=P3                   */
+#define OP_OpenAutoindex  56 /* synopsis: nColumn=P2                       */
+#define OP_OpenEphemeral  57 /* synopsis: nColumn=P2                       */
+#define OP_SorterOpen     58
+#define OP_SequenceTest   59 /* synopsis: if( cursor[P1].ctr++ ) pc = P2   */
+#define OP_OpenPseudo     60 /* synopsis: P3 columns in r[P2]              */
+#define OP_Close          61
+#define OP_SeekLT         62 /* synopsis: key=r[P3 P4]                     */
+#define OP_SeekLE         63 /* synopsis: key=r[P3 P4]                     */
+#define OP_SeekGE         64 /* synopsis: key=r[P3 P4]                     */
+#define OP_SeekGT         65 /* synopsis: key=r[P3 P4]                     */
+#define OP_Seek           66 /* synopsis: intkey=r[P2]                     */
+#define OP_NoConflict     67 /* synopsis: key=r[P3 P4]                     */
+#define OP_NotFound       68 /* synopsis: key=r[P3 P4]                     */
+#define OP_Found          69 /* synopsis: key=r[P3 P4]                     */
+#define OP_NotExists      70 /* synopsis: intkey=r[P3]                     */
 #define OP_Or             71 /* same as TK_OR, synopsis: r[P3]=(r[P1] || r[P2]) */
 #define OP_And            72 /* same as TK_AND, synopsis: r[P3]=(r[P1] && r[P2]) */
-#define OP_Insert         73 /* synopsis: intkey=r[P3] data=r[P2]          */
-#define OP_InsertInt      74 /* synopsis: intkey=P3 data=r[P2]             */
-#define OP_Delete         75
+#define OP_Sequence       73 /* synopsis: r[P2]=cursor[P1].ctr++           */
+#define OP_NewRowid       74 /* synopsis: r[P2]=rowid                      */
+#define OP_Insert         75 /* synopsis: intkey=r[P3] data=r[P2]          */
 #define OP_IsNull         76 /* same as TK_ISNULL, synopsis: if r[P1]==NULL goto P2 */
 #define OP_NotNull        77 /* same as TK_NOTNULL, synopsis: if r[P1]!=NULL goto P2 */
 #define OP_Ne             78 /* same as TK_NE, synopsis: if r[P1]!=r[P3] goto P2 */
@@ -9335,7 +9865,7 @@ typedef struct VdbeOpList VdbeOpList;
 #define OP_Le             81 /* same as TK_LE, synopsis: if r[P1]<=r[P3] goto P2 */
 #define OP_Lt             82 /* same as TK_LT, synopsis: if r[P1]<r[P3] goto P2 */
 #define OP_Ge             83 /* same as TK_GE, synopsis: if r[P1]>=r[P3] goto P2 */
-#define OP_ResetCount     84
+#define OP_InsertInt      84 /* synopsis: intkey=P3 data=r[P2]             */
 #define OP_BitAnd         85 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
 #define OP_BitOr          86 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
 #define OP_ShiftLeft      87 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
@@ -9346,70 +9876,69 @@ typedef struct VdbeOpList VdbeOpList;
 #define OP_Divide         92 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
 #define OP_Remainder      93 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
 #define OP_Concat         94 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
-#define OP_SorterCompare  95 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
+#define OP_Delete         95
 #define OP_BitNot         96 /* same as TK_BITNOT, synopsis: r[P1]= ~r[P1] */
 #define OP_String8        97 /* same as TK_STRING, synopsis: r[P2]='P4'    */
-#define OP_SorterData     98 /* synopsis: r[P2]=data                       */
-#define OP_RowKey         99 /* synopsis: r[P2]=key                        */
-#define OP_RowData       100 /* synopsis: r[P2]=data                       */
-#define OP_Rowid         101 /* synopsis: r[P2]=rowid                      */
-#define OP_NullRow       102
-#define OP_Last          103
-#define OP_SorterSort    104
-#define OP_Sort          105
-#define OP_Rewind        106
-#define OP_SorterInsert  107
-#define OP_IdxInsert     108 /* synopsis: key=r[P2]                        */
-#define OP_IdxDelete     109 /* synopsis: key=r[P2 P3]                     */
-#define OP_IdxRowid      110 /* synopsis: r[P2]=rowid                      */
-#define OP_IdxLE         111 /* synopsis: key=r[P3 P4]                     */
-#define OP_IdxGT         112 /* synopsis: key=r[P3 P4]                     */
-#define OP_IdxLT         113 /* synopsis: key=r[P3 P4]                     */
-#define OP_IdxGE         114 /* synopsis: key=r[P3 P4]                     */
-#define OP_Destroy       115
-#define OP_Clear         116
-#define OP_ResetSorter   117
-#define OP_CreateIndex   118 /* synopsis: r[P2]=root iDb=P1                */
-#define OP_CreateTable   119 /* synopsis: r[P2]=root iDb=P1                */
-#define OP_ParseSchema   120
-#define OP_LoadAnalysis  121
-#define OP_DropTable     122
-#define OP_DropIndex     123
-#define OP_DropTrigger   124
-#define OP_IntegrityCk   125
-#define OP_RowSetAdd     126 /* synopsis: rowset(P1)=r[P2]                 */
-#define OP_RowSetRead    127 /* synopsis: r[P3]=rowset(P1)                 */
-#define OP_RowSetTest    128 /* synopsis: if r[P3] in rowset(P1) goto P2   */
-#define OP_Program       129
-#define OP_Param         130
-#define OP_FkCounter     131 /* synopsis: fkctr[P1]+=P2                    */
-#define OP_FkIfZero      132 /* synopsis: if fkctr[P1]==0 goto P2          */
+#define OP_ResetCount     98
+#define OP_SorterCompare  99 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
+#define OP_SorterData    100 /* synopsis: r[P2]=data                       */
+#define OP_RowKey        101 /* synopsis: r[P2]=key                        */
+#define OP_RowData       102 /* synopsis: r[P2]=data                       */
+#define OP_Rowid         103 /* synopsis: r[P2]=rowid                      */
+#define OP_NullRow       104
+#define OP_Last          105
+#define OP_SorterSort    106
+#define OP_Sort          107
+#define OP_Rewind        108
+#define OP_SorterInsert  109
+#define OP_IdxInsert     110 /* synopsis: key=r[P2]                        */
+#define OP_IdxDelete     111 /* synopsis: key=r[P2 P3]                     */
+#define OP_IdxRowid      112 /* synopsis: r[P2]=rowid                      */
+#define OP_IdxLE         113 /* synopsis: key=r[P3 P4]                     */
+#define OP_IdxGT         114 /* synopsis: key=r[P3 P4]                     */
+#define OP_IdxLT         115 /* synopsis: key=r[P3 P4]                     */
+#define OP_IdxGE         116 /* synopsis: key=r[P3 P4]                     */
+#define OP_Destroy       117
+#define OP_Clear         118
+#define OP_ResetSorter   119
+#define OP_CreateIndex   120 /* synopsis: r[P2]=root iDb=P1                */
+#define OP_CreateTable   121 /* synopsis: r[P2]=root iDb=P1                */
+#define OP_ParseSchema   122
+#define OP_LoadAnalysis  123
+#define OP_DropTable     124
+#define OP_DropIndex     125
+#define OP_DropTrigger   126
+#define OP_IntegrityCk   127
+#define OP_RowSetAdd     128 /* synopsis: rowset(P1)=r[P2]                 */
+#define OP_RowSetRead    129 /* synopsis: r[P3]=rowset(P1)                 */
+#define OP_RowSetTest    130 /* synopsis: if r[P3] in rowset(P1) goto P2   */
+#define OP_Program       131
+#define OP_Param         132
 #define OP_Real          133 /* same as TK_FLOAT, synopsis: r[P2]=P4       */
-#define OP_MemMax        134 /* synopsis: r[P1]=max(r[P1],r[P2])           */
-#define OP_IfPos         135 /* synopsis: if r[P1]>0 goto P2               */
-#define OP_IfNeg         136 /* synopsis: r[P1]+=P3, if r[P1]<0 goto P2    */
-#define OP_IfZero        137 /* synopsis: r[P1]+=P3, if r[P1]==0 goto P2   */
-#define OP_AggFinal      138 /* synopsis: accum=r[P1] N=P2                 */
-#define OP_IncrVacuum    139
-#define OP_Expire        140
-#define OP_TableLock     141 /* synopsis: iDb=P1 root=P2 write=P3          */
-#define OP_VBegin        142
-#define OP_ToText        143 /* same as TK_TO_TEXT                         */
-#define OP_ToBlob        144 /* same as TK_TO_BLOB                         */
-#define OP_ToNumeric     145 /* same as TK_TO_NUMERIC                      */
-#define OP_ToInt         146 /* same as TK_TO_INT                          */
-#define OP_ToReal        147 /* same as TK_TO_REAL                         */
-#define OP_VCreate       148
-#define OP_VDestroy      149
-#define OP_VOpen         150
-#define OP_VColumn       151 /* synopsis: r[P3]=vcolumn(P2)                */
-#define OP_VNext         152
-#define OP_VRename       153
-#define OP_Pagecount     154
-#define OP_MaxPgcnt      155
-#define OP_Init          156 /* synopsis: Start at P2                      */
-#define OP_Noop          157
-#define OP_Explain       158
+#define OP_FkCounter     134 /* synopsis: fkctr[P1]+=P2                    */
+#define OP_FkIfZero      135 /* synopsis: if fkctr[P1]==0 goto P2          */
+#define OP_MemMax        136 /* synopsis: r[P1]=max(r[P1],r[P2])           */
+#define OP_IfPos         137 /* synopsis: if r[P1]>0 goto P2               */
+#define OP_IfNeg         138 /* synopsis: r[P1]+=P3, if r[P1]<0 goto P2    */
+#define OP_IfNotZero     139 /* synopsis: if r[P1]!=0 then r[P1]+=P3, goto P2 */
+#define OP_DecrJumpZero  140 /* synopsis: if (--r[P1])==0 goto P2          */
+#define OP_JumpZeroIncr  141 /* synopsis: if (r[P1]++)==0 ) goto P2        */
+#define OP_AggFinal      142 /* synopsis: accum=r[P1] N=P2                 */
+#define OP_IncrVacuum    143
+#define OP_Expire        144
+#define OP_TableLock     145 /* synopsis: iDb=P1 root=P2 write=P3          */
+#define OP_VBegin        146
+#define OP_VCreate       147
+#define OP_VDestroy      148
+#define OP_VOpen         149
+#define OP_VColumn       150 /* synopsis: r[P3]=vcolumn(P2)                */
+#define OP_VNext         151
+#define OP_VRename       152
+#define OP_Pagecount     153
+#define OP_MaxPgcnt      154
+#define OP_Init          155 /* synopsis: Start at P2                      */
+#define OP_Noop          156
+#define OP_Explain       157
 
 
 /* Properties such as "out2" or "jump" that are specified in
@@ -9417,33 +9946,32 @@ typedef struct VdbeOpList VdbeOpList;
 ** are encoded into bitvectors as follows:
 */
 #define OPFLG_JUMP            0x0001  /* jump:  P2 holds jmp target */
-#define OPFLG_OUT2_PRERELEASE 0x0002  /* out2-prerelease: */
-#define OPFLG_IN1             0x0004  /* in1:   P1 is an input */
-#define OPFLG_IN2             0x0008  /* in2:   P2 is an input */
-#define OPFLG_IN3             0x0010  /* in3:   P3 is an input */
-#define OPFLG_OUT2            0x0020  /* out2:  P2 is an output */
-#define OPFLG_OUT3            0x0040  /* out3:  P3 is an output */
+#define OPFLG_IN1             0x0002  /* in1:   P1 is an input */
+#define OPFLG_IN2             0x0004  /* in2:   P2 is an input */
+#define OPFLG_IN3             0x0008  /* in3:   P3 is an input */
+#define OPFLG_OUT2            0x0010  /* out2:  P2 is an output */
+#define OPFLG_OUT3            0x0020  /* out3:  P3 is an output */
 #define OPFLG_INITIALIZER {\
 /*   0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,\
-/*   8 */ 0x01, 0x01, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,\
-/*  16 */ 0x01, 0x01, 0x04, 0x24, 0x01, 0x04, 0x05, 0x10,\
-/*  24 */ 0x00, 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x02,\
-/*  32 */ 0x00, 0x00, 0x20, 0x00, 0x00, 0x04, 0x05, 0x04,\
-/*  40 */ 0x00, 0x00, 0x01, 0x01, 0x05, 0x05, 0x00, 0x00,\
-/*  48 */ 0x00, 0x02, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00,\
-/*  56 */ 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,\
-/*  64 */ 0x08, 0x11, 0x11, 0x11, 0x11, 0x02, 0x02, 0x4c,\
-/*  72 */ 0x4c, 0x00, 0x00, 0x00, 0x05, 0x05, 0x15, 0x15,\
-/*  80 */ 0x15, 0x15, 0x15, 0x15, 0x00, 0x4c, 0x4c, 0x4c,\
-/*  88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x00,\
-/*  96 */ 0x24, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01,\
-/* 104 */ 0x01, 0x01, 0x01, 0x08, 0x08, 0x00, 0x02, 0x01,\
-/* 112 */ 0x01, 0x01, 0x01, 0x02, 0x00, 0x00, 0x02, 0x02,\
-/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x45,\
-/* 128 */ 0x15, 0x01, 0x02, 0x00, 0x01, 0x02, 0x08, 0x05,\
-/* 136 */ 0x05, 0x05, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04,\
-/* 144 */ 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00,\
-/* 152 */ 0x01, 0x00, 0x02, 0x02, 0x01, 0x00, 0x00,}
+/*   8 */ 0x01, 0x01, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00,\
+/*  16 */ 0x01, 0x01, 0x02, 0x12, 0x01, 0x02, 0x03, 0x08,\
+/*  24 */ 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x10,\
+/*  32 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x02, 0x03, 0x02,\
+/*  40 */ 0x02, 0x00, 0x00, 0x01, 0x01, 0x03, 0x03, 0x00,\
+/*  48 */ 0x00, 0x00, 0x10, 0x10, 0x08, 0x00, 0x00, 0x00,\
+/*  56 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x09,\
+/*  64 */ 0x09, 0x09, 0x04, 0x09, 0x09, 0x09, 0x09, 0x26,\
+/*  72 */ 0x26, 0x10, 0x10, 0x00, 0x03, 0x03, 0x0b, 0x0b,\
+/*  80 */ 0x0b, 0x0b, 0x0b, 0x0b, 0x00, 0x26, 0x26, 0x26,\
+/*  88 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x00,\
+/*  96 */ 0x12, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
+/* 104 */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x04, 0x04, 0x00,\
+/* 112 */ 0x10, 0x01, 0x01, 0x01, 0x01, 0x10, 0x00, 0x00,\
+/* 120 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/* 128 */ 0x06, 0x23, 0x0b, 0x01, 0x10, 0x10, 0x00, 0x01,\
+/* 136 */ 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x01,\
+/* 144 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,\
+/* 152 */ 0x00, 0x10, 0x10, 0x01, 0x00, 0x00,}
 
 /************** End of opcodes.h *********************************************/
 /************** Continuing where we left off in vdbe.h ***********************/
@@ -9501,10 +10029,11 @@ SQLITE_PRIVATE   char *sqlite3VdbeExpandSql(Vdbe*, const char*);
 SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
 
 SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
-SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*,int);
+SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*);
+SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int);
 SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);
 
-typedef int (*RecordCompare)(int,const void*,UnpackedRecord*,int);
+typedef int (*RecordCompare)(int,const void*,UnpackedRecord*);
 SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*);
 
 #ifndef SQLITE_OMIT_TRIGGER
@@ -9571,6 +10100,12 @@ SQLITE_PRIVATE   void sqlite3VdbeSetLineNumber(Vdbe*,int);
 # define VDBE_OFFSET_LINENO(x) 0
 #endif
 
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+SQLITE_PRIVATE void sqlite3VdbeScanStatus(Vdbe*, int, int, int, LogEst, const char*);
+#else
+# define sqlite3VdbeScanStatus(a,b,c,d,e)
+#endif
+
 #endif
 
 /************** End of vdbe.h ************************************************/
@@ -9751,6 +10286,7 @@ SQLITE_PRIVATE   int sqlite3PagerWalFramesize(Pager *pPager);
 
 /* Functions used to query pager state and configuration. */
 SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*);
+SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager*);
 SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*);
 SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*);
 SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager*, int);
@@ -9767,6 +10303,8 @@ SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *);
 /* Functions used to truncate the database file. */
 SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);
 
+SQLITE_PRIVATE void sqlite3PagerRekey(DbPage*, Pgno, u16);
+
 #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL)
 SQLITE_PRIVATE void *sqlite3PagerCodec(DbPage *);
 #endif
@@ -9862,7 +10400,7 @@ SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *, int sz, int n);
 ** Under memory stress, invoke xStress to try to make pages clean.
 ** Only clean and unpinned pages can be reclaimed.
 */
-SQLITE_PRIVATE void sqlite3PcacheOpen(
+SQLITE_PRIVATE int sqlite3PcacheOpen(
   int szPage,                    /* Size of every page */
   int szExtra,                   /* Extra space associated with each page */
   int bPurgeable,                /* True if pages are on backing store */
@@ -9872,7 +10410,7 @@ SQLITE_PRIVATE void sqlite3PcacheOpen(
 );
 
 /* Modify the page-size after the cache has been created. */
-SQLITE_PRIVATE void sqlite3PcacheSetPageSize(PCache *, int);
+SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *, int);
 
 /* Return the size in bytes of a PCache object.  Used to preallocate
 ** storage space.
@@ -9882,7 +10420,9 @@ SQLITE_PRIVATE int sqlite3PcacheSize(void);
 /* One release per successful fetch.  Page is pinned until released.
 ** Reference counted. 
 */
-SQLITE_PRIVATE int sqlite3PcacheFetch(PCache*, Pgno, int createFlag, PgHdr**);
+SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch(PCache*, Pgno, int createFlag);
+SQLITE_PRIVATE int sqlite3PcacheFetchStress(PCache*, Pgno, sqlite3_pcache_page**);
+SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish(PCache*, Pgno, sqlite3_pcache_page *pPage);
 SQLITE_PRIVATE void sqlite3PcacheRelease(PgHdr*);
 
 SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr*);         /* Remove page from cache */
@@ -9952,6 +10492,10 @@ SQLITE_PRIVATE void sqlite3PcacheStats(int*,int*,int*,int*);
 
 SQLITE_PRIVATE void sqlite3PCacheSetDefault(void);
 
+/* Return the header size */
+SQLITE_PRIVATE int sqlite3HeaderSizePcache(void);
+SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void);
+
 #endif /* _PCACHE_H_ */
 
 /************** End of pcache.h **********************************************/
@@ -10142,7 +10686,7 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void);
 ** shared locks begins at SHARED_FIRST. 
 **
 ** The same locking strategy and
-** byte ranges are used for Unix.  This leaves open the possiblity of having
+** byte ranges are used for Unix.  This leaves open the possibility of having
 ** clients on win95, winNT, and unix all talking to the same shared file
 ** and all locking correctly.  To do so would require that samba (or whatever
 ** tool is being used for file sharing) implements locks correctly between
@@ -10261,7 +10805,7 @@ SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *);
 ** Figure out what version of the code to use.  The choices are
 **
 **   SQLITE_MUTEX_OMIT         No mutex logic.  Not even stubs.  The
-**                             mutexes implemention cannot be overridden
+**                             mutexes implementation cannot be overridden
 **                             at start-time.
 **
 **   SQLITE_MUTEX_NOOP         For single-threaded applications.  No
@@ -10381,7 +10925,7 @@ struct Schema {
 ** The number of different kinds of things that can be limited
 ** using the sqlite3_limit() interface.
 */
-#define SQLITE_N_LIMIT (SQLITE_LIMIT_TRIGGER_DEPTH+1)
+#define SQLITE_N_LIMIT (SQLITE_LIMIT_WORKER_THREADS+1)
 
 /*
 ** Lookaside malloc is a set of fixed-size buffers that can be used
@@ -10428,6 +10972,45 @@ struct FuncDefHash {
   FuncDef *a[23];       /* Hash table for functions */
 };
 
+#ifdef SQLITE_USER_AUTHENTICATION
+/*
+** Information held in the "sqlite3" database connection object and used
+** to manage user authentication.
+*/
+typedef struct sqlite3_userauth sqlite3_userauth;
+struct sqlite3_userauth {
+  u8 authLevel;                 /* Current authentication level */
+  int nAuthPW;                  /* Size of the zAuthPW in bytes */
+  char *zAuthPW;                /* Password used to authenticate */
+  char *zAuthUser;              /* User name used to authenticate */
+};
+
+/* Allowed values for sqlite3_userauth.authLevel */
+#define UAUTH_Unknown     0     /* Authentication not yet checked */
+#define UAUTH_Fail        1     /* User authentication failed */
+#define UAUTH_User        2     /* Authenticated as a normal user */
+#define UAUTH_Admin       3     /* Authenticated as an administrator */
+
+/* Functions used only by user authorization logic */
+SQLITE_PRIVATE int sqlite3UserAuthTable(const char*);
+SQLITE_PRIVATE int sqlite3UserAuthCheckLogin(sqlite3*,const char*,u8*);
+SQLITE_PRIVATE void sqlite3UserAuthInit(sqlite3*);
+SQLITE_PRIVATE void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**);
+
+#endif /* SQLITE_USER_AUTHENTICATION */
+
+/*
+** typedef for the authorization callback function.
+*/
+#ifdef SQLITE_USER_AUTHENTICATION
+  typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*,
+                               const char*, const char*);
+#else
+  typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*,
+                               const char*);
+#endif
+
+
 /*
 ** Each database connection is an instance of the following structure.
 */
@@ -10445,6 +11028,7 @@ struct sqlite3 {
   int errCode;                  /* Most recent error code (SQLITE_*) */
   int errMask;                  /* & result codes with this before returning */
   u16 dbOptFlags;               /* Flags to enable/disable optimizations */
+  u8 enc;                       /* Text encoding */
   u8 autoCommit;                /* The auto-commit flag. */
   u8 temp_store;                /* 1: file 2: memory 0: default */
   u8 mallocFailed;              /* True if we have seen a malloc failure */
@@ -10458,16 +11042,19 @@ struct sqlite3 {
   int nChange;                  /* Value returned by sqlite3_changes() */
   int nTotalChange;             /* Value returned by sqlite3_total_changes() */
   int aLimit[SQLITE_N_LIMIT];   /* Limits */
+  int nMaxSorterMmap;           /* Maximum size of regions mapped by sorter */
   struct sqlite3InitInfo {      /* Information used during initialization */
     int newTnum;                /* Rootpage of table being initialized */
     u8 iDb;                     /* Which db file is being initialized */
     u8 busy;                    /* TRUE if currently initializing */
     u8 orphanTrigger;           /* Last statement is orphaned TEMP trigger */
+    u8 imposterTable;           /* Building an imposter table */
   } init;
   int nVdbeActive;              /* Number of VDBEs currently running */
   int nVdbeRead;                /* Number of active VDBEs that read or write */
   int nVdbeWrite;               /* Number of active VDBEs that read and write */
   int nVdbeExec;                /* Number of nested calls to VdbeExec() */
+  int nVDestroy;                /* Number of active OP_VDestroy operations */
   int nExtension;               /* Number of loaded extensions */
   void **aExtension;            /* Array of shared library handles */
   void (*xTrace)(void*,const char*);        /* Trace function */
@@ -10494,8 +11081,7 @@ struct sqlite3 {
   } u1;
   Lookaside lookaside;          /* Lookaside malloc configuration */
 #ifndef SQLITE_OMIT_AUTHORIZATION
-  int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
-                                /* Access authorization function */
+  sqlite3_xauth xAuth;          /* Access authorization function */
   void *pAuthArg;               /* 1st argument to the access auth function */
 #endif
 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
@@ -10521,7 +11107,6 @@ struct sqlite3 {
   i64 nDeferredCons;            /* Net deferred constraints this transaction. */
   i64 nDeferredImmCons;         /* Net deferred immediate constraints */
   int *pnBytesFreed;            /* If not NULL, increment this in DbFree() */
-
 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
   /* The following variables are all protected by the STATIC_MASTER 
   ** mutex, not by sqlite3.mutex. They are used by code in notify.c. 
@@ -10539,12 +11124,16 @@ struct sqlite3 {
   void (*xUnlockNotify)(void **, int);  /* Unlock notify callback */
   sqlite3 *pNextBlocked;        /* Next in list of all blocked connections */
 #endif
+#ifdef SQLITE_USER_AUTHENTICATION
+  sqlite3_userauth auth;        /* User authentication information */
+#endif
 };
 
 /*
 ** A macro to discover the encoding of a database.
 */
-#define ENC(db) ((db)->aDb[0].pSchema->enc)
+#define SCHEMA_ENC(db) ((db)->aDb[0].pSchema->enc)
+#define ENC(db)        ((db)->enc)
 
 /*
 ** Possible values for the sqlite3.flags.
@@ -10579,6 +11168,7 @@ struct sqlite3 {
 #define SQLITE_DeferFKs       0x01000000  /* Defer all FK constraints */
 #define SQLITE_QueryOnly      0x02000000  /* Disable database changes */
 #define SQLITE_VdbeEQP        0x04000000  /* Debug EXPLAIN QUERY PLAN */
+#define SQLITE_Vacuum         0x08000000  /* Currently in a VACUUM */
 
 
 /*
@@ -10597,8 +11187,7 @@ struct sqlite3 {
 #define SQLITE_SubqCoroutine  0x0100   /* Evaluate subqueries as coroutines */
 #define SQLITE_Transitive     0x0200   /* Transitive constraints */
 #define SQLITE_OmitNoopJoin   0x0400   /* Omit unused tables in joins */
-#define SQLITE_Stat3          0x0800   /* Use the SQLITE_STAT3 table */
-#define SQLITE_AdjustOutEst   0x1000   /* Adjust output estimates using WHERE */
+#define SQLITE_Stat34         0x0800   /* Use STAT3 or STAT4 data */
 #define SQLITE_AllOpts        0xffff   /* All optimizations */
 
 /*
@@ -10685,6 +11274,7 @@ struct FuncDestructor {
 #define SQLITE_FUNC_COALESCE 0x200 /* Built-in coalesce() or ifnull() */
 #define SQLITE_FUNC_UNLIKELY 0x400 /* Built-in unlikely() function */
 #define SQLITE_FUNC_CONSTANT 0x800 /* Constant inputs give a constant output */
+#define SQLITE_FUNC_MINMAX  0x1000 /* True for min() and max() aggregates */
 
 /*
 ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
@@ -10732,6 +11322,9 @@ struct FuncDestructor {
 #define AGGREGATE(zName, nArg, arg, nc, xStep, xFinal) \
   {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL), \
    SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0}
+#define AGGREGATE2(zName, nArg, arg, nc, xStep, xFinal, extraFlags) \
+  {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|extraFlags, \
+   SQLITE_INT_TO_PTR(arg), 0, 0, xStep,xFinal,#zName,0,0}
 
 /*
 ** All current savepoints are stored in a linked list starting at
@@ -10818,18 +11411,18 @@ struct CollSeq {
 ** 't' for SQLITE_AFF_TEXT.  But we can save a little space and improve
 ** the speed a little by numbering the values consecutively.  
 **
-** But rather than start with 0 or 1, we begin with 'a'.  That way,
+** But rather than start with 0 or 1, we begin with 'A'.  That way,
 ** when multiple affinity types are concatenated into a string and
 ** used as the P4 operand, they will be more readable.
 **
 ** Note also that the numeric types are grouped together so that testing
-** for a numeric type is a single comparison.
+** for a numeric type is a single comparison.  And the NONE type is first.
 */
-#define SQLITE_AFF_TEXT     'a'
-#define SQLITE_AFF_NONE     'b'
-#define SQLITE_AFF_NUMERIC  'c'
-#define SQLITE_AFF_INTEGER  'd'
-#define SQLITE_AFF_REAL     'e'
+#define SQLITE_AFF_NONE     'A'
+#define SQLITE_AFF_TEXT     'B'
+#define SQLITE_AFF_NUMERIC  'C'
+#define SQLITE_AFF_INTEGER  'D'
+#define SQLITE_AFF_REAL     'E'
 
 #define sqlite3IsNumericAffinity(X)  ((X)>=SQLITE_AFF_NUMERIC)
 
@@ -10837,7 +11430,7 @@ struct CollSeq {
 ** The SQLITE_AFF_MASK values masks off the significant bits of an
 ** affinity value. 
 */
-#define SQLITE_AFF_MASK     0x67
+#define SQLITE_AFF_MASK     0x47
 
 /*
 ** Additional bit values that can be ORed with an affinity without
@@ -10848,10 +11441,10 @@ struct CollSeq {
 ** operator is NULL.  It is added to certain comparison operators to
 ** prove that the operands are always NOT NULL.
 */
-#define SQLITE_JUMPIFNULL   0x08  /* jumps if either operand is NULL */
-#define SQLITE_STOREP2      0x10  /* Store result in reg[P2] rather than jump */
+#define SQLITE_JUMPIFNULL   0x10  /* jumps if either operand is NULL */
+#define SQLITE_STOREP2      0x20  /* Store result in reg[P2] rather than jump */
 #define SQLITE_NULLEQ       0x80  /* NULL=NULL */
-#define SQLITE_NOTNULL      0x88  /* Assert that operands are never NULL */
+#define SQLITE_NOTNULL      0x90  /* Assert that operands are never NULL */
 
 /*
 ** An object of this type is created for each virtual table present in
@@ -10906,34 +11499,8 @@ struct VTable {
 };
 
 /*
-** Each SQL table is represented in memory by an instance of the
-** following structure.
-**
-** Table.zName is the name of the table.  The case of the original
-** CREATE TABLE statement is stored, but case is not significant for
-** comparisons.
-**
-** Table.nCol is the number of columns in this table.  Table.aCol is a
-** pointer to an array of Column structures, one for each column.
-**
-** If the table has an INTEGER PRIMARY KEY, then Table.iPKey is the index of
-** the column that is that key.   Otherwise Table.iPKey is negative.  Note
-** that the datatype of the PRIMARY KEY must be INTEGER for this field to
-** be set.  An INTEGER PRIMARY KEY is used as the rowid for each row of
-** the table.  If a table has no INTEGER PRIMARY KEY, then a random rowid
-** is generated for each row of the table.  TF_HasPrimaryKey is set if
-** the table has any PRIMARY KEY, INTEGER or otherwise.
-**
-** Table.tnum is the page number for the root BTree page of the table in the
-** database file.  If Table.iDb is the index of the database table backend
-** in sqlite.aDb[].  0 is for the main database and 1 is for the file that
-** holds temporary tables and indices.  If TF_Ephemeral is set
-** then the table is stored in a file that is automatically deleted
-** when the VDBE cursor to the table is closed.  In this case Table.tnum 
-** refers VDBE cursor number that holds the table open, not to the root
-** page number.  Transient tables are used to hold the results of a
-** sub-query that appears instead of a real table name in the FROM clause 
-** of a SELECT statement.
+** The schema for each SQL table and view is represented in memory
+** by an instance of the following structure.
 */
 struct Table {
   char *zName;         /* Name of the table or view */
@@ -10945,11 +11512,11 @@ struct Table {
 #ifndef SQLITE_OMIT_CHECK
   ExprList *pCheck;    /* All CHECK constraints */
 #endif
-  LogEst nRowLogEst;   /* Estimated rows in table - from sqlite_stat1 table */
-  int tnum;            /* Root BTree node for this table (see note above) */
-  i16 iPKey;           /* If not negative, use aCol[iPKey] as the primary key */
+  int tnum;            /* Root BTree page for this table */
+  i16 iPKey;           /* If not negative, use aCol[iPKey] as the rowid */
   i16 nCol;            /* Number of columns in this table */
   u16 nRef;            /* Number of pointers to this Table */
+  LogEst nRowLogEst;   /* Estimated rows in table - from sqlite_stat1 table */
   LogEst szTabRow;     /* Estimated size of each table row in bytes */
 #ifdef SQLITE_ENABLE_COSTMULT
   LogEst costMult;     /* Cost multiplier for using this table */
@@ -10971,6 +11538,12 @@ struct Table {
 
 /*
 ** Allowed values for Table.tabFlags.
+**
+** TF_OOOHidden applies to virtual tables that have hidden columns that are
+** followed by non-hidden columns.  Example:  "CREATE VIRTUAL TABLE x USING
+** vtab1(a HIDDEN, b);".  Since "b" is a non-hidden column but "a" is hidden,
+** the TF_OOOHidden attribute would apply in this case.  Such tables require
+** special handling during INSERT processing.
 */
 #define TF_Readonly        0x01    /* Read-only system table */
 #define TF_Ephemeral       0x02    /* An ephemeral table */
@@ -10978,6 +11551,7 @@ struct Table {
 #define TF_Autoincrement   0x08    /* Integer primary key is autoincrement */
 #define TF_Virtual         0x10    /* Is a virtual table */
 #define TF_WithoutRowid    0x20    /* No rowid used. PRIMARY KEY is the key */
+#define TF_OOOHidden       0x40    /* Out-of-Order hidden columns */
 
 
 /*
@@ -11121,7 +11695,7 @@ struct UnpackedRecord {
   KeyInfo *pKeyInfo;  /* Collation and sort-order information */
   u16 nField;         /* Number of entries in apMem[] */
   i8 default_rc;      /* Comparison result if keys are equal */
-  u8 isCorrupt;       /* Corruption detected by xRecordCompare() */
+  u8 errCode;         /* Error detected by xRecordCompare (CORRUPT or NOMEM) */
   Mem *aMem;          /* Values */
   int r1;             /* Value to return if (lhs > rhs) */
   int r2;             /* Value to return if (rhs < lhs) */
@@ -11165,7 +11739,6 @@ struct Index {
   u8 *aSortOrder;          /* for each column: True==DESC, False==ASC */
   char **azColl;           /* Array of collation sequence names for index */
   Expr *pPartIdxWhere;     /* WHERE clause for partial indices */
-  KeyInfo *pKeyInfo;       /* A KeyInfo object suitable for this index */
   int tnum;                /* DB Page containing root of this index */
   LogEst szIdxRow;         /* Estimated average row size in bytes */
   u16 nKeyCol;             /* Number of columns forming the key */
@@ -11176,11 +11749,14 @@ struct Index {
   unsigned uniqNotNull:1;  /* True if UNIQUE and NOT NULL for all columns */
   unsigned isResized:1;    /* True if resizeIndexObject() has been called */
   unsigned isCovering:1;   /* True if this is a covering index */
+  unsigned noSkipScan:1;   /* Do not try to use skip-scan if true */
 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
   int nSample;             /* Number of elements in aSample[] */
   int nSampleCol;          /* Size of IndexSample.anEq[] and so on */
   tRowcnt *aAvgEq;         /* Average nEq values for keys not in aSample */
   IndexSample *aSample;    /* Samples of the left-most key */
+  tRowcnt *aiRowEst;       /* Non-logarithmic stat1 data for this index */
+  tRowcnt nRowEst0;        /* Non-logarithmic number of rows in the index */
 #endif
 };
 
@@ -11378,7 +11954,7 @@ struct Expr {
   int iTable;            /* TK_COLUMN: cursor number of table holding column
                          ** TK_REGISTER: register number
                          ** TK_TRIGGER: 1 -> new, 0 -> old
-                         ** EP_Unlikely:  1000 times likelihood */
+                         ** EP_Unlikely:  134217728 times likelihood */
   ynVar iColumn;         /* TK_COLUMN: column index.  -1 for rowid.
                          ** TK_VARIABLE: variable number (always >= 1). */
   i16 iAgg;              /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
@@ -11393,7 +11969,7 @@ struct Expr {
 /*
 ** The following are the meanings of bits in the Expr.flags field.
 */
-#define EP_FromJoin  0x000001 /* Originated in ON or USING clause of a join */
+#define EP_FromJoin  0x000001 /* Originates in ON/USING clause of outer join */
 #define EP_Agg       0x000002 /* Contains one or more aggregate functions */
 #define EP_Resolved  0x000004 /* IDs have been resolved to COLUMNs */
 #define EP_Error     0x000008 /* Expression contains one or more errors */
@@ -11412,7 +11988,14 @@ struct Expr {
 #define EP_MemToken  0x010000 /* Need to sqlite3DbFree() Expr.zToken */
 #define EP_NoReduce  0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
 #define EP_Unlikely  0x040000 /* unlikely() or likelihood() function */
-#define EP_Constant  0x080000 /* Node is a constant */
+#define EP_ConstFunc 0x080000 /* Node is a SQLITE_FUNC_CONSTANT function */
+#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
+#define EP_Subquery  0x200000 /* Tree contains a TK_SELECT operator */
+
+/*
+** Combinations of two or more EP_* flags
+*/
+#define EP_Propagate (EP_Collate|EP_Subquery) /* Propagate these bits up tree */
 
 /*
 ** These macros can be used to test, set, or clear bits in the 
@@ -11611,7 +12194,7 @@ struct SrcList {
 #define WHERE_OMIT_OPEN_CLOSE  0x0010 /* Table cursors are already open */
 #define WHERE_FORCE_TABLE      0x0020 /* Do not use an index-only search */
 #define WHERE_ONETABLE_ONLY    0x0040 /* Only code the 1st table in pTabList */
-#define WHERE_AND_ONLY         0x0080 /* Don't use indices for OR terms */
+#define WHERE_NO_AUTOINDEX     0x0080 /* Disallow automatic indexes */
 #define WHERE_GROUPBY          0x0100 /* pOrderBy is really a GROUP BY */
 #define WHERE_DISTINCTBY       0x0200 /* pOrderby is really a DISTINCT clause */
 #define WHERE_WANT_DISTINCT    0x0400 /* All output needs to be distinct */
@@ -11654,17 +12237,22 @@ struct NameContext {
   NameContext *pNext;  /* Next outer name context.  NULL for outermost */
   int nRef;            /* Number of names resolved by this context */
   int nErr;            /* Number of errors encountered while resolving names */
-  u8 ncFlags;          /* Zero or more NC_* flags defined below */
+  u16 ncFlags;         /* Zero or more NC_* flags defined below */
 };
 
 /*
 ** Allowed values for the NameContext, ncFlags field.
+**
+** Note:  NC_MinMaxAgg must have the same value as SF_MinMaxAgg and
+** SQLITE_FUNC_MINMAX.
+** 
 */
-#define NC_AllowAgg  0x01    /* Aggregate functions are allowed here */
-#define NC_HasAgg    0x02    /* One or more aggregate functions seen */
-#define NC_IsCheck   0x04    /* True if resolving names in a CHECK constraint */
-#define NC_InAggFunc 0x08    /* True if analyzing arguments to an agg func */
-#define NC_PartIdx   0x10    /* True if resolving a partial index WHERE */
+#define NC_AllowAgg  0x0001  /* Aggregate functions are allowed here */
+#define NC_HasAgg    0x0002  /* One or more aggregate functions seen */
+#define NC_IsCheck   0x0004  /* True if resolving names in a CHECK constraint */
+#define NC_InAggFunc 0x0008  /* True if analyzing arguments to an agg func */
+#define NC_PartIdx   0x0010  /* True if resolving a partial index WHERE */
+#define NC_MinMaxAgg 0x1000  /* min/max aggregates seen.  See note above */
 
 /*
 ** An instance of the following structure contains all information
@@ -11691,6 +12279,9 @@ struct Select {
   u8 op;                 /* One of: TK_UNION TK_ALL TK_INTERSECT TK_EXCEPT */
   u16 selFlags;          /* Various SF_* values */
   int iLimit, iOffset;   /* Memory registers holding LIMIT & OFFSET counters */
+#if SELECTTRACE_ENABLED
+  char zSelName[12];     /* Symbolic name of this SELECT use for debugging */
+#endif
   int addrOpenEphm[2];   /* OP_OpenEphem opcodes related to this select */
   u64 nSelectRow;        /* Estimated number of result rows */
   SrcList *pSrc;         /* The FROM clause */
@@ -11715,13 +12306,14 @@ struct Select {
 #define SF_UsesEphemeral   0x0008  /* Uses the OpenEphemeral opcode */
 #define SF_Expanded        0x0010  /* sqlite3SelectExpand() called on this */
 #define SF_HasTypeInfo     0x0020  /* FROM subqueries have Table metadata */
-                    /*     0x0040  NOT USED */
+#define SF_Compound        0x0040  /* Part of a compound query */
 #define SF_Values          0x0080  /* Synthesized from VALUES clause */
-                    /*     0x0100  NOT USED */
+#define SF_MultiValue      0x0100  /* Single VALUES term with multiple rows */
 #define SF_NestedFrom      0x0200  /* Part of a parenthesized FROM clause */
 #define SF_MaybeConvert    0x0400  /* Need convertCompoundSelectToSubquery() */
 #define SF_Recursive       0x0800  /* The recursive part of a recursive CTE */
-#define SF_Compound        0x1000  /* Part of a compound query */
+#define SF_MinMaxAgg       0x1000  /* Aggregate containing min() or max() */
+#define SF_Converted       0x2000  /* By convertCompoundSelectToSubquery() */
 
 
 /*
@@ -11949,6 +12541,10 @@ struct Parse {
   int regRowid;        /* Register holding rowid of CREATE TABLE entry */
   int regRoot;         /* Register holding root page number for new objects */
   int nMaxArg;         /* Max args passed to user function by sub-program */
+#if SELECTTRACE_ENABLED
+  int nSelect;         /* Number of SELECT statements seen */
+  int nSelectIndent;   /* How far to indent SELECTTRACE() output */
+#endif
 #ifndef SQLITE_OMIT_SHARED_CACHE
   int nTableLock;        /* Number of locks in aTableLock */
   TableLock *aTableLock; /* Required table locks for shared-cache mode */
@@ -12028,15 +12624,16 @@ struct AuthContext {
 ** Bitfield flags for P5 value in various opcodes.
 */
 #define OPFLAG_NCHANGE       0x01    /* Set to update db->nChange */
+#define OPFLAG_EPHEM         0x01    /* OP_Column: Ephemeral output is ok */
 #define OPFLAG_LASTROWID     0x02    /* Set to update db->lastRowid */
 #define OPFLAG_ISUPDATE      0x04    /* This OP_Insert is an sql UPDATE */
 #define OPFLAG_APPEND        0x08    /* This is likely to be an append */
 #define OPFLAG_USESEEKRESULT 0x10    /* Try to avoid a seek in BtreeInsert() */
-#define OPFLAG_CLEARCACHE    0x20    /* Clear pseudo-table cache in OP_Column */
 #define OPFLAG_LENGTHARG     0x40    /* OP_Column only used for length() */
 #define OPFLAG_TYPEOFARG     0x80    /* OP_Column only used for typeof() */
 #define OPFLAG_BULKCSR       0x01    /* OP_Open** used to open bulk cursor */
-#define OPFLAG_P2ISREG       0x02    /* P2 to OP_Open** is a register number */
+#define OPFLAG_SEEKEQ        0x02    /* OP_Open** cursor uses EQ seek only */
+#define OPFLAG_P2ISREG       0x04    /* P2 to OP_Open** is a register number */
 #define OPFLAG_PERMUTE       0x01    /* OP_Compare: use the permutation */
 
 /*
@@ -12095,7 +12692,7 @@ struct Trigger {
  * orconf    -> stores the ON CONFLICT algorithm
  * pSelect   -> If this is an INSERT INTO ... SELECT ... statement, then
  *              this stores a pointer to the SELECT statement. Otherwise NULL.
- * target    -> A token holding the quoted name of the table to insert into.
+ * zTarget   -> Dequoted name of the table to insert into.
  * pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
  *              this stores values to be inserted. Otherwise NULL.
  * pIdList   -> If this is an INSERT INTO ... (<column-names>) VALUES ... 
@@ -12103,12 +12700,12 @@ struct Trigger {
  *              inserted into.
  *
  * (op == TK_DELETE)
- * target    -> A token holding the quoted name of the table to delete from.
+ * zTarget   -> Dequoted name of the table to delete from.
  * pWhere    -> The WHERE clause of the DELETE statement if one is specified.
  *              Otherwise NULL.
  * 
  * (op == TK_UPDATE)
- * target    -> A token holding the quoted name of the table to update rows of.
+ * zTarget   -> Dequoted name of the table to update.
  * pWhere    -> The WHERE clause of the UPDATE statement if one is specified.
  *              Otherwise NULL.
  * pExprList -> A list of the columns to update and the expressions to update
@@ -12120,8 +12717,8 @@ struct TriggerStep {
   u8 op;               /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
   u8 orconf;           /* OE_Rollback etc. */
   Trigger *pTrig;      /* The trigger that this step is a part of */
-  Select *pSelect;     /* SELECT statment or RHS of INSERT INTO .. SELECT ... */
-  Token target;        /* Target table for DELETE, UPDATE, INSERT */
+  Select *pSelect;     /* SELECT statement or RHS of INSERT INTO SELECT ... */
+  char *zTarget;       /* Target table for DELETE, UPDATE, INSERT */
   Expr *pWhere;        /* The WHERE clause for DELETE or UPDATE steps */
   ExprList *pExprList; /* SET clause for UPDATE. */
   IdList *pIdList;     /* Column names for INSERT */
@@ -12154,8 +12751,7 @@ struct StrAccum {
   char *zText;         /* The string collected so far */
   int  nChar;          /* Length of the string so far */
   int  nAlloc;         /* Amount of space allocated in zText */
-  int  mxAlloc;        /* Maximum allowed string length */
-  u8   useMalloc;      /* 0: none,  1: sqlite3DbMalloc,  2: sqlite3_malloc */
+  int  mxAlloc;        /* Maximum allowed allocation.  0 for no malloc usage */
   u8   accError;       /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
 };
 #define STRACCUM_NOMEM   1
@@ -12203,6 +12799,7 @@ struct Sqlite3Config {
   int nPage;                        /* Number of pages in pPage[] */
   int mxParserStack;                /* maximum depth of the parser stack */
   int sharedCacheEnabled;           /* true if shared-cache mode enabled */
+  u32 szPma;                        /* Maximum Sorter PMA size */
   /* The above might be initialized to non-zero.  The following need to always
   ** initially be zero, however. */
   int isInit;                       /* True after initialization has finished */
@@ -12258,9 +12855,11 @@ struct Walker {
   void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */
   Parse *pParse;                            /* Parser context.  */
   int walkerDepth;                          /* Number of subqueries */
+  u8 eCode;                                 /* A small processing code */
   union {                                   /* Extra data for callback */
     NameContext *pNC;                          /* Naming context */
-    int i;                                     /* Integer value */
+    int n;                                     /* A counter */
+    int iCur;                                  /* A cursor number */
     SrcList *pSrcList;                         /* FROM clause */
     struct SrcCount *pSrcCount;                /* Counting column references */
   } u;
@@ -12296,6 +12895,17 @@ struct With {
   } a[1];
 };
 
+#ifdef SQLITE_DEBUG
+/*
+** An instance of the TreeView object is used for printing the content of
+** data structures on sqlite3DebugPrintf() using a tree-like view.
+*/
+struct TreeView {
+  int iLevel;             /* Which level of the tree we are on */
+  u8  bLine[100];         /* Draw vertical in column i if bLine[i] is true */
+};
+#endif /* SQLITE_DEBUG */
+
 /*
 ** Assuming zIn points to the first byte of a UTF-8 character,
 ** advance zIn to point to the first byte of the next UTF-8 character.
@@ -12323,11 +12933,11 @@ SQLITE_PRIVATE int sqlite3CantopenError(int);
 
 /*
 ** FTS4 is really an extension for FTS3.  It is enabled using the
-** SQLITE_ENABLE_FTS3 macro.  But to avoid confusion we also all
-** the SQLITE_ENABLE_FTS4 macro to serve as an alisse for SQLITE_ENABLE_FTS3.
+** SQLITE_ENABLE_FTS3 macro.  But to avoid confusion we also call
+** the SQLITE_ENABLE_FTS4 macro to serve as an alias for SQLITE_ENABLE_FTS3.
 */
 #if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3)
-# define SQLITE_ENABLE_FTS3
+# define SQLITE_ENABLE_FTS3 1
 #endif
 
 /*
@@ -12361,6 +12971,7 @@ SQLITE_PRIVATE int sqlite3CantopenError(int);
 # define sqlite3Isxdigit(x)  isxdigit((unsigned char)(x))
 # define sqlite3Tolower(x)   tolower((unsigned char)(x))
 #endif
+SQLITE_PRIVATE int sqlite3IsIdChar(u8);
 
 /*
 ** Internal function prototypes
@@ -12371,15 +12982,15 @@ SQLITE_PRIVATE int sqlite3Strlen30(const char*);
 
 SQLITE_PRIVATE int sqlite3MallocInit(void);
 SQLITE_PRIVATE void sqlite3MallocEnd(void);
-SQLITE_PRIVATE void *sqlite3Malloc(int);
-SQLITE_PRIVATE void *sqlite3MallocZero(int);
-SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3*, int);
-SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3*, int);
+SQLITE_PRIVATE void *sqlite3Malloc(u64);
+SQLITE_PRIVATE void *sqlite3MallocZero(u64);
+SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3*, u64);
+SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3*, u64);
 SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3*,const char*);
-SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3*,const char*, int);
-SQLITE_PRIVATE void *sqlite3Realloc(void*, int);
-SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, int);
-SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, int);
+SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3*,const char*, u64);
+SQLITE_PRIVATE void *sqlite3Realloc(void*, u64);
+SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64);
+SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, u64);
 SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*);
 SQLITE_PRIVATE int sqlite3MallocSize(void*);
 SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, void*);
@@ -12425,10 +13036,15 @@ SQLITE_PRIVATE   int sqlite3MutexInit(void);
 SQLITE_PRIVATE   int sqlite3MutexEnd(void);
 #endif
 
-SQLITE_PRIVATE int sqlite3StatusValue(int);
-SQLITE_PRIVATE void sqlite3StatusAdd(int, int);
+SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int);
+SQLITE_PRIVATE void sqlite3StatusUp(int, int);
+SQLITE_PRIVATE void sqlite3StatusDown(int, int);
 SQLITE_PRIVATE void sqlite3StatusSet(int, int);
 
+/* Access to mutexes used by sqlite3_status() */
+SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void);
+SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void);
+
 #ifndef SQLITE_OMIT_FLOATING_POINT
 SQLITE_PRIVATE   int sqlite3IsNaN(double);
 #else
@@ -12452,32 +13068,21 @@ SQLITE_PRIVATE void sqlite3XPrintf(StrAccum*, u32, const char*, ...);
 SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...);
 SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
 SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3*,char*,const char*,...);
-#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
+#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
 SQLITE_PRIVATE   void sqlite3DebugPrintf(const char*, ...);
 #endif
 #if defined(SQLITE_TEST)
 SQLITE_PRIVATE   void *sqlite3TestTextToPtr(const char*);
 #endif
 
-/* Output formatting for SQLITE_TESTCTRL_EXPLAIN */
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
-SQLITE_PRIVATE   void sqlite3ExplainBegin(Vdbe*);
-SQLITE_PRIVATE   void sqlite3ExplainPrintf(Vdbe*, const char*, ...);
-SQLITE_PRIVATE   void sqlite3ExplainNL(Vdbe*);
-SQLITE_PRIVATE   void sqlite3ExplainPush(Vdbe*);
-SQLITE_PRIVATE   void sqlite3ExplainPop(Vdbe*);
-SQLITE_PRIVATE   void sqlite3ExplainFinish(Vdbe*);
-SQLITE_PRIVATE   void sqlite3ExplainSelect(Vdbe*, Select*);
-SQLITE_PRIVATE   void sqlite3ExplainExpr(Vdbe*, Expr*);
-SQLITE_PRIVATE   void sqlite3ExplainExprList(Vdbe*, ExprList*);
-SQLITE_PRIVATE   const char *sqlite3VdbeExplanation(Vdbe*);
-#else
-# define sqlite3ExplainBegin(X)
-# define sqlite3ExplainSelect(A,B)
-# define sqlite3ExplainExpr(A,B)
-# define sqlite3ExplainExprList(A,B)
-# define sqlite3ExplainFinish(X)
-# define sqlite3VdbeExplanation(X) 0
+#if defined(SQLITE_DEBUG)
+SQLITE_PRIVATE   TreeView *sqlite3TreeViewPush(TreeView*,u8);
+SQLITE_PRIVATE   void sqlite3TreeViewPop(TreeView*);
+SQLITE_PRIVATE   void sqlite3TreeViewLine(TreeView*, const char*, ...);
+SQLITE_PRIVATE   void sqlite3TreeViewItem(TreeView*, const char*, u8);
+SQLITE_PRIVATE   void sqlite3TreeViewExpr(TreeView*, const Expr*, u8);
+SQLITE_PRIVATE   void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
+SQLITE_PRIVATE   void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
 #endif
 
 
@@ -12504,6 +13109,7 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
 SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
 SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
 SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*);
+SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*);
 SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**);
 SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**);
 SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int);
@@ -12659,7 +13265,8 @@ SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *);
 SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
 SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*);
 SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*);
-SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*);
+SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8);
+SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int);
 SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*);
 SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*);
 SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
@@ -12683,6 +13290,11 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
 SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
 SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
 SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
+#if SELECTTRACE_ENABLED
+SQLITE_PRIVATE void sqlite3SelectSetName(Select*,const char*);
+#else
+# define sqlite3SelectSetName(A,B)
+#endif
 SQLITE_PRIVATE void sqlite3FuncDefInsert(FuncDefHash*, FuncDef*);
 SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,int,u8,u8);
 SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3*);
@@ -12769,38 +13381,23 @@ SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst);
 /*
 ** Routines to read and write variable-length integers.  These used to
 ** be defined locally, but now we use the varint routines in the util.c
-** file.  Code should use the MACRO forms below, as the Varint32 versions
-** are coded to assume the single byte case is already handled (which 
-** the MACRO form does).
+** file.
 */
 SQLITE_PRIVATE int sqlite3PutVarint(unsigned char*, u64);
-SQLITE_PRIVATE int sqlite3PutVarint32(unsigned char*, u32);
 SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *, u64 *);
 SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *, u32 *);
 SQLITE_PRIVATE int sqlite3VarintLen(u64 v);
 
 /*
-** The header of a record consists of a sequence variable-length integers.
-** These integers are almost always small and are encoded as a single byte.
-** The following macros take advantage this fact to provide a fast encode
-** and decode of the integers in a record header.  It is faster for the common
-** case where the integer is a single byte.  It is a little slower when the
-** integer is two or more bytes.  But overall it is faster.
-**
-** The following expressions are equivalent:
-**
-**     x = sqlite3GetVarint32( A, &B );
-**     x = sqlite3PutVarint32( A, B );
-**
-**     x = getVarint32( A, B );
-**     x = putVarint32( A, B );
-**
+** The common case is for a varint to be a single byte.  They following
+** macros handle the common case without a procedure call, but then call
+** the procedure for larger varints.
 */
 #define getVarint32(A,B)  \
   (u8)((*(A)<(u8)0x80)?((B)=(u32)*(A)),1:sqlite3GetVarint32((A),(u32 *)&(B)))
 #define putVarint32(A,B)  \
   (u8)(((u32)(B)<(u32)0x80)?(*(A)=(unsigned char)(B)),1:\
-  sqlite3PutVarint32((A),(B)))
+  sqlite3PutVarint((A),(B)))
 #define getVarint    sqlite3GetVarint
 #define putVarint    sqlite3PutVarint
 
@@ -12812,12 +13409,13 @@ SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity);
 SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr);
 SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8);
 SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*);
-SQLITE_PRIVATE void sqlite3Error(sqlite3*, int, const char*,...);
+SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...);
+SQLITE_PRIVATE void sqlite3Error(sqlite3*,int);
 SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
 SQLITE_PRIVATE u8 sqlite3HexToInt(int h);
 SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
 
-#if defined(SQLITE_TEST) 
+#if defined(SQLITE_NEED_ERR_NAME)
 SQLITE_PRIVATE const char *sqlite3ErrName(int);
 #endif
 
@@ -12826,7 +13424,7 @@ SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse);
 SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
 SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
 SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr);
-SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*);
+SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
 SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
 SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*);
 SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *);
@@ -12911,10 +13509,10 @@ SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
 SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
 SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);
 
-SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, char*, int, int);
+SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
 SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int);
 SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum*,const char*);
-SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum*,int);
+SQLITE_PRIVATE void sqlite3AppendChar(StrAccum*,int,char);
 SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
 SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*);
 SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int);
@@ -12934,7 +13532,7 @@ SQLITE_PRIVATE int sqlite3Stat4Column(sqlite3*, const void*, int, int, sqlite3_v
 /*
 ** The interface to the LEMON-generated parser
 */
-SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(size_t));
+SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(u64));
 SQLITE_PRIVATE void sqlite3ParserFree(void*, void(*)(void*));
 SQLITE_PRIVATE void sqlite3Parser(void*, int, Token, Parse*);
 #ifdef YYTRACKMAXSTACKDEPTH
@@ -13095,12 +13693,11 @@ SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *);
 SQLITE_PRIVATE int sqlite3MemJournalSize(void);
 SQLITE_PRIVATE int sqlite3IsMemJournal(sqlite3_file *);
 
+SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p);
 #if SQLITE_MAX_EXPR_DEPTH>0
-SQLITE_PRIVATE   void sqlite3ExprSetHeight(Parse *pParse, Expr *p);
 SQLITE_PRIVATE   int sqlite3SelectExprHeight(Select *);
 SQLITE_PRIVATE   int sqlite3ExprCheckHeight(Parse*, int);
 #else
-  #define sqlite3ExprSetHeight(x,y)
   #define sqlite3SelectExprHeight(x) 0
   #define sqlite3ExprCheckHeight(x,y)
 #endif
@@ -13130,7 +13727,7 @@ SQLITE_PRIVATE   void sqlite3ParserTrace(FILE*, char *);
 #ifdef SQLITE_ENABLE_IOTRACE
 # define IOTRACE(A)  if( sqlite3IoTrace ){ sqlite3IoTrace A; }
 SQLITE_PRIVATE   void sqlite3VdbeIOTraceSql(Vdbe*);
-SQLITE_PRIVATE void (*sqlite3IoTrace)(const char*,...);
+SQLITE_API SQLITE_EXTERN void (SQLITE_CDECL *sqlite3IoTrace)(const char*,...);
 #else
 # define IOTRACE(A)
 # define sqlite3VdbeIOTraceSql(X)
@@ -13174,10 +13771,17 @@ SQLITE_PRIVATE   int sqlite3MemdebugNoType(void*,u8);
 # define sqlite3MemdebugNoType(X,Y)   1
 #endif
 #define MEMTYPE_HEAP       0x01  /* General heap allocations */
-#define MEMTYPE_LOOKASIDE  0x02  /* Might have been lookaside memory */
+#define MEMTYPE_LOOKASIDE  0x02  /* Heap that might have been lookaside */
 #define MEMTYPE_SCRATCH    0x04  /* Scratch allocations */
 #define MEMTYPE_PCACHE     0x08  /* Page cache allocations */
-#define MEMTYPE_DB         0x10  /* Uses sqlite3DbMalloc, not sqlite_malloc */
+
+/*
+** Threading interface
+*/
+#if SQLITE_MAX_WORKER_THREADS>0
+SQLITE_PRIVATE int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*);
+SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread*, void**);
+#endif
 
 #endif /* _SQLITEINT_H_ */
 
@@ -13195,7 +13799,7 @@ SQLITE_PRIVATE   int sqlite3MemdebugNoType(void*,u8);
 **
 *************************************************************************
 **
-** This file contains definitions of global variables and contants.
+** This file contains definitions of global variables and constants.
 */
 
 /* An array to map all upper-case characters into their corresponding
@@ -13230,16 +13834,16 @@ SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[] = {
      48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 3x */
      64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 4x */
      80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 5x */
-     96, 97, 66, 67, 68, 69, 70, 71, 72, 73,106,107,108,109,110,111, /* 6x */
-    112, 81, 82, 83, 84, 85, 86, 87, 88, 89,122,123,124,125,126,127, /* 7x */
+     96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 6x */
+    112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /* 7x */
     128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, /* 8x */
-    144,145,146,147,148,149,150,151,152,153,154,155,156,157,156,159, /* 9x */
+    144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, /* 9x */
     160,161,162,163,164,165,166,167,168,169,170,171,140,141,142,175, /* Ax */
     176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, /* Bx */
     192,129,130,131,132,133,134,135,136,137,202,203,204,205,206,207, /* Cx */
     208,145,146,147,148,149,150,151,152,153,218,219,220,221,222,223, /* Dx */
-    224,225,162,163,164,165,166,167,168,169,232,203,204,205,206,207, /* Ex */
-    239,240,241,242,243,244,245,246,247,248,249,219,220,221,222,255, /* Fx */
+    224,225,162,163,164,165,166,167,168,169,234,235,236,237,238,239, /* Ex */
+    240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, /* Fx */
 #endif
 };
 
@@ -13313,14 +13917,36 @@ SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
 };
 #endif
 
+/* EVIDENCE-OF: R-02982-34736 In order to maintain full backwards
+** compatibility for legacy applications, the URI filename capability is
+** disabled by default.
+**
+** EVIDENCE-OF: R-38799-08373 URI filenames can be enabled or disabled
+** using the SQLITE_USE_URI=1 or SQLITE_USE_URI=0 compile-time options.
+**
+** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally
+** disabled. The default value may be changed by compiling with the
+** SQLITE_USE_URI symbol defined.
+*/
 #ifndef SQLITE_USE_URI
 # define  SQLITE_USE_URI 0
 #endif
 
+/* EVIDENCE-OF: R-38720-18127 The default setting is determined by the
+** SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option, or is "on" if
+** that compile-time option is omitted.
+*/
 #ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
 # define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
 #endif
 
+/* The minimum PMA size is set to this value multiplied by the database
+** page size in bytes.
+*/
+#ifndef SQLITE_SORTER_PMASZ
+# define SQLITE_SORTER_PMASZ 250
+#endif
+
 /*
 ** The following singleton contains the global configuration for
 ** the SQLite library.
@@ -13351,6 +13977,7 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = {
    0,                         /* nPage */
    0,                         /* mxParserStack */
    0,                         /* sharedCacheEnabled */
+   SQLITE_SORTER_PMASZ,       /* szPma */
    /* All the rest should always be initialized to zero */
    0,                         /* isInit */
    0,                         /* inProgress */
@@ -13406,8 +14033,8 @@ SQLITE_PRIVATE const Token sqlite3IntTokens[] = {
 **
 ** IMPORTANT:  Changing the pending byte to any value other than
 ** 0x40000000 results in an incompatible database file format!
-** Changing the pending byte during operating results in undefined
-** and dileterious behavior.
+** Changing the pending byte during operation will result in undefined
+** and incorrect behavior.
 */
 #ifndef SQLITE_OMIT_WSD
 SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000;
@@ -13457,88 +14084,94 @@ static const char * const azCompileOpt[] = {
 #define CTIMEOPT_VAL_(opt) #opt
 #define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
 
-#ifdef SQLITE_32BIT_ROWID
+#if SQLITE_32BIT_ROWID
   "32BIT_ROWID",
 #endif
-#ifdef SQLITE_4_BYTE_ALIGNED_MALLOC
+#if SQLITE_4_BYTE_ALIGNED_MALLOC
   "4_BYTE_ALIGNED_MALLOC",
 #endif
-#ifdef SQLITE_CASE_SENSITIVE_LIKE
+#if SQLITE_CASE_SENSITIVE_LIKE
   "CASE_SENSITIVE_LIKE",
 #endif
-#ifdef SQLITE_CHECK_PAGES
+#if SQLITE_CHECK_PAGES
   "CHECK_PAGES",
 #endif
-#ifdef SQLITE_COVERAGE_TEST
+#if SQLITE_COVERAGE_TEST
   "COVERAGE_TEST",
 #endif
-#ifdef SQLITE_DEBUG
+#if SQLITE_DEBUG
   "DEBUG",
 #endif
-#ifdef SQLITE_DEFAULT_LOCKING_MODE
+#if SQLITE_DEFAULT_LOCKING_MODE
   "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
 #endif
 #if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc)
   "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE),
 #endif
-#ifdef SQLITE_DISABLE_DIRSYNC
+#if SQLITE_DISABLE_DIRSYNC
   "DISABLE_DIRSYNC",
 #endif
-#ifdef SQLITE_DISABLE_LFS
+#if SQLITE_DISABLE_LFS
   "DISABLE_LFS",
 #endif
-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+#if SQLITE_ENABLE_API_ARMOR
+  "ENABLE_API_ARMOR",
+#endif
+#if SQLITE_ENABLE_ATOMIC_WRITE
   "ENABLE_ATOMIC_WRITE",
 #endif
-#ifdef SQLITE_ENABLE_CEROD
+#if SQLITE_ENABLE_CEROD
   "ENABLE_CEROD",
 #endif
-#ifdef SQLITE_ENABLE_COLUMN_METADATA
+#if SQLITE_ENABLE_COLUMN_METADATA
   "ENABLE_COLUMN_METADATA",
 #endif
-#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
+#if SQLITE_ENABLE_DBSTAT_VTAB
+  "ENABLE_DBSTAT_VTAB",
+#endif
+#if SQLITE_ENABLE_EXPENSIVE_ASSERT
   "ENABLE_EXPENSIVE_ASSERT",
 #endif
-#ifdef SQLITE_ENABLE_FTS1
+#if SQLITE_ENABLE_FTS1
   "ENABLE_FTS1",
 #endif
-#ifdef SQLITE_ENABLE_FTS2
+#if SQLITE_ENABLE_FTS2
   "ENABLE_FTS2",
 #endif
-#ifdef SQLITE_ENABLE_FTS3
+#if SQLITE_ENABLE_FTS3
   "ENABLE_FTS3",
 #endif
-#ifdef SQLITE_ENABLE_FTS3_PARENTHESIS
+#if SQLITE_ENABLE_FTS3_PARENTHESIS
   "ENABLE_FTS3_PARENTHESIS",
 #endif
-#ifdef SQLITE_ENABLE_FTS4
+#if SQLITE_ENABLE_FTS4
   "ENABLE_FTS4",
 #endif
-#ifdef SQLITE_ENABLE_ICU
+#if SQLITE_ENABLE_ICU
   "ENABLE_ICU",
 #endif
-#ifdef SQLITE_ENABLE_IOTRACE
+#if SQLITE_ENABLE_IOTRACE
   "ENABLE_IOTRACE",
 #endif
-#ifdef SQLITE_ENABLE_LOAD_EXTENSION
+#if SQLITE_ENABLE_LOAD_EXTENSION
   "ENABLE_LOAD_EXTENSION",
 #endif
-#ifdef SQLITE_ENABLE_LOCKING_STYLE
+#if SQLITE_ENABLE_LOCKING_STYLE
   "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE),
 #endif
-#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+#if SQLITE_ENABLE_MEMORY_MANAGEMENT
   "ENABLE_MEMORY_MANAGEMENT",
 #endif
-#ifdef SQLITE_ENABLE_MEMSYS3
+#if SQLITE_ENABLE_MEMSYS3
   "ENABLE_MEMSYS3",
 #endif
-#ifdef SQLITE_ENABLE_MEMSYS5
+#if SQLITE_ENABLE_MEMSYS5
   "ENABLE_MEMSYS5",
 #endif
-#ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK
+#if SQLITE_ENABLE_OVERSIZE_CELL_CHECK
   "ENABLE_OVERSIZE_CELL_CHECK",
 #endif
-#ifdef SQLITE_ENABLE_RTREE
+#if SQLITE_ENABLE_RTREE
   "ENABLE_RTREE",
 #endif
 #if defined(SQLITE_ENABLE_STAT4)
@@ -13546,31 +14179,31 @@ static const char * const azCompileOpt[] = {
 #elif defined(SQLITE_ENABLE_STAT3)
   "ENABLE_STAT3",
 #endif
-#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
+#if SQLITE_ENABLE_UNLOCK_NOTIFY
   "ENABLE_UNLOCK_NOTIFY",
 #endif
-#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
+#if SQLITE_ENABLE_UPDATE_DELETE_LIMIT
   "ENABLE_UPDATE_DELETE_LIMIT",
 #endif
-#ifdef SQLITE_HAS_CODEC
+#if SQLITE_HAS_CODEC
   "HAS_CODEC",
 #endif
-#ifdef SQLITE_HAVE_ISNAN
+#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
   "HAVE_ISNAN",
 #endif
-#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
+#if SQLITE_HOMEGROWN_RECURSIVE_MUTEX
   "HOMEGROWN_RECURSIVE_MUTEX",
 #endif
-#ifdef SQLITE_IGNORE_AFP_LOCK_ERRORS
+#if SQLITE_IGNORE_AFP_LOCK_ERRORS
   "IGNORE_AFP_LOCK_ERRORS",
 #endif
-#ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS
+#if SQLITE_IGNORE_FLOCK_LOCK_ERRORS
   "IGNORE_FLOCK_LOCK_ERRORS",
 #endif
 #ifdef SQLITE_INT64_TYPE
   "INT64_TYPE",
 #endif
-#ifdef SQLITE_LOCK_TRACE
+#if SQLITE_LOCK_TRACE
   "LOCK_TRACE",
 #endif
 #if defined(SQLITE_MAX_MMAP_SIZE) && !defined(SQLITE_MAX_MMAP_SIZE_xc)
@@ -13579,223 +14212,226 @@ static const char * const azCompileOpt[] = {
 #ifdef SQLITE_MAX_SCHEMA_RETRY
   "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY),
 #endif
-#ifdef SQLITE_MEMDEBUG
+#if SQLITE_MEMDEBUG
   "MEMDEBUG",
 #endif
-#ifdef SQLITE_MIXED_ENDIAN_64BIT_FLOAT
+#if SQLITE_MIXED_ENDIAN_64BIT_FLOAT
   "MIXED_ENDIAN_64BIT_FLOAT",
 #endif
-#ifdef SQLITE_NO_SYNC
+#if SQLITE_NO_SYNC
   "NO_SYNC",
 #endif
-#ifdef SQLITE_OMIT_ALTERTABLE
+#if SQLITE_OMIT_ALTERTABLE
   "OMIT_ALTERTABLE",
 #endif
-#ifdef SQLITE_OMIT_ANALYZE
+#if SQLITE_OMIT_ANALYZE
   "OMIT_ANALYZE",
 #endif
-#ifdef SQLITE_OMIT_ATTACH
+#if SQLITE_OMIT_ATTACH
   "OMIT_ATTACH",
 #endif
-#ifdef SQLITE_OMIT_AUTHORIZATION
+#if SQLITE_OMIT_AUTHORIZATION
   "OMIT_AUTHORIZATION",
 #endif
-#ifdef SQLITE_OMIT_AUTOINCREMENT
+#if SQLITE_OMIT_AUTOINCREMENT
   "OMIT_AUTOINCREMENT",
 #endif
-#ifdef SQLITE_OMIT_AUTOINIT
+#if SQLITE_OMIT_AUTOINIT
   "OMIT_AUTOINIT",
 #endif
-#ifdef SQLITE_OMIT_AUTOMATIC_INDEX
+#if SQLITE_OMIT_AUTOMATIC_INDEX
   "OMIT_AUTOMATIC_INDEX",
 #endif
-#ifdef SQLITE_OMIT_AUTORESET
+#if SQLITE_OMIT_AUTORESET
   "OMIT_AUTORESET",
 #endif
-#ifdef SQLITE_OMIT_AUTOVACUUM
+#if SQLITE_OMIT_AUTOVACUUM
   "OMIT_AUTOVACUUM",
 #endif
-#ifdef SQLITE_OMIT_BETWEEN_OPTIMIZATION
+#if SQLITE_OMIT_BETWEEN_OPTIMIZATION
   "OMIT_BETWEEN_OPTIMIZATION",
 #endif
-#ifdef SQLITE_OMIT_BLOB_LITERAL
+#if SQLITE_OMIT_BLOB_LITERAL
   "OMIT_BLOB_LITERAL",
 #endif
-#ifdef SQLITE_OMIT_BTREECOUNT
+#if SQLITE_OMIT_BTREECOUNT
   "OMIT_BTREECOUNT",
 #endif
-#ifdef SQLITE_OMIT_BUILTIN_TEST
+#if SQLITE_OMIT_BUILTIN_TEST
   "OMIT_BUILTIN_TEST",
 #endif
-#ifdef SQLITE_OMIT_CAST
+#if SQLITE_OMIT_CAST
   "OMIT_CAST",
 #endif
-#ifdef SQLITE_OMIT_CHECK
+#if SQLITE_OMIT_CHECK
   "OMIT_CHECK",
 #endif
-#ifdef SQLITE_OMIT_COMPLETE
+#if SQLITE_OMIT_COMPLETE
   "OMIT_COMPLETE",
 #endif
-#ifdef SQLITE_OMIT_COMPOUND_SELECT
+#if SQLITE_OMIT_COMPOUND_SELECT
   "OMIT_COMPOUND_SELECT",
 #endif
-#ifdef SQLITE_OMIT_CTE
+#if SQLITE_OMIT_CTE
   "OMIT_CTE",
 #endif
-#ifdef SQLITE_OMIT_DATETIME_FUNCS
+#if SQLITE_OMIT_DATETIME_FUNCS
   "OMIT_DATETIME_FUNCS",
 #endif
-#ifdef SQLITE_OMIT_DECLTYPE
+#if SQLITE_OMIT_DECLTYPE
   "OMIT_DECLTYPE",
 #endif
-#ifdef SQLITE_OMIT_DEPRECATED
+#if SQLITE_OMIT_DEPRECATED
   "OMIT_DEPRECATED",
 #endif
-#ifdef SQLITE_OMIT_DISKIO
+#if SQLITE_OMIT_DISKIO
   "OMIT_DISKIO",
 #endif
-#ifdef SQLITE_OMIT_EXPLAIN
+#if SQLITE_OMIT_EXPLAIN
   "OMIT_EXPLAIN",
 #endif
-#ifdef SQLITE_OMIT_FLAG_PRAGMAS
+#if SQLITE_OMIT_FLAG_PRAGMAS
   "OMIT_FLAG_PRAGMAS",
 #endif
-#ifdef SQLITE_OMIT_FLOATING_POINT
+#if SQLITE_OMIT_FLOATING_POINT
   "OMIT_FLOATING_POINT",
 #endif
-#ifdef SQLITE_OMIT_FOREIGN_KEY
+#if SQLITE_OMIT_FOREIGN_KEY
   "OMIT_FOREIGN_KEY",
 #endif
-#ifdef SQLITE_OMIT_GET_TABLE
+#if SQLITE_OMIT_GET_TABLE
   "OMIT_GET_TABLE",
 #endif
-#ifdef SQLITE_OMIT_INCRBLOB
+#if SQLITE_OMIT_INCRBLOB
   "OMIT_INCRBLOB",
 #endif
-#ifdef SQLITE_OMIT_INTEGRITY_CHECK
+#if SQLITE_OMIT_INTEGRITY_CHECK
   "OMIT_INTEGRITY_CHECK",
 #endif
-#ifdef SQLITE_OMIT_LIKE_OPTIMIZATION
+#if SQLITE_OMIT_LIKE_OPTIMIZATION
   "OMIT_LIKE_OPTIMIZATION",
 #endif
-#ifdef SQLITE_OMIT_LOAD_EXTENSION
+#if SQLITE_OMIT_LOAD_EXTENSION
   "OMIT_LOAD_EXTENSION",
 #endif
-#ifdef SQLITE_OMIT_LOCALTIME
+#if SQLITE_OMIT_LOCALTIME
   "OMIT_LOCALTIME",
 #endif
-#ifdef SQLITE_OMIT_LOOKASIDE
+#if SQLITE_OMIT_LOOKASIDE
   "OMIT_LOOKASIDE",
 #endif
-#ifdef SQLITE_OMIT_MEMORYDB
+#if SQLITE_OMIT_MEMORYDB
   "OMIT_MEMORYDB",
 #endif
-#ifdef SQLITE_OMIT_OR_OPTIMIZATION
+#if SQLITE_OMIT_OR_OPTIMIZATION
   "OMIT_OR_OPTIMIZATION",
 #endif
-#ifdef SQLITE_OMIT_PAGER_PRAGMAS
+#if SQLITE_OMIT_PAGER_PRAGMAS
   "OMIT_PAGER_PRAGMAS",
 #endif
-#ifdef SQLITE_OMIT_PRAGMA
+#if SQLITE_OMIT_PRAGMA
   "OMIT_PRAGMA",
 #endif
-#ifdef SQLITE_OMIT_PROGRESS_CALLBACK
+#if SQLITE_OMIT_PROGRESS_CALLBACK
   "OMIT_PROGRESS_CALLBACK",
 #endif
-#ifdef SQLITE_OMIT_QUICKBALANCE
+#if SQLITE_OMIT_QUICKBALANCE
   "OMIT_QUICKBALANCE",
 #endif
-#ifdef SQLITE_OMIT_REINDEX
+#if SQLITE_OMIT_REINDEX
   "OMIT_REINDEX",
 #endif
-#ifdef SQLITE_OMIT_SCHEMA_PRAGMAS
+#if SQLITE_OMIT_SCHEMA_PRAGMAS
   "OMIT_SCHEMA_PRAGMAS",
 #endif
-#ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
+#if SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
   "OMIT_SCHEMA_VERSION_PRAGMAS",
 #endif
-#ifdef SQLITE_OMIT_SHARED_CACHE
+#if SQLITE_OMIT_SHARED_CACHE
   "OMIT_SHARED_CACHE",
 #endif
-#ifdef SQLITE_OMIT_SUBQUERY
+#if SQLITE_OMIT_SUBQUERY
   "OMIT_SUBQUERY",
 #endif
-#ifdef SQLITE_OMIT_TCL_VARIABLE
+#if SQLITE_OMIT_TCL_VARIABLE
   "OMIT_TCL_VARIABLE",
 #endif
-#ifdef SQLITE_OMIT_TEMPDB
+#if SQLITE_OMIT_TEMPDB
   "OMIT_TEMPDB",
 #endif
-#ifdef SQLITE_OMIT_TRACE
+#if SQLITE_OMIT_TRACE
   "OMIT_TRACE",
 #endif
-#ifdef SQLITE_OMIT_TRIGGER
+#if SQLITE_OMIT_TRIGGER
   "OMIT_TRIGGER",
 #endif
-#ifdef SQLITE_OMIT_TRUNCATE_OPTIMIZATION
+#if SQLITE_OMIT_TRUNCATE_OPTIMIZATION
   "OMIT_TRUNCATE_OPTIMIZATION",
 #endif
-#ifdef SQLITE_OMIT_UTF16
+#if SQLITE_OMIT_UTF16
   "OMIT_UTF16",
 #endif
-#ifdef SQLITE_OMIT_VACUUM
+#if SQLITE_OMIT_VACUUM
   "OMIT_VACUUM",
 #endif
-#ifdef SQLITE_OMIT_VIEW
+#if SQLITE_OMIT_VIEW
   "OMIT_VIEW",
 #endif
-#ifdef SQLITE_OMIT_VIRTUALTABLE
+#if SQLITE_OMIT_VIRTUALTABLE
   "OMIT_VIRTUALTABLE",
 #endif
-#ifdef SQLITE_OMIT_WAL
+#if SQLITE_OMIT_WAL
   "OMIT_WAL",
 #endif
-#ifdef SQLITE_OMIT_WSD
+#if SQLITE_OMIT_WSD
   "OMIT_WSD",
 #endif
-#ifdef SQLITE_OMIT_XFER_OPT
+#if SQLITE_OMIT_XFER_OPT
   "OMIT_XFER_OPT",
 #endif
-#ifdef SQLITE_PERFORMANCE_TRACE
+#if SQLITE_PERFORMANCE_TRACE
   "PERFORMANCE_TRACE",
 #endif
-#ifdef SQLITE_PROXY_DEBUG
+#if SQLITE_PROXY_DEBUG
   "PROXY_DEBUG",
 #endif
-#ifdef SQLITE_RTREE_INT_ONLY
+#if SQLITE_RTREE_INT_ONLY
   "RTREE_INT_ONLY",
 #endif
-#ifdef SQLITE_SECURE_DELETE
+#if SQLITE_SECURE_DELETE
   "SECURE_DELETE",
 #endif
-#ifdef SQLITE_SMALL_STACK
+#if SQLITE_SMALL_STACK
   "SMALL_STACK",
 #endif
-#ifdef SQLITE_SOUNDEX
+#if SQLITE_SOUNDEX
   "SOUNDEX",
 #endif
-#ifdef SQLITE_SYSTEM_MALLOC
+#if SQLITE_SYSTEM_MALLOC
   "SYSTEM_MALLOC",
 #endif
-#ifdef SQLITE_TCL
+#if SQLITE_TCL
   "TCL",
 #endif
 #if defined(SQLITE_TEMP_STORE) && !defined(SQLITE_TEMP_STORE_xc)
   "TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE),
 #endif
-#ifdef SQLITE_TEST
+#if SQLITE_TEST
   "TEST",
 #endif
 #if defined(SQLITE_THREADSAFE)
   "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE),
 #endif
-#ifdef SQLITE_USE_ALLOCA
+#if SQLITE_USE_ALLOCA
   "USE_ALLOCA",
 #endif
-#ifdef SQLITE_WIN32_MALLOC
+#if SQLITE_USER_AUTHENTICATION
+  "USER_AUTHENTICATION",
+#endif
+#if SQLITE_WIN32_MALLOC
   "WIN32_MALLOC",
 #endif
-#ifdef SQLITE_ZERO_MALLOC
+#if SQLITE_ZERO_MALLOC
   "ZERO_MALLOC"
 #endif
 };
@@ -13807,8 +14443,15 @@ static const char * const azCompileOpt[] = {
 ** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix
 ** is not required for a match.
 */
-SQLITE_API int sqlite3_compileoption_used(const char *zOptName){
+SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName){
   int i, n;
+
+#if SQLITE_ENABLE_API_ARMOR
+  if( zOptName==0 ){
+    (void)SQLITE_MISUSE_BKPT;
+    return 0;
+  }
+#endif
   if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7;
   n = sqlite3Strlen30(zOptName);
 
@@ -13816,7 +14459,7 @@ SQLITE_API int sqlite3_compileoption_used(const char *zOptName){
   ** linear search is adequate.  No need for a binary search. */
   for(i=0; i<ArraySize(azCompileOpt); i++){
     if( sqlite3StrNICmp(zOptName, azCompileOpt[i], n)==0
-     && sqlite3CtypeMap[(unsigned char)azCompileOpt[i][n]]==0
+     && sqlite3IsIdChar((unsigned char)azCompileOpt[i][n])==0
     ){
       return 1;
     }
@@ -13828,7 +14471,7 @@ SQLITE_API int sqlite3_compileoption_used(const char *zOptName){
 ** Return the N-th compile-time option string.  If N is out of range,
 ** return a NULL pointer.
 */
-SQLITE_API const char *sqlite3_compileoption_get(int N){
+SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N){
   if( N>=0 && N<ArraySize(azCompileOpt) ){
     return azCompileOpt[N];
   }
@@ -13931,7 +14574,6 @@ struct VdbeCursor {
 #endif
   i8 iDb;               /* Index of cursor database in db->aDb[] (or -1) */
   u8 nullRow;           /* True if pointing to a row with no data */
-  u8 rowidIsValid;      /* True if lastRowid is valid */
   u8 deferredMoveto;    /* A call to sqlite3BtreeMoveto() is needed */
   Bool isEphemeral:1;   /* True for an ephemeral table */
   Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
@@ -13941,7 +14583,6 @@ struct VdbeCursor {
   sqlite3_vtab_cursor *pVtabCursor;  /* The cursor for a virtual table */
   i64 seqCount;         /* Sequence counter */
   i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
-  i64 lastRowid;        /* Rowid being deleted by OP_Delete */
   VdbeSorter *pSorter;  /* Sorter object for OP_SorterOpen cursors */
 
   /* Cached information about the header for the data record that the
@@ -13958,6 +14599,7 @@ struct VdbeCursor {
   u32 szRow;            /* Byte available in aRow */
   u32 iHdrOffset;       /* Offset to next unparsed byte of the header */
   const u8 *aRow;       /* Data for the current row, if all on one page */
+  u32 *aOffset;         /* Pointer to aType[nField] */
   u32 aType[1];         /* Type values for all entries in the record */
   /* 2*nField extra array elements allocated for aType[], beyond the one
   ** static element declared in the structure.  nField total array slots for
@@ -13991,6 +14633,7 @@ struct VdbeFrame {
   Vdbe *v;                /* VM this frame belongs to */
   VdbeFrame *pParent;     /* Parent of this frame, or NULL if parent is main */
   Op *aOp;                /* Program instructions for parent frame */
+  i64 *anExec;            /* Event counters from parent frame */
   Mem *aMem;              /* Array of memory cells for parent frame */
   u8 *aOnceFlag;          /* Array of OP_Once flags for parent frame */
   VdbeCursor **apCsr;     /* Array of Vdbe cursors for parent frame */
@@ -14003,7 +14646,8 @@ struct VdbeFrame {
   int nOnceFlag;          /* Number of entries in aOnceFlag */
   int nChildMem;          /* Number of memory cells for child frame */
   int nChildCsr;          /* Number of cursors for child frame */
-  int nChange;            /* Statement changes (Vdbe.nChanges)     */
+  int nChange;            /* Statement changes (Vdbe.nChange)     */
+  int nDbChange;          /* Value of db->nChange */
 };
 
 #define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
@@ -14019,25 +14663,28 @@ struct VdbeFrame {
 ** integer etc.) of the same value.
 */
 struct Mem {
-  sqlite3 *db;        /* The associated database connection */
-  char *z;            /* String or BLOB value */
-  double r;           /* Real value */
-  union {
+  union MemValue {
+    double r;           /* Real value used when MEM_Real is set in flags */
     i64 i;              /* Integer value used when MEM_Int is set in flags */
     int nZero;          /* Used when bit MEM_Zero is set in flags */
     FuncDef *pDef;      /* Used only when flags==MEM_Agg */
     RowSet *pRowSet;    /* Used only when flags==MEM_RowSet */
     VdbeFrame *pFrame;  /* Used when flags==MEM_Frame */
   } u;
-  int n;              /* Number of characters in string value, excluding '\0' */
   u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
   u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
+  int n;              /* Number of characters in string value, excluding '\0' */
+  char *z;            /* String or BLOB value */
+  /* ShallowCopy only needs to copy the information above */
+  char *zMalloc;      /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
+  int szMalloc;       /* Size of the zMalloc allocation */
+  u32 uTemp;          /* Transient storage for serial_type in OP_MakeRecord */
+  sqlite3 *db;        /* The associated database connection */
+  void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
 #ifdef SQLITE_DEBUG
   Mem *pScopyFrom;    /* This Mem is a shallow copy of pScopyFrom */
   void *pFiller;      /* So that sizeof(Mem) is a multiple of 8 */
 #endif
-  void (*xDel)(void *);  /* If not null, call this function to delete Mem.z */
-  char *zMalloc;      /* Dynamic buffer allocated by sqlite3_malloc() */
 };
 
 /* One or more of the following flags are set to indicate the validOK
@@ -14096,7 +14743,7 @@ struct Mem {
 #endif
 
 /*
-** Each auxilliary data pointer stored by a user defined function 
+** Each auxiliary data pointer stored by a user defined function 
 ** implementation calling sqlite3_set_auxdata() is stored in an instance
 ** of this structure. All such structures associated with a single VM
 ** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed
@@ -14111,7 +14758,7 @@ struct AuxData {
 };
 
 /*
-** The "context" argument for a installable function.  A pointer to an
+** The "context" argument for an installable function.  A pointer to an
 ** instance of this structure is the first argument to the routines used
 ** implement the SQL functions.
 **
@@ -14124,14 +14771,13 @@ struct AuxData {
 ** (Mem) which are only defined there.
 */
 struct sqlite3_context {
-  FuncDef *pFunc;       /* Pointer to function information.  MUST BE FIRST */
-  Mem s;                /* The return value is stored here */
+  Mem *pOut;            /* The return value is stored here */
+  FuncDef *pFunc;       /* Pointer to function information */
   Mem *pMem;            /* Memory cell used to store aggregate context */
-  CollSeq *pColl;       /* Collating sequence */
   Vdbe *pVdbe;          /* The VM that owns this context */
   int iOp;              /* Instruction number of OP_Function */
   int isError;          /* Error code returned by the function. */
-  u8 skipFlag;          /* Skip skip accumulator loading if true */
+  u8 skipFlag;          /* Skip accumulator loading if true */
   u8 fErrorOrAux;       /* isError!=0 or pVdbe->pAuxData modified */
 };
 
@@ -14152,20 +14798,22 @@ struct Explain {
 */
 typedef unsigned bft;  /* Bit Field Type */
 
+typedef struct ScanStatus ScanStatus;
+struct ScanStatus {
+  int addrExplain;                /* OP_Explain for loop */
+  int addrLoop;                   /* Address of "loops" counter */
+  int addrVisit;                  /* Address of "rows visited" counter */
+  int iSelectID;                  /* The "Select-ID" for this loop */
+  LogEst nEst;                    /* Estimated output rows per loop */
+  char *zName;                    /* Name of table or index */
+};
+
 /*
 ** An instance of the virtual machine.  This structure contains the complete
 ** state of the virtual machine.
 **
 ** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare()
 ** is really a pointer to an instance of this structure.
-**
-** The Vdbe.inVtabMethod variable is set to non-zero for the duration of
-** any virtual table method invocations made by the vdbe program. It is
-** set to 2 for xDestroy method calls and 1 for all other methods. This
-** variable is used for two purposes: to allow xDestroy methods to execute
-** "DROP TABLE" statements and to prevent some nasty side effects of
-** malloc failure when SQLite is invoked recursively by a virtual table 
-** method function.
 */
 struct Vdbe {
   sqlite3 *db;            /* The database connection that owns this statement */
@@ -14189,11 +14837,13 @@ struct Vdbe {
   u32 cacheCtr;           /* VdbeCursor row cache generation counter */
   int pc;                 /* The program counter */
   int rc;                 /* Value to return */
+#ifdef SQLITE_DEBUG
+  int rcApp;              /* errcode set by sqlite3_result_error_code() */
+#endif
   u16 nResColumn;         /* Number of columns in one row of the result set */
   u8 errorAction;         /* Recovery action to do in case of an error */
   u8 minWriteFileFormat;  /* Minimum file format for writable database files */
   bft explain:2;          /* True if EXPLAIN present on SQL command */
-  bft inVtabMethod:2;     /* See comments above */
   bft changeCntOn:1;      /* True to update the change-counter */
   bft expired:1;          /* True if the VM needs to be recompiled */
   bft runOnlyOnce:1;      /* Automatically expire on reset */
@@ -14216,10 +14866,6 @@ struct Vdbe {
   i64 nStmtDefImmCons;    /* Number of def. imm constraints when stmt started */
   char *zSql;             /* Text of the SQL statement that generated this */
   void *pFree;            /* Free this when deleting the vdbe */
-#ifdef SQLITE_ENABLE_TREE_EXPLAIN
-  Explain *pExplain;      /* The explainer */
-  char *zExplain;         /* Explanation of data structures */
-#endif
   VdbeFrame *pFrame;      /* Parent frame */
   VdbeFrame *pDelFrame;   /* List of frame objects to free on VM reset */
   int nFrame;             /* Number of frames in pFrame list */
@@ -14228,6 +14874,11 @@ struct Vdbe {
   int nOnceFlag;          /* Size of array aOnceFlag[] */
   u8 *aOnceFlag;          /* Flags for OP_Once */
   AuxData *pAuxData;      /* Linked list of auxdata allocations */
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+  i64 *anExec;            /* Number of times each op has been executed */
+  int nScan;              /* Entries in aScan[] */
+  ScanStatus *aScan;      /* Scan definitions for sqlite3_stmt_scanstatus() */
+#endif
 };
 
 /*
@@ -14244,6 +14895,7 @@ struct Vdbe {
 SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
 void sqliteVdbePopStack(Vdbe*,int);
 SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*);
+SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
 #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
 SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
 #endif
@@ -14254,8 +14906,8 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
 SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
 
 int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
-SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*);
-SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *);
+SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
+SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
 SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
 SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
 SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
@@ -14272,39 +14924,39 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem*, i64);
 #else
 SQLITE_PRIVATE   void sqlite3VdbeMemSetDouble(Mem*, double);
 #endif
+SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
 SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*);
 SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int);
 SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem*);
 SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
-SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, int);
+SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8);
 SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*);
 SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*);
 SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*);
 SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*);
 SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*);
 SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
+SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem*,u8,u8);
 SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*);
 SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
-SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p);
 #define VdbeMemDynamic(X)  \
   (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
-#define VdbeMemRelease(X)  \
-  if( VdbeMemDynamic(X) ) sqlite3VdbeMemReleaseExternal(X);
 SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
 SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
 SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
+SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
 SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
 SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*);
 SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *);
 SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p);
 
-SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *);
+SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, int, VdbeCursor *);
 SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *, VdbeSorter *);
 SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *);
 SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *);
 SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *);
-SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, const VdbeCursor *, int *);
-SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, const VdbeCursor *, Mem *);
+SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *, int *);
+SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *);
 SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
 
 #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
@@ -14351,10 +15003,32 @@ SQLITE_PRIVATE   int sqlite3VdbeMemExpandBlob(Mem *);
 */
 typedef struct sqlite3StatType sqlite3StatType;
 static SQLITE_WSD struct sqlite3StatType {
-  int nowValue[10];         /* Current value */
-  int mxValue[10];          /* Maximum value */
+#if SQLITE_PTRSIZE>4
+  sqlite3_int64 nowValue[10];         /* Current value */
+  sqlite3_int64 mxValue[10];          /* Maximum value */
+#else
+  u32 nowValue[10];                   /* Current value */
+  u32 mxValue[10];                    /* Maximum value */
+#endif
 } sqlite3Stat = { {0,}, {0,} };
 
+/*
+** Elements of sqlite3Stat[] are protected by either the memory allocator
+** mutex, or by the pcache1 mutex.  The following array determines which.
+*/
+static const char statMutex[] = {
+  0,  /* SQLITE_STATUS_MEMORY_USED */
+  1,  /* SQLITE_STATUS_PAGECACHE_USED */
+  1,  /* SQLITE_STATUS_PAGECACHE_OVERFLOW */
+  0,  /* SQLITE_STATUS_SCRATCH_USED */
+  0,  /* SQLITE_STATUS_SCRATCH_OVERFLOW */
+  0,  /* SQLITE_STATUS_MALLOC_SIZE */
+  0,  /* SQLITE_STATUS_PARSER_STACK */
+  1,  /* SQLITE_STATUS_PAGECACHE_SIZE */
+  0,  /* SQLITE_STATUS_SCRATCH_SIZE */
+  0,  /* SQLITE_STATUS_MALLOC_COUNT */
+};
+
 
 /* The "wsdStat" macro will resolve to the status information
 ** state vector.  If writable static data is unsupported on the target,
@@ -14371,33 +15045,60 @@ static SQLITE_WSD struct sqlite3StatType {
 #endif
 
 /*
-** Return the current value of a status parameter.
+** Return the current value of a status parameter.  The caller must
+** be holding the appropriate mutex.
 */
-SQLITE_PRIVATE int sqlite3StatusValue(int op){
+SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int op){
   wsdStatInit;
   assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
+  assert( op>=0 && op<ArraySize(statMutex) );
+  assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
+                                           : sqlite3MallocMutex()) );
   return wsdStat.nowValue[op];
 }
 
 /*
-** Add N to the value of a status record.  It is assumed that the
-** caller holds appropriate locks.
+** Add N to the value of a status record.  The caller must hold the
+** appropriate mutex.  (Locking is checked by assert()).
+**
+** The StatusUp() routine can accept positive or negative values for N.
+** The value of N is added to the current status value and the high-water
+** mark is adjusted if necessary.
+**
+** The StatusDown() routine lowers the current value by N.  The highwater
+** mark is unchanged.  N must be non-negative for StatusDown().
 */
-SQLITE_PRIVATE void sqlite3StatusAdd(int op, int N){
+SQLITE_PRIVATE void sqlite3StatusUp(int op, int N){
   wsdStatInit;
   assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
+  assert( op>=0 && op<ArraySize(statMutex) );
+  assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
+                                           : sqlite3MallocMutex()) );
   wsdStat.nowValue[op] += N;
   if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
     wsdStat.mxValue[op] = wsdStat.nowValue[op];
   }
 }
+SQLITE_PRIVATE void sqlite3StatusDown(int op, int N){
+  wsdStatInit;
+  assert( N>=0 );
+  assert( op>=0 && op<ArraySize(statMutex) );
+  assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
+                                           : sqlite3MallocMutex()) );
+  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
+  wsdStat.nowValue[op] -= N;
+}
 
 /*
-** Set the value of a status to X.
+** Set the value of a status to X.  The highwater mark is adjusted if
+** necessary.  The caller must hold the appropriate mutex.
 */
 SQLITE_PRIVATE void sqlite3StatusSet(int op, int X){
   wsdStatInit;
   assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
+  assert( op>=0 && op<ArraySize(statMutex) );
+  assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
+                                           : sqlite3MallocMutex()) );
   wsdStat.nowValue[op] = X;
   if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
     wsdStat.mxValue[op] = wsdStat.nowValue[op];
@@ -14406,28 +15107,50 @@ SQLITE_PRIVATE void sqlite3StatusSet(int op, int X){
 
 /*
 ** Query status information.
-**
-** This implementation assumes that reading or writing an aligned
-** 32-bit integer is an atomic operation.  If that assumption is not true,
-** then this routine is not threadsafe.
 */
-SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
+SQLITE_API int SQLITE_STDCALL sqlite3_status64(
+  int op,
+  sqlite3_int64 *pCurrent,
+  sqlite3_int64 *pHighwater,
+  int resetFlag
+){
+  sqlite3_mutex *pMutex;
   wsdStatInit;
   if( op<0 || op>=ArraySize(wsdStat.nowValue) ){
     return SQLITE_MISUSE_BKPT;
   }
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT;
+#endif
+  pMutex = statMutex[op] ? sqlite3Pcache1Mutex() : sqlite3MallocMutex();
+  sqlite3_mutex_enter(pMutex);
   *pCurrent = wsdStat.nowValue[op];
   *pHighwater = wsdStat.mxValue[op];
   if( resetFlag ){
     wsdStat.mxValue[op] = wsdStat.nowValue[op];
   }
+  sqlite3_mutex_leave(pMutex);
+  (void)pMutex;  /* Prevent warning when SQLITE_THREADSAFE=0 */
   return SQLITE_OK;
 }
+SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
+  sqlite3_int64 iCur, iHwtr;
+  int rc;
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT;
+#endif
+  rc = sqlite3_status64(op, &iCur, &iHwtr, resetFlag);
+  if( rc==0 ){
+    *pCurrent = (int)iCur;
+    *pHighwater = (int)iHwtr;
+  }
+  return rc;
+}
 
 /*
 ** Query status information for a single database connection
 */
-SQLITE_API int sqlite3_db_status(
+SQLITE_API int SQLITE_STDCALL sqlite3_db_status(
   sqlite3 *db,          /* The database connection whose status is desired */
   int op,               /* Status verb */
   int *pCurrent,        /* Write current value here */
@@ -14435,6 +15158,11 @@ SQLITE_API int sqlite3_db_status(
   int resetFlag         /* Reset high-water mark if true */
 ){
   int rc = SQLITE_OK;   /* Return code */
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwater==0 ){
+    return SQLITE_MISUSE_BKPT;
+  }
+#endif
   sqlite3_mutex_enter(db->mutex);
   switch( op ){
     case SQLITE_DBSTATUS_LOOKASIDE_USED: {
@@ -14543,7 +15271,7 @@ SQLITE_API int sqlite3_db_status(
       }
       db->pnBytesFreed = 0;
 
-      *pHighwater = 0;
+      *pHighwater = 0;  /* IMP: R-64479-57858 */
       *pCurrent = nByte;
 
       break;
@@ -14568,7 +15296,9 @@ SQLITE_API int sqlite3_db_status(
           sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet);
         }
       }
-      *pHighwater = 0;
+      *pHighwater = 0; /* IMP: R-42420-56072 */
+                       /* IMP: R-54100-20147 */
+                       /* IMP: R-29431-39229 */
       *pCurrent = nRet;
       break;
     }
@@ -14578,7 +15308,7 @@ SQLITE_API int sqlite3_db_status(
     ** have been satisfied.  The *pHighwater is always set to zero.
     */
     case SQLITE_DBSTATUS_DEFERRED_FKS: {
-      *pHighwater = 0;
+      *pHighwater = 0;  /* IMP: R-11967-56545 */
       *pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0;
       break;
     }
@@ -14611,7 +15341,7 @@ SQLITE_API int sqlite3_db_status(
 ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
 ** All other code has file scope.
 **
-** SQLite processes all times and dates as Julian Day numbers.  The
+** SQLite processes all times and dates as julian day numbers.  The
 ** dates and times are stored as the number of days since noon
 ** in Greenwich on November 24, 4714 B.C. according to the Gregorian
 ** calendar system. 
@@ -14619,14 +15349,14 @@ SQLITE_API int sqlite3_db_status(
 ** 1970-01-01 00:00:00 is JD 2440587.5
 ** 2000-01-01 00:00:00 is JD 2451544.5
 **
-** This implemention requires years to be expressed as a 4-digit number
+** This implementation requires years to be expressed as a 4-digit number
 ** which means that only dates between 0000-01-01 and 9999-12-31 can
 ** be represented, even though julian day numbers allow a much wider
 ** range of dates.
 **
 ** The Gregorian calendar system is used for all dates and times,
 ** even those that predate the Gregorian calendar.  Historians usually
-** use the Julian calendar for dates prior to 1582-10-15 and for some
+** use the julian calendar for dates prior to 1582-10-15 and for some
 ** dates afterwards, depending on locale.  Beware of this difference.
 **
 ** The conversion algorithms are implemented based on descriptions
@@ -14898,7 +15628,7 @@ static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
 }
 
 /*
-** Attempt to parse the given string into a Julian Day Number.  Return
+** Attempt to parse the given string into a julian day number.  Return
 ** the number of errors.
 **
 ** The following are acceptable forms for the input string:
@@ -15006,8 +15736,9 @@ static void clearYMD_HMS_TZ(DateTime *p){
 ** already, check for an MSVC build environment that provides 
 ** localtime_s().
 */
-#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \
-     defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE)
+#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S \
+    && defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE)
+#undef  HAVE_LOCALTIME_S
 #define HAVE_LOCALTIME_S 1
 #endif
 
@@ -15027,8 +15758,7 @@ static void clearYMD_HMS_TZ(DateTime *p){
 */
 static int osLocaltime(time_t *t, struct tm *pTm){
   int rc;
-#if (!defined(HAVE_LOCALTIME_R) || !HAVE_LOCALTIME_R) \
-      && (!defined(HAVE_LOCALTIME_S) || !HAVE_LOCALTIME_S)
+#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S
   struct tm *pX;
 #if SQLITE_THREADSAFE>0
   sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
@@ -15045,7 +15775,7 @@ static int osLocaltime(time_t *t, struct tm *pTm){
 #ifndef SQLITE_OMIT_BUILTIN_TEST
   if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
 #endif
-#if defined(HAVE_LOCALTIME_R) && HAVE_LOCALTIME_R
+#if HAVE_LOCALTIME_R
   rc = localtime_r(t, pTm)==0;
 #else
   rc = localtime_s(pTm, t);
@@ -15469,7 +16199,7 @@ static void dateFunc(
 **   %f  ** fractional seconds  SS.SSS
 **   %H  hour 00-24
 **   %j  day of year 000-366
-**   %J  ** Julian day number
+**   %J  ** julian day number
 **   %m  month 01-12
 **   %M  minute 00-59
 **   %s  seconds since 1970-01-01
@@ -15489,8 +16219,10 @@ static void strftimeFunc(
   size_t i,j;
   char *z;
   sqlite3 *db;
-  const char *zFmt = (const char*)sqlite3_value_text(argv[0]);
+  const char *zFmt;
   char zBuf[100];
+  if( argc==0 ) return;
+  zFmt = (const char*)sqlite3_value_text(argv[0]);
   if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return;
   db = sqlite3_context_db_handle(context);
   for(i=0, n=1; zFmt[i]; i++, n++){
@@ -15684,7 +16416,7 @@ static void currentTimeFunc(
   iT = sqlite3StmtCurrentTime(context);
   if( iT<=0 ) return;
   t = iT/1000 - 10000*(sqlite3_int64)21086676;
-#ifdef HAVE_GMTIME_R
+#if HAVE_GMTIME_R
   pTm = gmtime_r(&t, &sNow);
 #else
   sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
@@ -16042,7 +16774,7 @@ static sqlite3_vfs * SQLITE_WSD vfsList = 0;
 ** Locate a VFS by name.  If no name is given, simply return the
 ** first VFS on the list.
 */
-SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
+SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfs){
   sqlite3_vfs *pVfs = 0;
 #if SQLITE_THREADSAFE
   sqlite3_mutex *mutex;
@@ -16088,12 +16820,16 @@ static void vfsUnlink(sqlite3_vfs *pVfs){
 ** VFS multiple times.  The new VFS becomes the default if makeDflt is
 ** true.
 */
-SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
+SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
   MUTEX_LOGIC(sqlite3_mutex *mutex;)
 #ifndef SQLITE_OMIT_AUTOINIT
   int rc = sqlite3_initialize();
   if( rc ) return rc;
 #endif
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( pVfs==0 ) return SQLITE_MISUSE_BKPT;
+#endif
+
   MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
   sqlite3_mutex_enter(mutex);
   vfsUnlink(pVfs);
@@ -16112,7 +16848,7 @@ SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
 /*
 ** Unregister a VFS so that it is no longer accessible.
 */
-SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
+SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
 #if SQLITE_THREADSAFE
   sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
 #endif
@@ -16354,9 +17090,9 @@ static malloc_zone_t* _sqliteZone_;
 ** The malloc.h header file is needed for malloc_usable_size() function
 ** on some systems (e.g. Linux).
 */
-#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLOC_USABLE_SIZE)
-#  define SQLITE_USE_MALLOC_H
-#  define SQLITE_USE_MALLOC_USABLE_SIZE
+#if HAVE_MALLOC_H && HAVE_MALLOC_USABLE_SIZE
+#  define SQLITE_USE_MALLOC_H 1
+#  define SQLITE_USE_MALLOC_USABLE_SIZE 1
 /*
 ** The MSVCRT has malloc_usable_size(), but it is called _msize().  The
 ** use of _msize() is automatic, but can be disabled by compiling with
@@ -16463,7 +17199,7 @@ static int sqlite3MemSize(void *pPrior){
 **
 ** For this low-level interface, we know that pPrior!=0.  Cases where
 ** pPrior==0 while have been intercepted by higher-level routine and
-** redirected to xMalloc.  Similarly, we know that nByte>0 becauses
+** redirected to xMalloc.  Similarly, we know that nByte>0 because
 ** cases where nByte<=0 will have been intercepted by higher-level
 ** routines and redirected to xFree.
 */
@@ -16966,7 +17702,7 @@ SQLITE_PRIVATE void sqlite3MemdebugSetType(void *p, u8 eType){
 ** This routine is designed for use within an assert() statement, to
 ** verify the type of an allocation.  For example:
 **
-**     assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
+**     assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
 */
 SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){
   int rc = 1;
@@ -16988,7 +17724,7 @@ SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){
 ** This routine is designed for use within an assert() statement, to
 ** verify the type of an allocation.  For example:
 **
-**     assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
+**     assert( sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
 */
 SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){
   int rc = 1;
@@ -17820,7 +18556,7 @@ SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void){
 **   1.  All memory allocations sizes are rounded up to a power of 2.
 **
 **   2.  If two adjacent free blocks are the halves of a larger block,
-**       then the two blocks are coalesed into the single larger block.
+**       then the two blocks are coalesced into the single larger block.
 **
 **   3.  New memory is allocated from the first available free block.
 **
@@ -18448,9 +19184,10 @@ SQLITE_PRIVATE int sqlite3MutexEnd(void){
 /*
 ** Retrieve a pointer to a static mutex or allocate a new dynamic one.
 */
-SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){
+SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int id){
 #ifndef SQLITE_OMIT_AUTOINIT
   if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0;
+  if( id>SQLITE_MUTEX_RECURSIVE && sqlite3MutexInit() ) return 0;
 #endif
   return sqlite3GlobalConfig.mutex.xMutexAlloc(id);
 }
@@ -18466,7 +19203,7 @@ SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){
 /*
 ** Free a dynamic mutex.
 */
-SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){
+SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex *p){
   if( p ){
     sqlite3GlobalConfig.mutex.xMutexFree(p);
   }
@@ -18476,7 +19213,7 @@ SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){
 ** Obtain the mutex p. If some other thread already has the mutex, block
 ** until it can be obtained.
 */
-SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){
+SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex *p){
   if( p ){
     sqlite3GlobalConfig.mutex.xMutexEnter(p);
   }
@@ -18486,7 +19223,7 @@ SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){
 ** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another
 ** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY.
 */
-SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){
+SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex *p){
   int rc = SQLITE_OK;
   if( p ){
     return sqlite3GlobalConfig.mutex.xMutexTry(p);
@@ -18500,7 +19237,7 @@ SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){
 ** is not currently entered. If a NULL pointer is passed as an argument
 ** this function is a no-op.
 */
-SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){
+SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex *p){
   if( p ){
     sqlite3GlobalConfig.mutex.xMutexLeave(p);
   }
@@ -18511,10 +19248,10 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){
 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
 ** intended for use inside assert() statements.
 */
-SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){
+SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex *p){
   return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p);
 }
-SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
+SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex *p){
   return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p);
 }
 #endif
@@ -18644,8 +19381,12 @@ static sqlite3_mutex *debugMutexAlloc(int id){
       break;
     }
     default: {
-      assert( id-2 >= 0 );
-      assert( id-2 < (int)(sizeof(aStatic)/sizeof(aStatic[0])) );
+#ifdef SQLITE_ENABLE_API_ARMOR
+      if( id-2<0 || id-2>=ArraySize(aStatic) ){
+        (void)SQLITE_MISUSE_BKPT;
+        return 0;
+      }
+#endif
       pNew = &aStatic[id-2];
       pNew->id = id;
       break;
@@ -18660,8 +19401,13 @@ static sqlite3_mutex *debugMutexAlloc(int id){
 static void debugMutexFree(sqlite3_mutex *pX){
   sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX;
   assert( p->cnt==0 );
-  assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
-  sqlite3_free(p);
+  if( p->id==SQLITE_MUTEX_RECURSIVE || p->id==SQLITE_MUTEX_FAST ){
+    sqlite3_free(p);
+  }else{
+#ifdef SQLITE_ENABLE_API_ARMOR
+    (void)SQLITE_MISUSE_BKPT;
+#endif
+  }
 }
 
 /*
@@ -18772,8 +19518,10 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
 */
 struct sqlite3_mutex {
   pthread_mutex_t mutex;     /* Mutex controlling the lock */
-#if SQLITE_MUTEX_NREF
+#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
   int id;                    /* Mutex type */
+#endif
+#if SQLITE_MUTEX_NREF
   volatile int nRef;         /* Number of entrances */
   volatile pthread_t owner;  /* Thread that is within this mutex */
   int trace;                 /* True to trace changes */
@@ -18890,32 +19638,30 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
         pthread_mutex_init(&p->mutex, &recursiveAttr);
         pthread_mutexattr_destroy(&recursiveAttr);
 #endif
-#if SQLITE_MUTEX_NREF
-        p->id = iType;
-#endif
       }
       break;
     }
     case SQLITE_MUTEX_FAST: {
       p = sqlite3MallocZero( sizeof(*p) );
       if( p ){
-#if SQLITE_MUTEX_NREF
-        p->id = iType;
-#endif
         pthread_mutex_init(&p->mutex, 0);
       }
       break;
     }
     default: {
-      assert( iType-2 >= 0 );
-      assert( iType-2 < ArraySize(staticMutexes) );
-      p = &staticMutexes[iType-2];
-#if SQLITE_MUTEX_NREF
-      p->id = iType;
+#ifdef SQLITE_ENABLE_API_ARMOR
+      if( iType-2<0 || iType-2>=ArraySize(staticMutexes) ){
+        (void)SQLITE_MISUSE_BKPT;
+        return 0;
+      }
 #endif
+      p = &staticMutexes[iType-2];
       break;
     }
   }
+#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
+  if( p ) p->id = iType;
+#endif
   return p;
 }
 
@@ -18927,9 +19673,18 @@ static sqlite3_mutex *pthreadMutexAlloc(int iType){
 */
 static void pthreadMutexFree(sqlite3_mutex *p){
   assert( p->nRef==0 );
-  assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
-  pthread_mutex_destroy(&p->mutex);
-  sqlite3_free(p);
+#if SQLITE_ENABLE_API_ARMOR
+  if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE )
+#endif
+  {
+    pthread_mutex_destroy(&p->mutex);
+    sqlite3_free(p);
+  }
+#ifdef SQLITE_ENABLE_API_ARMOR
+  else{
+    (void)SQLITE_MISUSE_BKPT;
+  }
+#endif
 }
 
 /*
@@ -19141,16 +19896,6 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
 # error "The MEMORY_DEBUG macro is obsolete.  Use SQLITE_DEBUG instead."
 #endif
 
-#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
-# ifndef SQLITE_DEBUG_OS_TRACE
-#   define SQLITE_DEBUG_OS_TRACE 0
-# endif
-  int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE;
-# define OSTRACE(X)          if( sqlite3OSTrace ) sqlite3DebugPrintf X
-#else
-# define OSTRACE(X)
-#endif
-
 /*
 ** Macros for performance tracing.  Normally turned off.  Only works
 ** on i486 hardware.
@@ -19389,6 +20134,27 @@ SQLITE_API int sqlite3_open_file_count = 0;
 # define SQLITE_OS_WINRT 0
 #endif
 
+/*
+** For WinCE, some API function parameters do not appear to be declared as
+** volatile.
+*/
+#if SQLITE_OS_WINCE
+# define SQLITE_WIN32_VOLATILE
+#else
+# define SQLITE_WIN32_VOLATILE volatile
+#endif
+
+/*
+** For some Windows sub-platforms, the _beginthreadex() / _endthreadex()
+** functions are not available (e.g. those not using MSVC, Cygwin, etc).
+*/
+#if SQLITE_OS_WIN && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \
+    SQLITE_THREADSAFE>0 && !defined(__CYGWIN__)
+# define SQLITE_OS_WIN_THREADS 1
+#else
+# define SQLITE_OS_WIN_THREADS 0
+#endif
+
 #endif /* _OS_WIN_H_ */
 
 /************** End of os_win.h **********************************************/
@@ -19469,10 +20235,10 @@ static int winMutex_isNt = -1; /* <0 means "need to query" */
 ** of the sqlite3_initialize() and sqlite3_shutdown() processing, the
 ** "interlocked" magic used here is probably not strictly necessary.
 */
-static LONG volatile winMutex_lock = 0;
+static LONG SQLITE_WIN32_VOLATILE winMutex_lock = 0;
 
-SQLITE_API int sqlite3_win32_is_nt(void); /* os_win.c */
-SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
+SQLITE_API int SQLITE_STDCALL sqlite3_win32_is_nt(void); /* os_win.c */
+SQLITE_API void SQLITE_STDCALL sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */
 
 static int winMutexInit(void){
   /* The first to increment to 1 does actual initialization */
@@ -19564,8 +20330,8 @@ static sqlite3_mutex *winMutexAlloc(int iType){
     case SQLITE_MUTEX_RECURSIVE: {
       p = sqlite3MallocZero( sizeof(*p) );
       if( p ){
-#ifdef SQLITE_DEBUG
         p->id = iType;
+#ifdef SQLITE_DEBUG
 #ifdef SQLITE_WIN32_MUTEX_TRACE_DYNAMIC
         p->trace = 1;
 #endif
@@ -19579,12 +20345,15 @@ static sqlite3_mutex *winMutexAlloc(int iType){
       break;
     }
     default: {
-      assert( iType-2 >= 0 );
-      assert( iType-2 < ArraySize(winMutex_staticMutexes) );
-      assert( winMutex_isInit==1 );
+#ifdef SQLITE_ENABLE_API_ARMOR
+      if( iType-2<0 || iType-2>=ArraySize(winMutex_staticMutexes) ){
+        (void)SQLITE_MISUSE_BKPT;
+        return 0;
+      }
+#endif
       p = &winMutex_staticMutexes[iType-2];
-#ifdef SQLITE_DEBUG
       p->id = iType;
+#ifdef SQLITE_DEBUG
 #ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC
       p->trace = 1;
 #endif
@@ -19603,13 +20372,15 @@ static sqlite3_mutex *winMutexAlloc(int iType){
 */
 static void winMutexFree(sqlite3_mutex *p){
   assert( p );
-#ifdef SQLITE_DEBUG
   assert( p->nRef==0 && p->owner==0 );
-  assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
+  if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ){
+    DeleteCriticalSection(&p->mutex);
+    sqlite3_free(p);
+  }else{
+#ifdef SQLITE_ENABLE_API_ARMOR
+    (void)SQLITE_MISUSE_BKPT;
 #endif
-  assert( winMutex_isInit==1 );
-  DeleteCriticalSection(&p->mutex);
-  sqlite3_free(p);
+  }
 }
 
 /*
@@ -19763,7 +20534,7 @@ SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){
 ** held by SQLite. An example of non-essential memory is memory used to
 ** cache database pages that are not currently in use.
 */
-SQLITE_API int sqlite3_release_memory(int n){
+SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int n){
 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
   return sqlite3PcacheReleaseMemory(n);
 #else
@@ -19819,6 +20590,13 @@ static SQLITE_WSD struct Mem0Global {
 #define mem0 GLOBAL(struct Mem0Global, mem0)
 
 /*
+** Return the memory allocator mutex. sqlite3_status() needs it.
+*/
+SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void){
+  return mem0.mutex;
+}
+
+/*
 ** This routine runs when the memory allocator sees that the
 ** total memory allocation is about to exceed the soft heap
 ** limit.
@@ -19840,7 +20618,7 @@ static int sqlite3MemoryAlarm(
   void *pArg,
   sqlite3_int64 iThreshold
 ){
-  int nUsed;
+  sqlite3_int64 nUsed;
   sqlite3_mutex_enter(mem0.mutex);
   mem0.alarmCallback = xCallback;
   mem0.alarmArg = pArg;
@@ -19856,7 +20634,7 @@ static int sqlite3MemoryAlarm(
 ** Deprecated external interface.  Internal/core SQLite code
 ** should call sqlite3MemoryAlarm.
 */
-SQLITE_API int sqlite3_memory_alarm(
+SQLITE_API int SQLITE_STDCALL sqlite3_memory_alarm(
   void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
   void *pArg,
   sqlite3_int64 iThreshold
@@ -19869,7 +20647,7 @@ SQLITE_API int sqlite3_memory_alarm(
 ** Set the soft heap-size limit for the library. Passing a zero or 
 ** negative value indicates no limit.
 */
-SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 n){
   sqlite3_int64 priorLimit;
   sqlite3_int64 excess;
 #ifndef SQLITE_OMIT_AUTOINIT
@@ -19889,7 +20667,7 @@ SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){
   if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff));
   return priorLimit;
 }
-SQLITE_API void sqlite3_soft_heap_limit(int n){
+SQLITE_API void SQLITE_STDCALL sqlite3_soft_heap_limit(int n){
   if( n<0 ) n = 0;
   sqlite3_soft_heap_limit64(n);
 }
@@ -19898,6 +20676,7 @@ SQLITE_API void sqlite3_soft_heap_limit(int n){
 ** Initialize the memory allocation subsystem.
 */
 SQLITE_PRIVATE int sqlite3MallocInit(void){
+  int rc;
   if( sqlite3GlobalConfig.m.xMalloc==0 ){
     sqlite3MemSetDefault();
   }
@@ -19933,7 +20712,9 @@ SQLITE_PRIVATE int sqlite3MallocInit(void){
     sqlite3GlobalConfig.szPage = 0;
     sqlite3GlobalConfig.nPage = 0;
   }
-  return sqlite3GlobalConfig.m.xInit(sqlite3GlobalConfig.m.pAppData);
+  rc = sqlite3GlobalConfig.m.xInit(sqlite3GlobalConfig.m.pAppData);
+  if( rc!=SQLITE_OK ) memset(&mem0, 0, sizeof(mem0));
+  return rc;
 }
 
 /*
@@ -19958,7 +20739,7 @@ SQLITE_PRIVATE void sqlite3MallocEnd(void){
 /*
 ** Return the amount of memory currently checked out.
 */
-SQLITE_API sqlite3_int64 sqlite3_memory_used(void){
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void){
   int n, mx;
   sqlite3_int64 res;
   sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, 0);
@@ -19971,7 +20752,7 @@ SQLITE_API sqlite3_int64 sqlite3_memory_used(void){
 ** checked out since either the beginning of this process
 ** or since the most recent reset.
 */
-SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag){
   int n, mx;
   sqlite3_int64 res;
   sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, resetFlag);
@@ -20009,7 +20790,7 @@ static int mallocWithAlarm(int n, void **pp){
   nFull = sqlite3GlobalConfig.m.xRoundup(n);
   sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n);
   if( mem0.alarmCallback!=0 ){
-    int nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
+    sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
     if( nUsed >= mem0.alarmThreshold - nFull ){
       mem0.nearlyFull = 1;
       sqlite3MallocAlarm(nFull);
@@ -20026,8 +20807,8 @@ static int mallocWithAlarm(int n, void **pp){
 #endif
   if( p ){
     nFull = sqlite3MallocSize(p);
-    sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nFull);
-    sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, 1);
+    sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nFull);
+    sqlite3StatusUp(SQLITE_STATUS_MALLOC_COUNT, 1);
   }
   *pp = p;
   return nFull;
@@ -20037,11 +20818,9 @@ static int mallocWithAlarm(int n, void **pp){
 ** Allocate memory.  This routine is like sqlite3_malloc() except that it
 ** assumes the memory subsystem has already been initialized.
 */
-SQLITE_PRIVATE void *sqlite3Malloc(int n){
+SQLITE_PRIVATE void *sqlite3Malloc(u64 n){
   void *p;
-  if( n<=0               /* IMP: R-65312-04917 */ 
-   || n>=0x7fffff00
-  ){
+  if( n==0 || n>=0x7fffff00 ){
     /* A memory allocation of a number of bytes which is near the maximum
     ** signed integer value might cause an integer overflow inside of the
     ** xMalloc().  Hence we limit the maximum size to 0x7fffff00, giving
@@ -20050,12 +20829,12 @@ SQLITE_PRIVATE void *sqlite3Malloc(int n){
     p = 0;
   }else if( sqlite3GlobalConfig.bMemstat ){
     sqlite3_mutex_enter(mem0.mutex);
-    mallocWithAlarm(n, &p);
+    mallocWithAlarm((int)n, &p);
     sqlite3_mutex_leave(mem0.mutex);
   }else{
-    p = sqlite3GlobalConfig.m.xMalloc(n);
+    p = sqlite3GlobalConfig.m.xMalloc((int)n);
   }
-  assert( EIGHT_BYTE_ALIGNMENT(p) );  /* IMP: R-04675-44850 */
+  assert( EIGHT_BYTE_ALIGNMENT(p) );  /* IMP: R-11148-40995 */
   return p;
 }
 
@@ -20064,7 +20843,13 @@ SQLITE_PRIVATE void *sqlite3Malloc(int n){
 ** First make sure the memory subsystem is initialized, then do the
 ** allocation.
 */
-SQLITE_API void *sqlite3_malloc(int n){
+SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int n){
+#ifndef SQLITE_OMIT_AUTOINIT
+  if( sqlite3_initialize() ) return 0;
+#endif
+  return n<=0 ? 0 : sqlite3Malloc(n);
+}
+SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64 n){
 #ifndef SQLITE_OMIT_AUTOINIT
   if( sqlite3_initialize() ) return 0;
 #endif
@@ -20095,22 +20880,20 @@ SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){
   assert( n>0 );
 
   sqlite3_mutex_enter(mem0.mutex);
+  sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n);
   if( mem0.nScratchFree && sqlite3GlobalConfig.szScratch>=n ){
     p = mem0.pScratchFree;
     mem0.pScratchFree = mem0.pScratchFree->pNext;
     mem0.nScratchFree--;
-    sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, 1);
-    sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n);
+    sqlite3StatusUp(SQLITE_STATUS_SCRATCH_USED, 1);
     sqlite3_mutex_leave(mem0.mutex);
   }else{
-    if( sqlite3GlobalConfig.bMemstat ){
-      sqlite3StatusSet(SQLITE_STATUS_SCRATCH_SIZE, n);
-      n = mallocWithAlarm(n, &p);
-      if( p ) sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, n);
-      sqlite3_mutex_leave(mem0.mutex);
-    }else{
+    sqlite3_mutex_leave(mem0.mutex);
+    p = sqlite3Malloc(n);
+    if( sqlite3GlobalConfig.bMemstat && p ){
+      sqlite3_mutex_enter(mem0.mutex);
+      sqlite3StatusUp(SQLITE_STATUS_SCRATCH_OVERFLOW, sqlite3MallocSize(p));
       sqlite3_mutex_leave(mem0.mutex);
-      p = sqlite3GlobalConfig.m.xMalloc(n);
     }
     sqlite3MemdebugSetType(p, MEMTYPE_SCRATCH);
   }
@@ -20118,11 +20901,12 @@ SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){
 
 
 #if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
-  /* Verify that no more than two scratch allocations per thread
-  ** are outstanding at one time.  (This is only checked in the
-  ** single-threaded case since checking in the multi-threaded case
-  ** would be much more complicated.) */
-  assert( scratchAllocOut<=1 );
+  /* EVIDENCE-OF: R-12970-05880 SQLite will not use more than one scratch
+  ** buffers per thread.
+  **
+  ** This can only be checked in single-threaded mode.
+  */
+  assert( scratchAllocOut==0 );
   if( p ) scratchAllocOut++;
 #endif
 
@@ -20149,19 +20933,19 @@ SQLITE_PRIVATE void sqlite3ScratchFree(void *p){
       mem0.pScratchFree = pSlot;
       mem0.nScratchFree++;
       assert( mem0.nScratchFree <= (u32)sqlite3GlobalConfig.nScratch );
-      sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, -1);
+      sqlite3StatusDown(SQLITE_STATUS_SCRATCH_USED, 1);
       sqlite3_mutex_leave(mem0.mutex);
     }else{
       /* Release memory back to the heap */
       assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) );
-      assert( sqlite3MemdebugNoType(p, ~MEMTYPE_SCRATCH) );
+      assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_SCRATCH) );
       sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
       if( sqlite3GlobalConfig.bMemstat ){
         int iSize = sqlite3MallocSize(p);
         sqlite3_mutex_enter(mem0.mutex);
-        sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, -iSize);
-        sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -iSize);
-        sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
+        sqlite3StatusDown(SQLITE_STATUS_SCRATCH_OVERFLOW, iSize);
+        sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, iSize);
+        sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1);
         sqlite3GlobalConfig.m.xFree(p);
         sqlite3_mutex_leave(mem0.mutex);
       }else{
@@ -20188,33 +20972,41 @@ static int isLookaside(sqlite3 *db, void *p){
 */
 SQLITE_PRIVATE int sqlite3MallocSize(void *p){
   assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
-  assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
   return sqlite3GlobalConfig.m.xSize(p);
 }
 SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){
-  assert( db!=0 );
-  assert( sqlite3_mutex_held(db->mutex) );
-  if( isLookaside(db, p) ){
-    return db->lookaside.sz;
+  if( db==0 ){
+    assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
+    assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
+    return sqlite3MallocSize(p);
   }else{
-    assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
-    assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
-    assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
-    return sqlite3GlobalConfig.m.xSize(p);
+    assert( sqlite3_mutex_held(db->mutex) );
+    if( isLookaside(db, p) ){
+      return db->lookaside.sz;
+    }else{
+      assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
+      assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
+      return sqlite3GlobalConfig.m.xSize(p);
+    }
   }
 }
+SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void *p){
+  assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
+  assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
+  return (sqlite3_uint64)sqlite3GlobalConfig.m.xSize(p);
+}
 
 /*
 ** Free memory previously obtained from sqlite3Malloc().
 */
-SQLITE_API void sqlite3_free(void *p){
+SQLITE_API void SQLITE_STDCALL sqlite3_free(void *p){
   if( p==0 ) return;  /* IMP: R-49053-54554 */
-  assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
   assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
+  assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
   if( sqlite3GlobalConfig.bMemstat ){
     sqlite3_mutex_enter(mem0.mutex);
-    sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p));
-    sqlite3StatusAdd(SQLITE_STATUS_MALLOC_COUNT, -1);
+    sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, sqlite3MallocSize(p));
+    sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1);
     sqlite3GlobalConfig.m.xFree(p);
     sqlite3_mutex_leave(mem0.mutex);
   }else{
@@ -20223,6 +21015,14 @@ SQLITE_API void sqlite3_free(void *p){
 }
 
 /*
+** Add the size of memory allocation "p" to the count in
+** *db->pnBytesFreed.
+*/
+static SQLITE_NOINLINE void measureAllocationSize(sqlite3 *db, void *p){
+  *db->pnBytesFreed += sqlite3DbMallocSize(db,p);
+}
+
+/*
 ** Free memory that might be associated with a particular database
 ** connection.
 */
@@ -20231,7 +21031,7 @@ SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
   if( p==0 ) return;
   if( db ){
     if( db->pnBytesFreed ){
-      *db->pnBytesFreed += sqlite3DbMallocSize(db, p);
+      measureAllocationSize(db, p);
       return;
     }
     if( isLookaside(db, p) ){
@@ -20246,8 +21046,8 @@ SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
       return;
     }
   }
-  assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
-  assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
+  assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
+  assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
   assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
   sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
   sqlite3_free(p);
@@ -20256,14 +21056,16 @@ SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){
 /*
 ** Change the size of an existing memory allocation
 */
-SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, int nBytes){
+SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){
   int nOld, nNew, nDiff;
   void *pNew;
+  assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) );
+  assert( sqlite3MemdebugNoType(pOld, (u8)~MEMTYPE_HEAP) );
   if( pOld==0 ){
-    return sqlite3Malloc(nBytes); /* IMP: R-28354-25769 */
+    return sqlite3Malloc(nBytes); /* IMP: R-04300-56712 */
   }
-  if( nBytes<=0 ){
-    sqlite3_free(pOld); /* IMP: R-31593-10574 */
+  if( nBytes==0 ){
+    sqlite3_free(pOld); /* IMP: R-26507-47431 */
     return 0;
   }
   if( nBytes>=0x7fffff00 ){
@@ -20274,33 +21076,31 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, int nBytes){
   /* IMPLEMENTATION-OF: R-46199-30249 SQLite guarantees that the second
   ** argument to xRealloc is always a value returned by a prior call to
   ** xRoundup. */
-  nNew = sqlite3GlobalConfig.m.xRoundup(nBytes);
+  nNew = sqlite3GlobalConfig.m.xRoundup((int)nBytes);
   if( nOld==nNew ){
     pNew = pOld;
   }else if( sqlite3GlobalConfig.bMemstat ){
     sqlite3_mutex_enter(mem0.mutex);
-    sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, nBytes);
+    sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes);
     nDiff = nNew - nOld;
     if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= 
           mem0.alarmThreshold-nDiff ){
       sqlite3MallocAlarm(nDiff);
     }
-    assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) );
-    assert( sqlite3MemdebugNoType(pOld, ~MEMTYPE_HEAP) );
     pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
     if( pNew==0 && mem0.alarmCallback ){
-      sqlite3MallocAlarm(nBytes);
+      sqlite3MallocAlarm((int)nBytes);
       pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
     }
     if( pNew ){
       nNew = sqlite3MallocSize(pNew);
-      sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
+      sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
     }
     sqlite3_mutex_leave(mem0.mutex);
   }else{
     pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew);
   }
-  assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-04675-44850 */
+  assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-11148-40995 */
   return pNew;
 }
 
@@ -20308,7 +21108,14 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, int nBytes){
 ** The public interface to sqlite3Realloc.  Make sure that the memory
 ** subsystem is initialized prior to invoking sqliteRealloc.
 */
-SQLITE_API void *sqlite3_realloc(void *pOld, int n){
+SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void *pOld, int n){
+#ifndef SQLITE_OMIT_AUTOINIT
+  if( sqlite3_initialize() ) return 0;
+#endif
+  if( n<0 ) n = 0;  /* IMP: R-26507-47431 */
+  return sqlite3Realloc(pOld, n);
+}
+SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void *pOld, sqlite3_uint64 n){
 #ifndef SQLITE_OMIT_AUTOINIT
   if( sqlite3_initialize() ) return 0;
 #endif
@@ -20319,10 +21126,10 @@ SQLITE_API void *sqlite3_realloc(void *pOld, int n){
 /*
 ** Allocate and zero memory.
 */ 
-SQLITE_PRIVATE void *sqlite3MallocZero(int n){
+SQLITE_PRIVATE void *sqlite3MallocZero(u64 n){
   void *p = sqlite3Malloc(n);
   if( p ){
-    memset(p, 0, n);
+    memset(p, 0, (size_t)n);
   }
   return p;
 }
@@ -20331,10 +21138,10 @@ SQLITE_PRIVATE void *sqlite3MallocZero(int n){
 ** Allocate and zero memory.  If the allocation fails, make
 ** the mallocFailed flag in the connection pointer.
 */
-SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3 *db, int n){
+SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3 *db, u64 n){
   void *p = sqlite3DbMallocRaw(db, n);
   if( p ){
-    memset(p, 0, n);
+    memset(p, 0, (size_t)n);
   }
   return p;
 }
@@ -20357,7 +21164,7 @@ SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3 *db, int n){
 ** In other words, if a subsequent malloc (ex: "b") worked, it is assumed
 ** that all prior mallocs (ex: "a") worked too.
 */
-SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, int n){
+SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, u64 n){
   void *p;
   assert( db==0 || sqlite3_mutex_held(db->mutex) );
   assert( db==0 || db->pnBytesFreed==0 );
@@ -20392,8 +21199,8 @@ SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, int n){
   if( !p && db ){
     db->mallocFailed = 1;
   }
-  sqlite3MemdebugSetType(p, MEMTYPE_DB |
-         ((db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
+  sqlite3MemdebugSetType(p, 
+         (db && db->lookaside.bEnabled) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP);
   return p;
 }
 
@@ -20401,7 +21208,7 @@ SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, int n){
 ** Resize the block of memory pointed to by p to n bytes. If the
 ** resize fails, set the mallocFailed flag in the connection object.
 */
-SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, int n){
+SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){
   void *pNew = 0;
   assert( db!=0 );
   assert( sqlite3_mutex_held(db->mutex) );
@@ -20419,15 +21226,14 @@ SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, int n){
         sqlite3DbFree(db, p);
       }
     }else{
-      assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
-      assert( sqlite3MemdebugHasType(p, MEMTYPE_LOOKASIDE|MEMTYPE_HEAP) );
+      assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
+      assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) );
       sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
-      pNew = sqlite3_realloc(p, n);
+      pNew = sqlite3_realloc64(p, n);
       if( !pNew ){
-        sqlite3MemdebugSetType(p, MEMTYPE_DB|MEMTYPE_HEAP);
         db->mallocFailed = 1;
       }
-      sqlite3MemdebugSetType(pNew, MEMTYPE_DB | 
+      sqlite3MemdebugSetType(pNew,
             (db->lookaside.bEnabled ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP));
     }
   }
@@ -20438,7 +21244,7 @@ SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, int n){
 ** Attempt to reallocate p.  If the reallocation fails, then free p
 ** and set the mallocFailed flag in the database connection.
 */
-SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *db, void *p, int n){
+SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *db, void *p, u64 n){
   void *pNew;
   pNew = sqlite3DbRealloc(db, p, n);
   if( !pNew ){
@@ -20468,7 +21274,7 @@ SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3 *db, const char *z){
   }
   return zNew;
 }
-SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, int n){
+SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, u64 n){
   char *zNew;
   if( z==0 ){
     return 0;
@@ -20476,7 +21282,7 @@ SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, int n){
   assert( (n&0x7fffffff)==n );
   zNew = sqlite3DbMallocRaw(db, n+1);
   if( zNew ){
-    memcpy(zNew, z, n);
+    memcpy(zNew, z, (size_t)n);
     zNew[n] = 0;
   }
   return zNew;
@@ -20498,6 +21304,14 @@ SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zFormat
   *pz = z;
 }
 
+/*
+** Take actions at the end of an API call to indicate an OOM error
+*/
+static SQLITE_NOINLINE int apiOomError(sqlite3 *db){
+  db->mallocFailed = 0;
+  sqlite3Error(db, SQLITE_NOMEM);
+  return SQLITE_NOMEM;
+}
 
 /*
 ** This function must be called before exiting any API function (i.e. 
@@ -20518,12 +21332,11 @@ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){
   ** is unsafe, as is the call to sqlite3Error().
   */
   assert( !db || sqlite3_mutex_held(db->mutex) );
-  if( db && (db->mallocFailed || rc==SQLITE_IOERR_NOMEM) ){
-    sqlite3Error(db, SQLITE_NOMEM, 0);
-    db->mallocFailed = 0;
-    rc = SQLITE_NOMEM;
+  if( db==0 ) return rc & 0xff;
+  if( db->mallocFailed || rc==SQLITE_IOERR_NOMEM ){
+    return apiOomError(db);
   }
-  return rc & (db ? db->errMask : 0xff);
+  return rc & db->errMask;
 }
 
 /************** End of malloc.c **********************************************/
@@ -20667,6 +21480,7 @@ static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){
 ** Set the StrAccum object to an error mode.
 */
 static void setStrAccumError(StrAccum *p, u8 eError){
+  assert( eError==STRACCUM_NOMEM || eError==STRACCUM_TOOBIG );
   p->accError = eError;
   p->nAlloc = 0;
 }
@@ -20730,7 +21544,7 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
   const et_info *infop;      /* Pointer to the appropriate info structure */
   char *zOut;                /* Rendering buffer */
   int nOut;                  /* Size of the rendering buffer */
-  char *zExtra;              /* Malloced memory used by some conversion */
+  char *zExtra = 0;          /* Malloced memory used by some conversion */
 #ifndef SQLITE_OMIT_FLOATING_POINT
   int  exp, e2;              /* exponent of real numbers */
   int nsd;                   /* Number of significant digits returned */
@@ -20753,9 +21567,13 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
   for(; (c=(*fmt))!=0; ++fmt){
     if( c!='%' ){
       bufpt = (char *)fmt;
-      while( (c=(*++fmt))!='%' && c!=0 ){};
+#if HAVE_STRCHRNUL
+      fmt = strchrnul(fmt, '%');
+#else
+      do{ fmt++; }while( *fmt && *fmt != '%' );
+#endif
       sqlite3StrAccumAppend(pAccum, bufpt, (int)(fmt - bufpt));
-      if( c==0 ) break;
+      if( *fmt==0 ) break;
     }
     if( (c=(*++fmt))==0 ){
       sqlite3StrAccumAppend(pAccum, "%", 1);
@@ -20777,7 +21595,6 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
       }
     }while( !done && (c=(*++fmt))!=0 );
     /* Get the field width */
-    width = 0;
     if( c=='*' ){
       if( bArgList ){
         width = (int)getIntArg(pArgList);
@@ -20786,18 +21603,21 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
       }
       if( width<0 ){
         flag_leftjustify = 1;
-        width = -width;
+        width = width >= -2147483647 ? -width : 0;
       }
       c = *++fmt;
     }else{
+      unsigned wx = 0;
       while( c>='0' && c<='9' ){
-        width = width*10 + c - '0';
+        wx = wx*10 + c - '0';
         c = *++fmt;
       }
+      testcase( wx>0x7fffffff );
+      width = wx & 0x7fffffff;
     }
+
     /* Get the precision */
     if( c=='.' ){
-      precision = 0;
       c = *++fmt;
       if( c=='*' ){
         if( bArgList ){
@@ -20805,13 +21625,18 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
         }else{
           precision = va_arg(ap,int);
         }
-        if( precision<0 ) precision = -precision;
         c = *++fmt;
+        if( precision<0 ){
+          precision = precision >= -2147483647 ? -precision : -1;
+        }
       }else{
+        unsigned px = 0;
         while( c>='0' && c<='9' ){
-          precision = precision*10 + c - '0';
+          px = px*10 + c - '0';
           c = *++fmt;
         }
+        testcase( px>0x7fffffff );
+        precision = px & 0x7fffffff;
       }
     }else{
       precision = -1;
@@ -20843,7 +21668,6 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
         break;
       }
     }
-    zExtra = 0;
 
     /*
     ** At this point, variables are initialized as follows:
@@ -20976,7 +21800,8 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
           else                         prefix = 0;
         }
         if( xtype==etGENERIC && precision>0 ) precision--;
-        for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){}
+        testcase( precision>0xfff );
+        for(idx=precision&0xfff, rounder=0.5; idx>0; idx--, rounder*=0.1){}
         if( xtype==etFLOAT ) realvalue += rounder;
         /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */
         exp = 0;
@@ -21031,8 +21856,9 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
         }else{
           e2 = exp;
         }
-        if( MAX(e2,0)+precision+width > etBUFSIZE - 15 ){
-          bufpt = zExtra = sqlite3Malloc( MAX(e2,0)+precision+width+15 );
+        if( MAX(e2,0)+(i64)precision+(i64)width > etBUFSIZE - 15 ){
+          bufpt = zExtra 
+              = sqlite3Malloc( MAX(e2,0)+(i64)precision+(i64)width+15 );
           if( bufpt==0 ){
             setStrAccumError(pAccum, STRACCUM_NOMEM);
             return;
@@ -21134,13 +21960,16 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
         }else{
           c = va_arg(ap,int);
         }
-        buf[0] = (char)c;
-        if( precision>=0 ){
-          for(idx=1; idx<precision; idx++) buf[idx] = (char)c;
-          length = precision;
-        }else{
-          length =1;
+        if( precision>1 ){
+          width -= precision-1;
+          if( width>1 && !flag_leftjustify ){
+            sqlite3AppendChar(pAccum, width-1, ' ');
+            width = 0;
+          }
+          sqlite3AppendChar(pAccum, precision-1, c);
         }
+        length = 1;
+        buf[0] = c;
         bufpt = buf;
         break;
       case etSTRING:
@@ -21241,11 +22070,14 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
     ** the output.
     */
     width -= length;
-    if( width>0 && !flag_leftjustify ) sqlite3AppendSpace(pAccum, width);
+    if( width>0 && !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
     sqlite3StrAccumAppend(pAccum, bufpt, length);
-    if( width>0 && flag_leftjustify ) sqlite3AppendSpace(pAccum, width);
+    if( width>0 && flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
 
-    if( zExtra ) sqlite3_free(zExtra);
+    if( zExtra ){
+      sqlite3_free(zExtra);
+      zExtra = 0;
+    }
   }/* End for loop over the format string */
 } /* End of function */
 
@@ -21258,13 +22090,13 @@ SQLITE_PRIVATE void sqlite3VXPrintf(
 */
 static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
   char *zNew;
-  assert( p->nChar+N >= p->nAlloc ); /* Only called if really needed */
+  assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */
   if( p->accError ){
     testcase(p->accError==STRACCUM_TOOBIG);
     testcase(p->accError==STRACCUM_NOMEM);
     return 0;
   }
-  if( !p->useMalloc ){
+  if( p->mxAlloc==0 ){
     N = p->nAlloc - p->nChar - 1;
     setStrAccumError(p, STRACCUM_TOOBIG);
     return N;
@@ -21272,6 +22104,11 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
     char *zOld = (p->zText==p->zBase ? 0 : p->zText);
     i64 szNew = p->nChar;
     szNew += N + 1;
+    if( szNew+p->nChar<=p->mxAlloc ){
+      /* Force exponential buffer size growth as long as it does not overflow,
+      ** to avoid having to call this routine too often */
+      szNew += p->nChar;
+    }
     if( szNew > p->mxAlloc ){
       sqlite3StrAccumReset(p);
       setStrAccumError(p, STRACCUM_TOOBIG);
@@ -21279,15 +22116,16 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
     }else{
       p->nAlloc = (int)szNew;
     }
-    if( p->useMalloc==1 ){
+    if( p->db ){
       zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
     }else{
-      zNew = sqlite3_realloc(zOld, p->nAlloc);
+      zNew = sqlite3_realloc64(zOld, p->nAlloc);
     }
     if( zNew ){
       assert( p->zText!=0 || p->nChar==0 );
       if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
       p->zText = zNew;
+      p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
     }else{
       sqlite3StrAccumReset(p);
       setStrAccumError(p, STRACCUM_NOMEM);
@@ -21298,11 +22136,14 @@ static int sqlite3StrAccumEnlarge(StrAccum *p, int N){
 }
 
 /*
-** Append N space characters to the given string buffer.
+** Append N copies of character c to the given string buffer.
 */
-SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum *p, int N){
-  if( p->nChar+N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ) return;
-  while( (N--)>0 ) p->zText[p->nChar++] = ' ';
+SQLITE_PRIVATE void sqlite3AppendChar(StrAccum *p, int N, char c){
+  testcase( p->nChar + (i64)N > 0x7fffffff );
+  if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){
+    return;
+  }
+  while( (N--)>0 ) p->zText[p->nChar++] = c;
 }
 
 /*
@@ -21313,7 +22154,7 @@ SQLITE_PRIVATE void sqlite3AppendSpace(StrAccum *p, int N){
 ** work (enlarging the buffer) using tail recursion, so that the
 ** sqlite3StrAccumAppend() routine can use fast calling semantics.
 */
-static void enlargeAndAppend(StrAccum *p, const char *z, int N){
+static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){
   N = sqlite3StrAccumEnlarge(p, N);
   if( N>0 ){
     memcpy(&p->zText[p->nChar], z, N);
@@ -21326,17 +22167,17 @@ static void enlargeAndAppend(StrAccum *p, const char *z, int N){
 ** size of the memory allocation for StrAccum if necessary.
 */
 SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
-  assert( z!=0 );
+  assert( z!=0 || N==0 );
   assert( p->zText!=0 || p->nChar==0 || p->accError );
   assert( N>=0 );
   assert( p->accError==0 || p->nAlloc==0 );
   if( p->nChar+N >= p->nAlloc ){
     enlargeAndAppend(p,z,N);
-    return;
+  }else{
+    assert( p->zText );
+    p->nChar += N;
+    memcpy(&p->zText[p->nChar-N], z, N);
   }
-  assert( p->zText );
-  memcpy(&p->zText[p->nChar], z, N);
-  p->nChar += N;
 }
 
 /*
@@ -21355,12 +22196,8 @@ SQLITE_PRIVATE void sqlite3StrAccumAppendAll(StrAccum *p, const char *z){
 SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){
   if( p->zText ){
     p->zText[p->nChar] = 0;
-    if( p->useMalloc && p->zText==p->zBase ){
-      if( p->useMalloc==1 ){
-        p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
-      }else{
-        p->zText = sqlite3_malloc(p->nChar+1);
-      }
+    if( p->mxAlloc>0 && p->zText==p->zBase ){
+      p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
       if( p->zText ){
         memcpy(p->zText, p->zBase, p->nChar+1);
       }else{
@@ -21376,25 +22213,31 @@ SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){
 */
 SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){
   if( p->zText!=p->zBase ){
-    if( p->useMalloc==1 ){
-      sqlite3DbFree(p->db, p->zText);
-    }else{
-      sqlite3_free(p->zText);
-    }
+    sqlite3DbFree(p->db, p->zText);
   }
   p->zText = 0;
 }
 
 /*
-** Initialize a string accumulator
+** Initialize a string accumulator.
+**
+** p:     The accumulator to be initialized.
+** db:    Pointer to a database connection.  May be NULL.  Lookaside
+**        memory is used if not NULL. db->mallocFailed is set appropriately
+**        when not NULL.
+** zBase: An initial buffer.  May be NULL in which case the initial buffer
+**        is malloced.
+** n:     Size of zBase in bytes.  If total space requirements never exceed
+**        n then no memory allocations ever occur.
+** mx:    Maximum number of bytes to accumulate.  If mx==0 then no memory
+**        allocations will ever occur.
 */
-SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){
+SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){
   p->zText = p->zBase = zBase;
-  p->db = 0;
+  p->db = db;
   p->nChar = 0;
   p->nAlloc = n;
   p->mxAlloc = mx;
-  p->useMalloc = 1;
   p->accError = 0;
 }
 
@@ -21407,9 +22250,8 @@ SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list a
   char zBase[SQLITE_PRINT_BUF_SIZE];
   StrAccum acc;
   assert( db!=0 );
-  sqlite3StrAccumInit(&acc, zBase, sizeof(zBase),
+  sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase),
                       db->aLimit[SQLITE_LIMIT_LENGTH]);
-  acc.db = db;
   sqlite3VXPrintf(&acc, SQLITE_PRINTF_INTERNAL, zFormat, ap);
   z = sqlite3StrAccumFinish(&acc);
   if( acc.accError==STRACCUM_NOMEM ){
@@ -21433,7 +22275,7 @@ SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3 *db, const char *zFormat, ...){
 
 /*
 ** Like sqlite3MPrintf(), but call sqlite3DbFree() on zStr after formatting
-** the string and before returnning.  This routine is intended to be used
+** the string and before returning.  This routine is intended to be used
 ** to modify an existing string.  For example:
 **
 **       x = sqlite3MPrintf(db, x, "prefix %s suffix", x);
@@ -21453,15 +22295,21 @@ SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3 *db, char *zStr, const char *zForma
 ** Print into memory obtained from sqlite3_malloc().  Omit the internal
 ** %-conversion extensions.
 */
-SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){
+SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char *zFormat, va_list ap){
   char *z;
   char zBase[SQLITE_PRINT_BUF_SIZE];
   StrAccum acc;
+
+#ifdef SQLITE_ENABLE_API_ARMOR  
+  if( zFormat==0 ){
+    (void)SQLITE_MISUSE_BKPT;
+    return 0;
+  }
+#endif
 #ifndef SQLITE_OMIT_AUTOINIT
   if( sqlite3_initialize() ) return 0;
 #endif
-  sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
-  acc.useMalloc = 2;
+  sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
   sqlite3VXPrintf(&acc, 0, zFormat, ap);
   z = sqlite3StrAccumFinish(&acc);
   return z;
@@ -21471,7 +22319,7 @@ SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){
 ** Print into memory obtained from sqlite3_malloc()().  Omit the internal
 ** %-conversion extensions.
 */
-SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){
+SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char *zFormat, ...){
   va_list ap;
   char *z;
 #ifndef SQLITE_OMIT_AUTOINIT
@@ -21496,15 +22344,21 @@ SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){
 **
 ** sqlite3_vsnprintf() is the varargs version.
 */
-SQLITE_API char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
+SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){
   StrAccum acc;
   if( n<=0 ) return zBuf;
-  sqlite3StrAccumInit(&acc, zBuf, n, 0);
-  acc.useMalloc = 0;
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( zBuf==0 || zFormat==0 ) {
+    (void)SQLITE_MISUSE_BKPT;
+    if( zBuf ) zBuf[0] = 0;
+    return zBuf;
+  }
+#endif
+  sqlite3StrAccumInit(&acc, 0, zBuf, n, 0);
   sqlite3VXPrintf(&acc, 0, zFormat, ap);
   return sqlite3StrAccumFinish(&acc);
 }
-SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
+SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
   char *z;
   va_list ap;
   va_start(ap,zFormat);
@@ -21526,8 +22380,7 @@ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
   StrAccum acc;                          /* String accumulator */
   char zMsg[SQLITE_PRINT_BUF_SIZE*3];    /* Complete log message */
 
-  sqlite3StrAccumInit(&acc, zMsg, sizeof(zMsg), 0);
-  acc.useMalloc = 0;
+  sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0);
   sqlite3VXPrintf(&acc, 0, zFormat, ap);
   sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
                            sqlite3StrAccumFinish(&acc));
@@ -21536,7 +22389,7 @@ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
 /*
 ** Format and write a message to the log if logging is enabled.
 */
-SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...){
+SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...){
   va_list ap;                             /* Vararg list */
   if( sqlite3GlobalConfig.xLog ){
     va_start(ap, zFormat);
@@ -21545,7 +22398,7 @@ SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...){
   }
 }
 
-#if defined(SQLITE_DEBUG)
+#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
 /*
 ** A version of printf() that understands %lld.  Used for debugging.
 ** The printf() built into some versions of windows does not understand %lld
@@ -21555,8 +22408,7 @@ SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){
   va_list ap;
   StrAccum acc;
   char zBuf[500];
-  sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
-  acc.useMalloc = 0;
+  sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
   va_start(ap,zFormat);
   sqlite3VXPrintf(&acc, 0, zFormat, ap);
   va_end(ap);
@@ -21566,6 +22418,68 @@ SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){
 }
 #endif
 
+#ifdef SQLITE_DEBUG
+/*************************************************************************
+** Routines for implementing the "TreeView" display of hierarchical
+** data structures for debugging.
+**
+** The main entry points (coded elsewhere) are:
+**     sqlite3TreeViewExpr(0, pExpr, 0);
+**     sqlite3TreeViewExprList(0, pList, 0, 0);
+**     sqlite3TreeViewSelect(0, pSelect, 0);
+** Insert calls to those routines while debugging in order to display
+** a diagram of Expr, ExprList, and Select objects.
+**
+*/
+/* Add a new subitem to the tree.  The moreToFollow flag indicates that this
+** is not the last item in the tree. */
+SQLITE_PRIVATE TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){
+  if( p==0 ){
+    p = sqlite3_malloc64( sizeof(*p) );
+    if( p==0 ) return 0;
+    memset(p, 0, sizeof(*p));
+  }else{
+    p->iLevel++;
+  }
+  assert( moreToFollow==0 || moreToFollow==1 );
+  if( p->iLevel<sizeof(p->bLine) ) p->bLine[p->iLevel] = moreToFollow;
+  return p;
+}
+/* Finished with one layer of the tree */
+SQLITE_PRIVATE void sqlite3TreeViewPop(TreeView *p){
+  if( p==0 ) return;
+  p->iLevel--;
+  if( p->iLevel<0 ) sqlite3_free(p);
+}
+/* Generate a single line of output for the tree, with a prefix that contains
+** all the appropriate tree lines */
+SQLITE_PRIVATE void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){
+  va_list ap;
+  int i;
+  StrAccum acc;
+  char zBuf[500];
+  sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
+  if( p ){
+    for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
+      sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|   " : "    ", 4);
+    }
+    sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
+  }
+  va_start(ap, zFormat);
+  sqlite3VXPrintf(&acc, 0, zFormat, ap);
+  va_end(ap);
+  if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1);
+  sqlite3StrAccumFinish(&acc);
+  fprintf(stdout,"%s", zBuf);
+  fflush(stdout);
+}
+/* Shorthand for starting a new tree item that consists of a single label */
+SQLITE_PRIVATE void sqlite3TreeViewItem(TreeView *p, const char *zLabel, u8 moreToFollow){
+  p = sqlite3TreeViewPush(p, moreToFollow);
+  sqlite3TreeViewLine(p, "%s", zLabel);
+}
+#endif /* SQLITE_DEBUG */
+
 /*
 ** variable-argument wrapper around sqlite3VXPrintf().
 */
@@ -21609,7 +22523,7 @@ static SQLITE_WSD struct sqlite3PrngType {
 /*
 ** Return N random bytes.
 */
-SQLITE_API void sqlite3_randomness(int N, void *pBuf){
+SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *pBuf){
   unsigned char t;
   unsigned char *zBuf = pBuf;
 
@@ -21627,11 +22541,19 @@ SQLITE_API void sqlite3_randomness(int N, void *pBuf){
 #endif
 
 #if SQLITE_THREADSAFE
-  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
-  sqlite3_mutex_enter(mutex);
+  sqlite3_mutex *mutex;
+#endif
+
+#ifndef SQLITE_OMIT_AUTOINIT
+  if( sqlite3_initialize() ) return;
 #endif
 
-  if( N<=0 ){
+#if SQLITE_THREADSAFE
+  mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
+#endif
+
+  sqlite3_mutex_enter(mutex);
+  if( N<=0 || pBuf==0 ){
     wsdPrng.isInit = 0;
     sqlite3_mutex_leave(mutex);
     return;
@@ -21705,6 +22627,272 @@ SQLITE_PRIVATE void sqlite3PrngRestoreState(void){
 #endif /* SQLITE_OMIT_BUILTIN_TEST */
 
 /************** End of random.c **********************************************/
+/************** Begin file threads.c *****************************************/
+/*
+** 2012 July 21
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+******************************************************************************
+**
+** This file presents a simple cross-platform threading interface for
+** use internally by SQLite.
+**
+** A "thread" can be created using sqlite3ThreadCreate().  This thread
+** runs independently of its creator until it is joined using
+** sqlite3ThreadJoin(), at which point it terminates.
+**
+** Threads do not have to be real.  It could be that the work of the
+** "thread" is done by the main thread at either the sqlite3ThreadCreate()
+** or sqlite3ThreadJoin() call.  This is, in fact, what happens in
+** single threaded systems.  Nothing in SQLite requires multiple threads.
+** This interface exists so that applications that want to take advantage
+** of multiple cores can do so, while also allowing applications to stay
+** single-threaded if desired.
+*/
+#if SQLITE_OS_WIN
+#endif
+
+#if SQLITE_MAX_WORKER_THREADS>0
+
+/********************************* Unix Pthreads ****************************/
+#if SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) && SQLITE_THREADSAFE>0
+
+#define SQLITE_THREADS_IMPLEMENTED 1  /* Prevent the single-thread code below */
+/* #include <pthread.h> */
+
+/* A running thread */
+struct SQLiteThread {
+  pthread_t tid;                 /* Thread ID */
+  int done;                      /* Set to true when thread finishes */
+  void *pOut;                    /* Result returned by the thread */
+  void *(*xTask)(void*);         /* The thread routine */
+  void *pIn;                     /* Argument to the thread */
+};
+
+/* Create a new thread */
+SQLITE_PRIVATE int sqlite3ThreadCreate(
+  SQLiteThread **ppThread,  /* OUT: Write the thread object here */
+  void *(*xTask)(void*),    /* Routine to run in a separate thread */
+  void *pIn                 /* Argument passed into xTask() */
+){
+  SQLiteThread *p;
+  int rc;
+
+  assert( ppThread!=0 );
+  assert( xTask!=0 );
+  /* This routine is never used in single-threaded mode */
+  assert( sqlite3GlobalConfig.bCoreMutex!=0 );
+
+  *ppThread = 0;
+  p = sqlite3Malloc(sizeof(*p));
+  if( p==0 ) return SQLITE_NOMEM;
+  memset(p, 0, sizeof(*p));
+  p->xTask = xTask;
+  p->pIn = pIn;
+  if( sqlite3FaultSim(200) ){
+    rc = 1;
+  }else{    
+    rc = pthread_create(&p->tid, 0, xTask, pIn);
+  }
+  if( rc ){
+    p->done = 1;
+    p->pOut = xTask(pIn);
+  }
+  *ppThread = p;
+  return SQLITE_OK;
+}
+
+/* Get the results of the thread */
+SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
+  int rc;
+
+  assert( ppOut!=0 );
+  if( NEVER(p==0) ) return SQLITE_NOMEM;
+  if( p->done ){
+    *ppOut = p->pOut;
+    rc = SQLITE_OK;
+  }else{
+    rc = pthread_join(p->tid, ppOut) ? SQLITE_ERROR : SQLITE_OK;
+  }
+  sqlite3_free(p);
+  return rc;
+}
+
+#endif /* SQLITE_OS_UNIX && defined(SQLITE_MUTEX_PTHREADS) */
+/******************************** End Unix Pthreads *************************/
+
+
+/********************************* Win32 Threads ****************************/
+#if SQLITE_OS_WIN_THREADS
+
+#define SQLITE_THREADS_IMPLEMENTED 1  /* Prevent the single-thread code below */
+#include <process.h>
+
+/* A running thread */
+struct SQLiteThread {
+  void *tid;               /* The thread handle */
+  unsigned id;             /* The thread identifier */
+  void *(*xTask)(void*);   /* The routine to run as a thread */
+  void *pIn;               /* Argument to xTask */
+  void *pResult;           /* Result of xTask */
+};
+
+/* Thread procedure Win32 compatibility shim */
+static unsigned __stdcall sqlite3ThreadProc(
+  void *pArg  /* IN: Pointer to the SQLiteThread structure */
+){
+  SQLiteThread *p = (SQLiteThread *)pArg;
+
+  assert( p!=0 );
+#if 0
+  /*
+  ** This assert appears to trigger spuriously on certain
+  ** versions of Windows, possibly due to _beginthreadex()
+  ** and/or CreateThread() not fully setting their thread
+  ** ID parameter before starting the thread.
+  */
+  assert( p->id==GetCurrentThreadId() );
+#endif
+  assert( p->xTask!=0 );
+  p->pResult = p->xTask(p->pIn);
+
+  _endthreadex(0);
+  return 0; /* NOT REACHED */
+}
+
+/* Create a new thread */
+SQLITE_PRIVATE int sqlite3ThreadCreate(
+  SQLiteThread **ppThread,  /* OUT: Write the thread object here */
+  void *(*xTask)(void*),    /* Routine to run in a separate thread */
+  void *pIn                 /* Argument passed into xTask() */
+){
+  SQLiteThread *p;
+
+  assert( ppThread!=0 );
+  assert( xTask!=0 );
+  *ppThread = 0;
+  p = sqlite3Malloc(sizeof(*p));
+  if( p==0 ) return SQLITE_NOMEM;
+  if( sqlite3GlobalConfig.bCoreMutex==0 ){
+    memset(p, 0, sizeof(*p));
+  }else{
+    p->xTask = xTask;
+    p->pIn = pIn;
+    p->tid = (void*)_beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id);
+    if( p->tid==0 ){
+      memset(p, 0, sizeof(*p));
+    }
+  }
+  if( p->xTask==0 ){
+    p->id = GetCurrentThreadId();
+    p->pResult = xTask(pIn);
+  }
+  *ppThread = p;
+  return SQLITE_OK;
+}
+
+SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject); /* os_win.c */
+
+/* Get the results of the thread */
+SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
+  DWORD rc;
+  BOOL bRc;
+
+  assert( ppOut!=0 );
+  if( NEVER(p==0) ) return SQLITE_NOMEM;
+  if( p->xTask==0 ){
+    assert( p->id==GetCurrentThreadId() );
+    rc = WAIT_OBJECT_0;
+    assert( p->tid==0 );
+  }else{
+    assert( p->id!=0 && p->id!=GetCurrentThreadId() );
+    rc = sqlite3Win32Wait((HANDLE)p->tid);
+    assert( rc!=WAIT_IO_COMPLETION );
+    bRc = CloseHandle((HANDLE)p->tid);
+    assert( bRc );
+  }
+  if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult;
+  sqlite3_free(p);
+  return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR;
+}
+
+#endif /* SQLITE_OS_WIN_THREADS */
+/******************************** End Win32 Threads *************************/
+
+
+/********************************* Single-Threaded **************************/
+#ifndef SQLITE_THREADS_IMPLEMENTED
+/*
+** This implementation does not actually create a new thread.  It does the
+** work of the thread in the main thread, when either the thread is created
+** or when it is joined
+*/
+
+/* A running thread */
+struct SQLiteThread {
+  void *(*xTask)(void*);   /* The routine to run as a thread */
+  void *pIn;               /* Argument to xTask */
+  void *pResult;           /* Result of xTask */
+};
+
+/* Create a new thread */
+SQLITE_PRIVATE int sqlite3ThreadCreate(
+  SQLiteThread **ppThread,  /* OUT: Write the thread object here */
+  void *(*xTask)(void*),    /* Routine to run in a separate thread */
+  void *pIn                 /* Argument passed into xTask() */
+){
+  SQLiteThread *p;
+
+  assert( ppThread!=0 );
+  assert( xTask!=0 );
+  *ppThread = 0;
+  p = sqlite3Malloc(sizeof(*p));
+  if( p==0 ) return SQLITE_NOMEM;
+  if( (SQLITE_PTR_TO_INT(p)/17)&1 ){
+    p->xTask = xTask;
+    p->pIn = pIn;
+  }else{
+    p->xTask = 0;
+    p->pResult = xTask(pIn);
+  }
+  *ppThread = p;
+  return SQLITE_OK;
+}
+
+/* Get the results of the thread */
+SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
+
+  assert( ppOut!=0 );
+  if( NEVER(p==0) ) return SQLITE_NOMEM;
+  if( p->xTask ){
+    *ppOut = p->xTask(p->pIn);
+  }else{
+    *ppOut = p->pResult;
+  }
+  sqlite3_free(p);
+
+#if defined(SQLITE_TEST)
+  {
+    void *pTstAlloc = sqlite3Malloc(10);
+    if (!pTstAlloc) return SQLITE_NOMEM;
+    sqlite3_free(pTstAlloc);
+  }
+#endif
+
+  return SQLITE_OK;
+}
+
+#endif /* !defined(SQLITE_THREADS_IMPLEMENTED) */
+/****************************** End Single-Threaded *************************/
+#endif /* SQLITE_MAX_WORKER_THREADS>0 */
+
+/************** End of threads.c *********************************************/
 /************** Begin file utf.c *********************************************/
 /*
 ** 2004 April 13
@@ -21905,7 +23093,7 @@ SQLITE_PRIVATE u32 sqlite3Utf8Read(
 ** desiredEnc. It is an error if the string is already of the desired
 ** encoding, or if *pMem does not contain a string value.
 */
-SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
+SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
   int len;                    /* Maximum length of output string in bytes */
   unsigned char *zOut;                  /* Output buffer */
   unsigned char *zIn;                   /* Input iterator */
@@ -22020,12 +23208,13 @@ SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
   *z = 0;
   assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len );
 
+  c = pMem->flags;
   sqlite3VdbeMemRelease(pMem);
-  pMem->flags &= ~(MEM_Static|MEM_Dyn|MEM_Ephem);
+  pMem->flags = MEM_Str|MEM_Term|(c&MEM_AffMask);
   pMem->enc = desiredEnc;
-  pMem->flags |= (MEM_Term);
   pMem->z = (char*)zOut;
   pMem->zMalloc = pMem->z;
+  pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->z);
 
 translate_out:
 #if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)
@@ -22254,7 +23443,7 @@ SQLITE_PRIVATE void sqlite3UtfSelfTest(void){
 **
 */
 /* #include <stdarg.h> */
-#ifdef SQLITE_HAVE_ISNAN
+#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
 # include <math.h>
 #endif
 
@@ -22295,7 +23484,7 @@ SQLITE_PRIVATE int sqlite3FaultSim(int iTest){
 */
 SQLITE_PRIVATE int sqlite3IsNaN(double x){
   int rc;   /* The value return */
-#if !defined(SQLITE_HAVE_ISNAN)
+#if !SQLITE_HAVE_ISNAN && !HAVE_ISNAN
   /*
   ** Systems that support the isnan() library function should probably
   ** make use of it by compiling with -DSQLITE_HAVE_ISNAN.  But we have
@@ -22325,9 +23514,9 @@ SQLITE_PRIVATE int sqlite3IsNaN(double x){
   volatile double y = x;
   volatile double z = y;
   rc = (y!=z);
-#else  /* if defined(SQLITE_HAVE_ISNAN) */
+#else  /* if HAVE_ISNAN */
   rc = isnan(x);
-#endif /* SQLITE_HAVE_ISNAN */
+#endif /* HAVE_ISNAN */
   testcase( rc );
   return rc;
 }
@@ -22349,6 +23538,15 @@ SQLITE_PRIVATE int sqlite3Strlen30(const char *z){
 }
 
 /*
+** Set the current error code to err_code and clear any prior error message.
+*/
+SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){
+  assert( db!=0 );
+  db->errCode = err_code;
+  if( db->pErr ) sqlite3ValueSetNull(db->pErr);
+}
+
+/*
 ** Set the most recent error code and error string for the sqlite
 ** handle "db". The error code is set to "err_code".
 **
@@ -22369,18 +23567,18 @@ SQLITE_PRIVATE int sqlite3Strlen30(const char *z){
 ** should be called with err_code set to SQLITE_OK and zFormat set
 ** to NULL.
 */
-SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat, ...){
+SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *zFormat, ...){
   assert( db!=0 );
   db->errCode = err_code;
-  if( zFormat && (db->pErr || (db->pErr = sqlite3ValueNew(db))!=0) ){
+  if( zFormat==0 ){
+    sqlite3Error(db, err_code);
+  }else if( db->pErr || (db->pErr = sqlite3ValueNew(db))!=0 ){
     char *z;
     va_list ap;
     va_start(ap, zFormat);
     z = sqlite3VMPrintf(db, zFormat, ap);
     va_end(ap);
     sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC);
-  }else if( db->pErr ){
-    sqlite3ValueSetNull(db->pErr);
   }
 }
 
@@ -22394,12 +23592,12 @@ SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code, const char *zFormat,
 **      %T      Insert a token
 **      %S      Insert the first element of a SrcList
 **
-** This function should be used to report any error that occurs whilst
+** This function should be used to report any error that occurs while
 ** compiling an SQL statement (i.e. within sqlite3_prepare()). The
 ** last thing the sqlite3_prepare() function does is copy the error
 ** stored by this function into the database handle using sqlite3Error().
-** Function sqlite3Error() should be used during statement execution
-** (sqlite3_step() etc.).
+** Functions sqlite3Error() or sqlite3ErrorWithMsg() should be used
+** during statement execution (sqlite3_step() etc.).
 */
 SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
   char *zMsg;
@@ -22432,7 +23630,7 @@ SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){
 ** occur.
 **
 ** 2002-Feb-14: This routine is extended to remove MS-Access style
-** brackets from around identifers.  For example:  "[a-b-c]" becomes
+** brackets from around identifiers.  For example:  "[a-b-c]" becomes
 ** "a-b-c".
 */
 SQLITE_PRIVATE int sqlite3Dequote(char *z){
@@ -22477,15 +23675,25 @@ SQLITE_PRIVATE int sqlite3Dequote(char *z){
 ** case-independent fashion, using the same definition of "case
 ** independence" that SQLite uses internally when comparing identifiers.
 */
-SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){
+SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *zLeft, const char *zRight){
   register unsigned char *a, *b;
+  if( zLeft==0 ){
+    return zRight ? -1 : 0;
+  }else if( zRight==0 ){
+    return 1;
+  }
   a = (unsigned char *)zLeft;
   b = (unsigned char *)zRight;
   while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
   return UpperToLower[*a] - UpperToLower[*b];
 }
-SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
+SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){
   register unsigned char *a, *b;
+  if( zLeft==0 ){
+    return zRight ? -1 : 0;
+  }else if( zRight==0 ){
+    return 1;
+  }
   a = (unsigned char *)zLeft;
   b = (unsigned char *)zRight;
   while( N-- > 0 && *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; }
@@ -22873,6 +24081,7 @@ SQLITE_PRIVATE int sqlite3GetInt32(const char *zNum, int *pValue){
     }
   }
 #endif
+  while( zNum[0]=='0' ) zNum++;
   for(i=0; i<11 && (c = zNum[i] - '0')>=0 && c<=9; i++){
     v = v*10 + c;
   }
@@ -22936,7 +24145,7 @@ SQLITE_PRIVATE int sqlite3Atoi(const char *z){
 ** bit clear.  Except, if we get to the 9th byte, it stores the full
 ** 8 bits and is the last byte.
 */
-SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *p, u64 v){
+static int SQLITE_NOINLINE putVarint64(unsigned char *p, u64 v){
   int i, j, n;
   u8 buf[10];
   if( v & (((u64)0xff000000)<<32) ){
@@ -22960,28 +24169,17 @@ SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *p, u64 v){
   }
   return n;
 }
-
-/*
-** This routine is a faster version of sqlite3PutVarint() that only
-** works for 32-bit positive integers and which is optimized for
-** the common case of small integers.  A MACRO version, putVarint32,
-** is provided which inlines the single-byte case.  All code should use
-** the MACRO version as this function assumes the single-byte case has
-** already been handled.
-*/
-SQLITE_PRIVATE int sqlite3PutVarint32(unsigned char *p, u32 v){
-#ifndef putVarint32
-  if( (v & ~0x7f)==0 ){
-    p[0] = v;
+SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *p, u64 v){
+  if( v<=0x7f ){
+    p[0] = v&0x7f;
     return 1;
   }
-#endif
-  if( (v & ~0x3fff)==0 ){
-    p[0] = (u8)((v>>7) | 0x80);
-    p[1] = (u8)(v & 0x7f);
+  if( v<=0x3fff ){
+    p[0] = ((v>>7)&0x7f)|0x80;
+    p[1] = v&0x7f;
     return 2;
   }
-  return sqlite3PutVarint(p, v);
+  return putVarint64(p,v);
 }
 
 /*
@@ -23657,12 +24855,11 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash *pH){
 /*
 ** The hashing function.
 */
-static unsigned int strHash(const char *z, int nKey){
+static unsigned int strHash(const char *z){
   unsigned int h = 0;
-  assert( nKey>=0 );
-  while( nKey > 0  ){
-    h = (h<<3) ^ h ^ sqlite3UpperToLower[(unsigned char)*z++];
-    nKey--;
+  unsigned char c;
+  while( (c = (unsigned char)*z++)!=0 ){
+    h = (h<<3) ^ h ^ sqlite3UpperToLower[c];
   }
   return h;
 }
@@ -23734,7 +24931,7 @@ static int rehash(Hash *pH, unsigned int new_size){
   pH->htsize = new_size = sqlite3MallocSize(new_ht)/sizeof(struct _ht);
   memset(new_ht, 0, new_size*sizeof(struct _ht));
   for(elem=pH->first, pH->first=0; elem; elem = next_elem){
-    unsigned int h = strHash(elem->pKey, elem->nKey) % new_size;
+    unsigned int h = strHash(elem->pKey) % new_size;
     next_elem = elem->next;
     insertElement(pH, &new_ht[h], elem);
   }
@@ -23742,28 +24939,33 @@ static int rehash(Hash *pH, unsigned int new_size){
 }
 
 /* This function (for internal use only) locates an element in an
-** hash table that matches the given key.  The hash for this key has
-** already been computed and is passed as the 4th parameter.
+** hash table that matches the given key.  The hash for this key is
+** also computed and returned in the *pH parameter.
 */
-static HashElem *findElementGivenHash(
+static HashElem *findElementWithHash(
   const Hash *pH,     /* The pH to be searched */
   const char *pKey,   /* The key we are searching for */
-  int nKey,           /* Bytes in key (not counting zero terminator) */
-  unsigned int h      /* The hash for this key. */
+  unsigned int *pHash /* Write the hash value here */
 ){
   HashElem *elem;                /* Used to loop thru the element list */
   int count;                     /* Number of elements left to test */
+  unsigned int h;                /* The computed hash */
 
   if( pH->ht ){
-    struct _ht *pEntry = &pH->ht[h];
+    struct _ht *pEntry;
+    h = strHash(pKey) % pH->htsize;
+    pEntry = &pH->ht[h];
     elem = pEntry->chain;
     count = pEntry->count;
   }else{
+    h = 0;
     elem = pH->first;
     count = pH->count;
   }
-  while( count-- && ALWAYS(elem) ){
-    if( elem->nKey==nKey && sqlite3StrNICmp(elem->pKey,pKey,nKey)==0 ){ 
+  *pHash = h;
+  while( count-- ){
+    assert( elem!=0 );
+    if( sqlite3StrICmp(elem->pKey,pKey)==0 ){ 
       return elem;
     }
     elem = elem->next;
@@ -23806,26 +25008,20 @@ static void removeElementGivenHash(
 }
 
 /* Attempt to locate an element of the hash table pH with a key
-** that matches pKey,nKey.  Return the data for this element if it is
+** that matches pKey.  Return the data for this element if it is
 ** found, or NULL if there is no match.
 */
-SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey, int nKey){
+SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey){
   HashElem *elem;    /* The element that matches key */
   unsigned int h;    /* A hash on key */
 
   assert( pH!=0 );
   assert( pKey!=0 );
-  assert( nKey>=0 );
-  if( pH->ht ){
-    h = strHash(pKey, nKey) % pH->htsize;
-  }else{
-    h = 0;
-  }
-  elem = findElementGivenHash(pH, pKey, nKey, h);
+  elem = findElementWithHash(pH, pKey, &h);
   return elem ? elem->data : 0;
 }
 
-/* Insert an element into the hash table pH.  The key is pKey,nKey
+/* Insert an element into the hash table pH.  The key is pKey
 ** and the data is "data".
 **
 ** If no element exists with a matching key, then a new
@@ -23839,20 +25035,14 @@ SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey, int nKey)
 ** If the "data" parameter to this function is NULL, then the
 ** element corresponding to "key" is removed from the hash table.
 */
-SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, int nKey, void *data){
+SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, void *data){
   unsigned int h;       /* the hash of the key modulo hash table size */
   HashElem *elem;       /* Used to loop thru the element list */
   HashElem *new_elem;   /* New element added to the pH */
 
   assert( pH!=0 );
   assert( pKey!=0 );
-  assert( nKey>=0 );
-  if( pH->htsize ){
-    h = strHash(pKey, nKey) % pH->htsize;
-  }else{
-    h = 0;
-  }
-  elem = findElementGivenHash(pH,pKey,nKey,h);
+  elem = findElementWithHash(pH,pKey,&h);
   if( elem ){
     void *old_data = elem->data;
     if( data==0 ){
@@ -23860,7 +25050,6 @@ SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, int nKey, voi
     }else{
       elem->data = data;
       elem->pKey = pKey;
-      assert(nKey==elem->nKey);
     }
     return old_data;
   }
@@ -23868,20 +25057,15 @@ SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, int nKey, voi
   new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) );
   if( new_elem==0 ) return data;
   new_elem->pKey = pKey;
-  new_elem->nKey = nKey;
   new_elem->data = data;
   pH->count++;
   if( pH->count>=10 && pH->count > 2*pH->htsize ){
     if( rehash(pH, pH->count*2) ){
       assert( pH->htsize>0 );
-      h = strHash(pKey, nKey) % pH->htsize;
+      h = strHash(pKey) % pH->htsize;
     }
   }
-  if( pH->ht ){
-    insertElement(pH, &pH->ht[h], new_elem);
-  }else{
-    insertElement(pH, 0, new_elem);
-  }
+  insertElement(pH, pH->ht ? &pH->ht[h] : 0, new_elem);
   return 0;
 }
 
@@ -23936,42 +25120,42 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
      /*  37 */ "AddImm"           OpHelp("r[P1]=r[P1]+P2"),
      /*  38 */ "MustBeInt"        OpHelp(""),
      /*  39 */ "RealAffinity"     OpHelp(""),
-     /*  40 */ "Permutation"      OpHelp(""),
-     /*  41 */ "Compare"          OpHelp("r[P1 P3] <-> r[P2 P3]"),
-     /*  42 */ "Jump"             OpHelp(""),
-     /*  43 */ "Once"             OpHelp(""),
-     /*  44 */ "If"               OpHelp(""),
-     /*  45 */ "IfNot"            OpHelp(""),
-     /*  46 */ "Column"           OpHelp("r[P3]=PX"),
-     /*  47 */ "Affinity"         OpHelp("affinity(r[P1 P2])"),
-     /*  48 */ "MakeRecord"       OpHelp("r[P3]=mkrec(r[P1 P2])"),
-     /*  49 */ "Count"            OpHelp("r[P2]=count()"),
-     /*  50 */ "ReadCookie"       OpHelp(""),
-     /*  51 */ "SetCookie"        OpHelp(""),
-     /*  52 */ "ReopenIdx"        OpHelp("root=P2 iDb=P3"),
-     /*  53 */ "OpenRead"         OpHelp("root=P2 iDb=P3"),
-     /*  54 */ "OpenWrite"        OpHelp("root=P2 iDb=P3"),
-     /*  55 */ "OpenAutoindex"    OpHelp("nColumn=P2"),
-     /*  56 */ "OpenEphemeral"    OpHelp("nColumn=P2"),
-     /*  57 */ "SorterOpen"       OpHelp(""),
-     /*  58 */ "OpenPseudo"       OpHelp("P3 columns in r[P2]"),
-     /*  59 */ "Close"            OpHelp(""),
-     /*  60 */ "SeekLT"           OpHelp("key=r[P3 P4]"),
-     /*  61 */ "SeekLE"           OpHelp("key=r[P3 P4]"),
-     /*  62 */ "SeekGE"           OpHelp("key=r[P3 P4]"),
-     /*  63 */ "SeekGT"           OpHelp("key=r[P3 P4]"),
-     /*  64 */ "Seek"             OpHelp("intkey=r[P2]"),
-     /*  65 */ "NoConflict"       OpHelp("key=r[P3 P4]"),
-     /*  66 */ "NotFound"         OpHelp("key=r[P3 P4]"),
-     /*  67 */ "Found"            OpHelp("key=r[P3 P4]"),
-     /*  68 */ "NotExists"        OpHelp("intkey=r[P3]"),
-     /*  69 */ "Sequence"         OpHelp("r[P2]=cursor[P1].ctr++"),
-     /*  70 */ "NewRowid"         OpHelp("r[P2]=rowid"),
+     /*  40 */ "Cast"             OpHelp("affinity(r[P1])"),
+     /*  41 */ "Permutation"      OpHelp(""),
+     /*  42 */ "Compare"          OpHelp("r[P1 P3] <-> r[P2 P3]"),
+     /*  43 */ "Jump"             OpHelp(""),
+     /*  44 */ "Once"             OpHelp(""),
+     /*  45 */ "If"               OpHelp(""),
+     /*  46 */ "IfNot"            OpHelp(""),
+     /*  47 */ "Column"           OpHelp("r[P3]=PX"),
+     /*  48 */ "Affinity"         OpHelp("affinity(r[P1 P2])"),
+     /*  49 */ "MakeRecord"       OpHelp("r[P3]=mkrec(r[P1 P2])"),
+     /*  50 */ "Count"            OpHelp("r[P2]=count()"),
+     /*  51 */ "ReadCookie"       OpHelp(""),
+     /*  52 */ "SetCookie"        OpHelp(""),
+     /*  53 */ "ReopenIdx"        OpHelp("root=P2 iDb=P3"),
+     /*  54 */ "OpenRead"         OpHelp("root=P2 iDb=P3"),
+     /*  55 */ "OpenWrite"        OpHelp("root=P2 iDb=P3"),
+     /*  56 */ "OpenAutoindex"    OpHelp("nColumn=P2"),
+     /*  57 */ "OpenEphemeral"    OpHelp("nColumn=P2"),
+     /*  58 */ "SorterOpen"       OpHelp(""),
+     /*  59 */ "SequenceTest"     OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
+     /*  60 */ "OpenPseudo"       OpHelp("P3 columns in r[P2]"),
+     /*  61 */ "Close"            OpHelp(""),
+     /*  62 */ "SeekLT"           OpHelp("key=r[P3 P4]"),
+     /*  63 */ "SeekLE"           OpHelp("key=r[P3 P4]"),
+     /*  64 */ "SeekGE"           OpHelp("key=r[P3 P4]"),
+     /*  65 */ "SeekGT"           OpHelp("key=r[P3 P4]"),
+     /*  66 */ "Seek"             OpHelp("intkey=r[P2]"),
+     /*  67 */ "NoConflict"       OpHelp("key=r[P3 P4]"),
+     /*  68 */ "NotFound"         OpHelp("key=r[P3 P4]"),
+     /*  69 */ "Found"            OpHelp("key=r[P3 P4]"),
+     /*  70 */ "NotExists"        OpHelp("intkey=r[P3]"),
      /*  71 */ "Or"               OpHelp("r[P3]=(r[P1] || r[P2])"),
      /*  72 */ "And"              OpHelp("r[P3]=(r[P1] && r[P2])"),
-     /*  73 */ "Insert"           OpHelp("intkey=r[P3] data=r[P2]"),
-     /*  74 */ "InsertInt"        OpHelp("intkey=P3 data=r[P2]"),
-     /*  75 */ "Delete"           OpHelp(""),
+     /*  73 */ "Sequence"         OpHelp("r[P2]=cursor[P1].ctr++"),
+     /*  74 */ "NewRowid"         OpHelp("r[P2]=rowid"),
+     /*  75 */ "Insert"           OpHelp("intkey=r[P3] data=r[P2]"),
      /*  76 */ "IsNull"           OpHelp("if r[P1]==NULL goto P2"),
      /*  77 */ "NotNull"          OpHelp("if r[P1]!=NULL goto P2"),
      /*  78 */ "Ne"               OpHelp("if r[P1]!=r[P3] goto P2"),
@@ -23980,7 +25164,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
      /*  81 */ "Le"               OpHelp("if r[P1]<=r[P3] goto P2"),
      /*  82 */ "Lt"               OpHelp("if r[P1]<r[P3] goto P2"),
      /*  83 */ "Ge"               OpHelp("if r[P1]>=r[P3] goto P2"),
-     /*  84 */ "ResetCount"       OpHelp(""),
+     /*  84 */ "InsertInt"        OpHelp("intkey=P3 data=r[P2]"),
      /*  85 */ "BitAnd"           OpHelp("r[P3]=r[P1]&r[P2]"),
      /*  86 */ "BitOr"            OpHelp("r[P3]=r[P1]|r[P2]"),
      /*  87 */ "ShiftLeft"        OpHelp("r[P3]=r[P2]<<r[P1]"),
@@ -23991,70 +25175,69 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
      /*  92 */ "Divide"           OpHelp("r[P3]=r[P2]/r[P1]"),
      /*  93 */ "Remainder"        OpHelp("r[P3]=r[P2]%r[P1]"),
      /*  94 */ "Concat"           OpHelp("r[P3]=r[P2]+r[P1]"),
-     /*  95 */ "SorterCompare"    OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
+     /*  95 */ "Delete"           OpHelp(""),
      /*  96 */ "BitNot"           OpHelp("r[P1]= ~r[P1]"),
      /*  97 */ "String8"          OpHelp("r[P2]='P4'"),
-     /*  98 */ "SorterData"       OpHelp("r[P2]=data"),
-     /*  99 */ "RowKey"           OpHelp("r[P2]=key"),
-     /* 100 */ "RowData"          OpHelp("r[P2]=data"),
-     /* 101 */ "Rowid"            OpHelp("r[P2]=rowid"),
-     /* 102 */ "NullRow"          OpHelp(""),
-     /* 103 */ "Last"             OpHelp(""),
-     /* 104 */ "SorterSort"       OpHelp(""),
-     /* 105 */ "Sort"             OpHelp(""),
-     /* 106 */ "Rewind"           OpHelp(""),
-     /* 107 */ "SorterInsert"     OpHelp(""),
-     /* 108 */ "IdxInsert"        OpHelp("key=r[P2]"),
-     /* 109 */ "IdxDelete"        OpHelp("key=r[P2 P3]"),
-     /* 110 */ "IdxRowid"         OpHelp("r[P2]=rowid"),
-     /* 111 */ "IdxLE"            OpHelp("key=r[P3 P4]"),
-     /* 112 */ "IdxGT"            OpHelp("key=r[P3 P4]"),
-     /* 113 */ "IdxLT"            OpHelp("key=r[P3 P4]"),
-     /* 114 */ "IdxGE"            OpHelp("key=r[P3 P4]"),
-     /* 115 */ "Destroy"          OpHelp(""),
-     /* 116 */ "Clear"            OpHelp(""),
-     /* 117 */ "ResetSorter"      OpHelp(""),
-     /* 118 */ "CreateIndex"      OpHelp("r[P2]=root iDb=P1"),
-     /* 119 */ "CreateTable"      OpHelp("r[P2]=root iDb=P1"),
-     /* 120 */ "ParseSchema"      OpHelp(""),
-     /* 121 */ "LoadAnalysis"     OpHelp(""),
-     /* 122 */ "DropTable"        OpHelp(""),
-     /* 123 */ "DropIndex"        OpHelp(""),
-     /* 124 */ "DropTrigger"      OpHelp(""),
-     /* 125 */ "IntegrityCk"      OpHelp(""),
-     /* 126 */ "RowSetAdd"        OpHelp("rowset(P1)=r[P2]"),
-     /* 127 */ "RowSetRead"       OpHelp("r[P3]=rowset(P1)"),
-     /* 128 */ "RowSetTest"       OpHelp("if r[P3] in rowset(P1) goto P2"),
-     /* 129 */ "Program"          OpHelp(""),
-     /* 130 */ "Param"            OpHelp(""),
-     /* 131 */ "FkCounter"        OpHelp("fkctr[P1]+=P2"),
-     /* 132 */ "FkIfZero"         OpHelp("if fkctr[P1]==0 goto P2"),
+     /*  98 */ "ResetCount"       OpHelp(""),
+     /*  99 */ "SorterCompare"    OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
+     /* 100 */ "SorterData"       OpHelp("r[P2]=data"),
+     /* 101 */ "RowKey"           OpHelp("r[P2]=key"),
+     /* 102 */ "RowData"          OpHelp("r[P2]=data"),
+     /* 103 */ "Rowid"            OpHelp("r[P2]=rowid"),
+     /* 104 */ "NullRow"          OpHelp(""),
+     /* 105 */ "Last"             OpHelp(""),
+     /* 106 */ "SorterSort"       OpHelp(""),
+     /* 107 */ "Sort"             OpHelp(""),
+     /* 108 */ "Rewind"           OpHelp(""),
+     /* 109 */ "SorterInsert"     OpHelp(""),
+     /* 110 */ "IdxInsert"        OpHelp("key=r[P2]"),
+     /* 111 */ "IdxDelete"        OpHelp("key=r[P2 P3]"),
+     /* 112 */ "IdxRowid"         OpHelp("r[P2]=rowid"),
+     /* 113 */ "IdxLE"            OpHelp("key=r[P3 P4]"),
+     /* 114 */ "IdxGT"            OpHelp("key=r[P3 P4]"),
+     /* 115 */ "IdxLT"            OpHelp("key=r[P3 P4]"),
+     /* 116 */ "IdxGE"            OpHelp("key=r[P3 P4]"),
+     /* 117 */ "Destroy"          OpHelp(""),
+     /* 118 */ "Clear"            OpHelp(""),
+     /* 119 */ "ResetSorter"      OpHelp(""),
+     /* 120 */ "CreateIndex"      OpHelp("r[P2]=root iDb=P1"),
+     /* 121 */ "CreateTable"      OpHelp("r[P2]=root iDb=P1"),
+     /* 122 */ "ParseSchema"      OpHelp(""),
+     /* 123 */ "LoadAnalysis"     OpHelp(""),
+     /* 124 */ "DropTable"        OpHelp(""),
+     /* 125 */ "DropIndex"        OpHelp(""),
+     /* 126 */ "DropTrigger"      OpHelp(""),
+     /* 127 */ "IntegrityCk"      OpHelp(""),
+     /* 128 */ "RowSetAdd"        OpHelp("rowset(P1)=r[P2]"),
+     /* 129 */ "RowSetRead"       OpHelp("r[P3]=rowset(P1)"),
+     /* 130 */ "RowSetTest"       OpHelp("if r[P3] in rowset(P1) goto P2"),
+     /* 131 */ "Program"          OpHelp(""),
+     /* 132 */ "Param"            OpHelp(""),
      /* 133 */ "Real"             OpHelp("r[P2]=P4"),
-     /* 134 */ "MemMax"           OpHelp("r[P1]=max(r[P1],r[P2])"),
-     /* 135 */ "IfPos"            OpHelp("if r[P1]>0 goto P2"),
-     /* 136 */ "IfNeg"            OpHelp("r[P1]+=P3, if r[P1]<0 goto P2"),
-     /* 137 */ "IfZero"           OpHelp("r[P1]+=P3, if r[P1]==0 goto P2"),
-     /* 138 */ "AggFinal"         OpHelp("accum=r[P1] N=P2"),
-     /* 139 */ "IncrVacuum"       OpHelp(""),
-     /* 140 */ "Expire"           OpHelp(""),
-     /* 141 */ "TableLock"        OpHelp("iDb=P1 root=P2 write=P3"),
-     /* 142 */ "VBegin"           OpHelp(""),
-     /* 143 */ "ToText"           OpHelp(""),
-     /* 144 */ "ToBlob"           OpHelp(""),
-     /* 145 */ "ToNumeric"        OpHelp(""),
-     /* 146 */ "ToInt"            OpHelp(""),
-     /* 147 */ "ToReal"           OpHelp(""),
-     /* 148 */ "VCreate"          OpHelp(""),
-     /* 149 */ "VDestroy"         OpHelp(""),
-     /* 150 */ "VOpen"            OpHelp(""),
-     /* 151 */ "VColumn"          OpHelp("r[P3]=vcolumn(P2)"),
-     /* 152 */ "VNext"            OpHelp(""),
-     /* 153 */ "VRename"          OpHelp(""),
-     /* 154 */ "Pagecount"        OpHelp(""),
-     /* 155 */ "MaxPgcnt"         OpHelp(""),
-     /* 156 */ "Init"             OpHelp("Start at P2"),
-     /* 157 */ "Noop"             OpHelp(""),
-     /* 158 */ "Explain"          OpHelp(""),
+     /* 134 */ "FkCounter"        OpHelp("fkctr[P1]+=P2"),
+     /* 135 */ "FkIfZero"         OpHelp("if fkctr[P1]==0 goto P2"),
+     /* 136 */ "MemMax"           OpHelp("r[P1]=max(r[P1],r[P2])"),
+     /* 137 */ "IfPos"            OpHelp("if r[P1]>0 goto P2"),
+     /* 138 */ "IfNeg"            OpHelp("r[P1]+=P3, if r[P1]<0 goto P2"),
+     /* 139 */ "IfNotZero"        OpHelp("if r[P1]!=0 then r[P1]+=P3, goto P2"),
+     /* 140 */ "DecrJumpZero"     OpHelp("if (--r[P1])==0 goto P2"),
+     /* 141 */ "JumpZeroIncr"     OpHelp("if (r[P1]++)==0 ) goto P2"),
+     /* 142 */ "AggFinal"         OpHelp("accum=r[P1] N=P2"),
+     /* 143 */ "IncrVacuum"       OpHelp(""),
+     /* 144 */ "Expire"           OpHelp(""),
+     /* 145 */ "TableLock"        OpHelp("iDb=P1 root=P2 write=P3"),
+     /* 146 */ "VBegin"           OpHelp(""),
+     /* 147 */ "VCreate"          OpHelp(""),
+     /* 148 */ "VDestroy"         OpHelp(""),
+     /* 149 */ "VOpen"            OpHelp(""),
+     /* 150 */ "VColumn"          OpHelp("r[P3]=vcolumn(P2)"),
+     /* 151 */ "VNext"            OpHelp(""),
+     /* 152 */ "VRename"          OpHelp(""),
+     /* 153 */ "Pagecount"        OpHelp(""),
+     /* 154 */ "MaxPgcnt"         OpHelp(""),
+     /* 155 */ "Init"             OpHelp("Start at P2"),
+     /* 156 */ "Noop"             OpHelp(""),
+     /* 157 */ "Explain"          OpHelp(""),
   };
   return azName[i];
 }
@@ -24135,18 +25318,6 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
 #endif
 
 /*
-** Define the OS_VXWORKS pre-processor macro to 1 if building on 
-** vxworks, or 0 otherwise.
-*/
-#ifndef OS_VXWORKS
-#  if defined(__RTP__) || defined(_WRS_KERNEL)
-#    define OS_VXWORKS 1
-#  else
-#    define OS_VXWORKS 0
-#  endif
-#endif
-
-/*
 ** standard include files.
 */
 #include <sys/types.h>
@@ -24160,18 +25331,30 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
 # include <sys/mman.h>
 #endif
 
-#if SQLITE_ENABLE_LOCKING_STYLE || OS_VXWORKS
+#if SQLITE_ENABLE_LOCKING_STYLE
 # include <sys/ioctl.h>
-# if OS_VXWORKS
-#  include <semaphore.h>
-#  include <limits.h>
-# else
-#  include <sys/file.h>
-#  include <sys/param.h>
-# endif
+# include <sys/file.h>
+# include <sys/param.h>
 #endif /* SQLITE_ENABLE_LOCKING_STYLE */
 
-#if defined(__APPLE__) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS)
+#if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \
+                           (__IPHONE_OS_VERSION_MIN_REQUIRED > 2000))
+#  if (!defined(TARGET_OS_EMBEDDED) || (TARGET_OS_EMBEDDED==0)) \
+       && (!defined(TARGET_IPHONE_SIMULATOR) || (TARGET_IPHONE_SIMULATOR==0))
+#    define HAVE_GETHOSTUUID 1
+#  else
+#    warning "gethostuuid() is disabled."
+#  endif
+#endif
+
+
+#if OS_VXWORKS
+/* # include <sys/ioctl.h> */
+# include <semaphore.h>
+# include <limits.h>
+#endif /* OS_VXWORKS */
+
+#if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
 # include <sys/mount.h>
 #endif
 
@@ -24212,6 +25395,10 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
 */
 #define MAX_PATHNAME 512
 
+/* Always cast the getpid() return type for compatibility with
+** kernel modules in VxWorks. */
+#define osGetpid(X) (pid_t)getpid()
+
 /*
 ** Only set the lastErrno if the error code is a real error and not 
 ** a normal expected return code of SQLITE_BUSY or SQLITE_OK
@@ -24300,7 +25487,7 @@ struct unixFile {
 ** method was called.  If xOpen() is called from a different process id,
 ** indicating that a fork() has occurred, the PRNG will be reset.
 */
-static int randomnessPid = 0;
+static pid_t randomnessPid = 0;
 
 /*
 ** Allowed values for the unixFile.ctrlFlags bitmask:
@@ -24317,7 +25504,8 @@ static int randomnessPid = 0;
 #define UNIXFILE_DELETE      0x20     /* Delete on close */
 #define UNIXFILE_URI         0x40     /* Filename might have query parameters */
 #define UNIXFILE_NOLOCK      0x80     /* Do no file locking */
-#define UNIXFILE_WARNED    0x0100     /* verifyDbFile() warnings have been issued */
+#define UNIXFILE_WARNED    0x0100     /* verifyDbFile() warnings issued */
+#define UNIXFILE_BLOCK     0x0200     /* Next SHM lock might block */
 
 /*
 ** Include code that is common to all os_*.c files
@@ -24355,16 +25543,6 @@ static int randomnessPid = 0;
 # error "The MEMORY_DEBUG macro is obsolete.  Use SQLITE_DEBUG instead."
 #endif
 
-#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
-# ifndef SQLITE_DEBUG_OS_TRACE
-#   define SQLITE_DEBUG_OS_TRACE 0
-# endif
-  int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE;
-# define OSTRACE(X)          if( sqlite3OSTrace ) sqlite3DebugPrintf X
-#else
-# define OSTRACE(X)
-#endif
-
 /*
 ** Macros for performance tracing.  Normally turned off.  Only works
 ** on i486 hardware.
@@ -24571,6 +25749,14 @@ SQLITE_API int sqlite3_open_file_count = 0;
 #endif
 
 /*
+** Explicitly call the 64-bit version of lseek() on Android. Otherwise, lseek()
+** is the 32-bit version, even if _FILE_OFFSET_BITS=64 is defined.
+*/
+#ifdef __ANDROID__
+# define lseek lseek64
+#endif
+
+/*
 ** Different Unix systems declare open() in different ways.  Same use
 ** open(const char*,int,mode_t).  Others use open(const char*,int,...).
 ** The difference is important when using a pointer to the function.
@@ -24648,7 +25834,7 @@ static struct unix_syscall {
   { "read",         (sqlite3_syscall_ptr)read,       0  },
 #define osRead      ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent)
 
-#if defined(USE_PREAD) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS)
+#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE
   { "pread",        (sqlite3_syscall_ptr)pread,      0  },
 #else
   { "pread",        (sqlite3_syscall_ptr)0,          0  },
@@ -24665,7 +25851,7 @@ static struct unix_syscall {
   { "write",        (sqlite3_syscall_ptr)write,      0  },
 #define osWrite     ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent)
 
-#if defined(USE_PREAD) || (SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS)
+#if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE
   { "pwrite",       (sqlite3_syscall_ptr)pwrite,     0  },
 #else
   { "pwrite",       (sqlite3_syscall_ptr)0,          0  },
@@ -24899,10 +26085,10 @@ static int unixMutexHeld(void) {
 #endif
 
 
-#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
+#ifdef SQLITE_HAVE_OS_TRACE
 /*
 ** Helper function for printing out trace information from debugging
-** binaries. This returns the string represetation of the supplied
+** binaries. This returns the string representation of the supplied
 ** integer lock-type.
 */
 static const char *azFileLock(int eFileLock){
@@ -24979,9 +26165,22 @@ static int lockTrace(int fd, int op, struct flock *p){
 
 /*
 ** Retry ftruncate() calls that fail due to EINTR
+**
+** All calls to ftruncate() within this file should be made through
+** this wrapper.  On the Android platform, bypassing the logic below
+** could lead to a corrupt database.
 */
 static int robust_ftruncate(int h, sqlite3_int64 sz){
   int rc;
+#ifdef __ANDROID__
+  /* On Android, ftruncate() always uses 32-bit offsets, even if 
+  ** _FILE_OFFSET_BITS=64 is defined. This means it is unsafe to attempt to
+  ** truncate a file to any size larger than 2GiB. Silently ignore any
+  ** such attempts.  */
+  if( sz>(sqlite3_int64)0x7FFFFFFF ){
+    rc = SQLITE_OK;
+  }else
+#endif
   do{ rc = osFtruncate(h,sz); }while( rc<0 && errno==EINTR );
   return rc;
 }
@@ -25149,7 +26348,7 @@ static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){
 
   assert( zAbsoluteName[0]=='/' );
   n = (int)strlen(zAbsoluteName);
-  pNew = sqlite3_malloc( sizeof(*pNew) + (n+1) );
+  pNew = sqlite3_malloc64( sizeof(*pNew) + (n+1) );
   if( pNew==0 ) return 0;
   pNew->zCanonicalName = (char*)&pNew[1];
   memcpy(pNew->zCanonicalName, zAbsoluteName, n+1);
@@ -25429,6 +26628,14 @@ static void robust_close(unixFile *pFile, int h, int lineno){
 }
 
 /*
+** Set the pFile->lastErrno.  Do this in a subroutine as that provides
+** a convenient place to set a breakpoint.
+*/
+static void storeLastErrno(unixFile *pFile, int error){
+  pFile->lastErrno = error;
+}
+
+/*
 ** Close all file descriptors accumuated in the unixInodeInfo->pUnused list.
 */ 
 static void closePendingFds(unixFile *pFile){
@@ -25501,7 +26708,7 @@ static int findInodeInfo(
   fd = pFile->h;
   rc = osFstat(fd, &statbuf);
   if( rc!=0 ){
-    pFile->lastErrno = errno;
+    storeLastErrno(pFile, errno);
 #ifdef EOVERFLOW
     if( pFile->lastErrno==EOVERFLOW ) return SQLITE_NOLFS;
 #endif
@@ -25522,12 +26729,12 @@ static int findInodeInfo(
   if( statbuf.st_size==0 && (pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS)!=0 ){
     do{ rc = osWrite(fd, "S", 1); }while( rc<0 && errno==EINTR );
     if( rc!=1 ){
-      pFile->lastErrno = errno;
+      storeLastErrno(pFile, errno);
       return SQLITE_IOERR;
     }
     rc = osFstat(fd, &statbuf);
     if( rc!=0 ){
-      pFile->lastErrno = errno;
+      storeLastErrno(pFile, errno);
       return SQLITE_IOERR;
     }
   }
@@ -25545,7 +26752,7 @@ static int findInodeInfo(
     pInode = pInode->pNext;
   }
   if( pInode==0 ){
-    pInode = sqlite3_malloc( sizeof(*pInode) );
+    pInode = sqlite3_malloc64( sizeof(*pInode) );
     if( pInode==0 ){
       return SQLITE_NOMEM;
     }
@@ -25650,7 +26857,7 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
     lock.l_type = F_WRLCK;
     if( osFcntl(pFile->h, F_GETLK, &lock) ){
       rc = SQLITE_IOERR_CHECKRESERVEDLOCK;
-      pFile->lastErrno = errno;
+      storeLastErrno(pFile, errno);
     } else if( lock.l_type!=F_UNLCK ){
       reserved = 1;
     }
@@ -25783,7 +26990,8 @@ static int unixLock(sqlite3_file *id, int eFileLock){
   assert( pFile );
   OSTRACE(("LOCK    %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h,
       azFileLock(eFileLock), azFileLock(pFile->eFileLock),
-      azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared , getpid()));
+      azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared,
+      osGetpid(0)));
 
   /* If there is already a lock of this type or more restrictive on the
   ** unixFile, do nothing. Don't use the end_lock: exit path, as
@@ -25850,7 +27058,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
       tErrno = errno;
       rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
       if( rc!=SQLITE_BUSY ){
-        pFile->lastErrno = tErrno;
+        storeLastErrno(pFile, tErrno);
       }
       goto end_lock;
     }
@@ -25885,7 +27093,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
 
     if( rc ){
       if( rc!=SQLITE_BUSY ){
-        pFile->lastErrno = tErrno;
+        storeLastErrno(pFile, tErrno);
       }
       goto end_lock;
     }else{
@@ -25918,7 +27126,7 @@ static int unixLock(sqlite3_file *id, int eFileLock){
       tErrno = errno;
       rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
       if( rc!=SQLITE_BUSY ){
-        pFile->lastErrno = tErrno;
+        storeLastErrno(pFile, tErrno);
       }
     }
   }
@@ -25991,7 +27199,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
   assert( pFile );
   OSTRACE(("UNLOCK  %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, eFileLock,
       pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared,
-      getpid()));
+      osGetpid(0)));
 
   assert( eFileLock<=SHARED_LOCK );
   if( pFile->eFileLock<=eFileLock ){
@@ -26025,7 +27233,6 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
     **  4:   [RRRR.]
     */
     if( eFileLock==SHARED_LOCK ){
-
 #if !defined(__APPLE__) || !SQLITE_ENABLE_LOCKING_STYLE
       (void)handleNFSUnlock;
       assert( handleNFSUnlock==0 );
@@ -26043,7 +27250,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
           tErrno = errno;
           rc = SQLITE_IOERR_UNLOCK;
           if( IS_LOCK_ERROR(rc) ){
-            pFile->lastErrno = tErrno;
+            storeLastErrno(pFile, tErrno);
           }
           goto end_unlock;
         }
@@ -26055,7 +27262,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
           tErrno = errno;
           rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK);
           if( IS_LOCK_ERROR(rc) ){
-            pFile->lastErrno = tErrno;
+            storeLastErrno(pFile, tErrno);
           }
           goto end_unlock;
         }
@@ -26067,7 +27274,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
           tErrno = errno;
           rc = SQLITE_IOERR_UNLOCK;
           if( IS_LOCK_ERROR(rc) ){
-            pFile->lastErrno = tErrno;
+            storeLastErrno(pFile, tErrno);
           }
           goto end_unlock;
         }
@@ -26086,7 +27293,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
           ** SQLITE_BUSY would confuse the upper layer (in practice it causes 
           ** an assert to fail). */ 
           rc = SQLITE_IOERR_RDLOCK;
-          pFile->lastErrno = errno;
+          storeLastErrno(pFile, errno);
           goto end_unlock;
         }
       }
@@ -26099,7 +27306,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
       pInode->eFileLock = SHARED_LOCK;
     }else{
       rc = SQLITE_IOERR_UNLOCK;
-      pFile->lastErrno = errno;
+      storeLastErrno(pFile, errno);
       goto end_unlock;
     }
   }
@@ -26117,7 +27324,7 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
         pInode->eFileLock = NO_LOCK;
       }else{
         rc = SQLITE_IOERR_UNLOCK;
-        pFile->lastErrno = errno;
+        storeLastErrno(pFile, errno);
         pInode->eFileLock = NO_LOCK;
         pFile->eFileLock = NO_LOCK;
       }
@@ -26392,7 +27599,7 @@ static int dotlockLock(sqlite3_file *id, int eFileLock) {
     } else {
       rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
       if( IS_LOCK_ERROR(rc) ){
-        pFile->lastErrno = tErrno;
+        storeLastErrno(pFile, tErrno);
       }
     }
     return rc;
@@ -26419,7 +27626,7 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
 
   assert( pFile );
   OSTRACE(("UNLOCK  %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock,
-           pFile->eFileLock, getpid()));
+           pFile->eFileLock, osGetpid(0)));
   assert( eFileLock<=SHARED_LOCK );
   
   /* no-op if possible */
@@ -26446,7 +27653,7 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
       rc = SQLITE_IOERR_UNLOCK;
     }
     if( IS_LOCK_ERROR(rc) ){
-      pFile->lastErrno = tErrno;
+      storeLastErrno(pFile, tErrno);
     }
     return rc; 
   }
@@ -26482,10 +27689,9 @@ static int dotlockClose(sqlite3_file *id) {
 ** still works when you do this, but concurrency is reduced since
 ** only a single process can be reading the database at a time.
 **
-** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off or if
-** compiling for VXWORKS.
+** Omit this section if SQLITE_ENABLE_LOCKING_STYLE is turned off
 */
-#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
+#if SQLITE_ENABLE_LOCKING_STYLE
 
 /*
 ** Retry flock() calls that fail with EINTR
@@ -26533,7 +27739,7 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
         /* unlock failed with an error */
         lrc = SQLITE_IOERR_UNLOCK; 
         if( IS_LOCK_ERROR(lrc) ){
-          pFile->lastErrno = tErrno;
+          storeLastErrno(pFile, tErrno);
           rc = lrc;
         }
       }
@@ -26543,7 +27749,7 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
       /* someone else might have it reserved */
       lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); 
       if( IS_LOCK_ERROR(lrc) ){
-        pFile->lastErrno = tErrno;
+        storeLastErrno(pFile, tErrno);
         rc = lrc;
       }
     }
@@ -26609,7 +27815,7 @@ static int flockLock(sqlite3_file *id, int eFileLock) {
     /* didn't get, must be busy */
     rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
     if( IS_LOCK_ERROR(rc) ){
-      pFile->lastErrno = tErrno;
+      storeLastErrno(pFile, tErrno);
     }
   } else {
     /* got it, set the type and return ok */
@@ -26638,7 +27844,7 @@ static int flockUnlock(sqlite3_file *id, int eFileLock) {
   
   assert( pFile );
   OSTRACE(("UNLOCK  %d %d was %d pid=%d (flock)\n", pFile->h, eFileLock,
-           pFile->eFileLock, getpid()));
+           pFile->eFileLock, osGetpid(0)));
   assert( eFileLock<=SHARED_LOCK );
   
   /* no-op if possible */
@@ -26699,7 +27905,7 @@ static int flockClose(sqlite3_file *id) {
 ** to a non-zero value otherwise *pResOut is set to zero.  The return value
 ** is set to SQLITE_OK unless an I/O error occurs during lock checking.
 */
-static int semCheckReservedLock(sqlite3_file *id, int *pResOut) {
+static int semXCheckReservedLock(sqlite3_file *id, int *pResOut) {
   int rc = SQLITE_OK;
   int reserved = 0;
   unixFile *pFile = (unixFile*)id;
@@ -26721,7 +27927,7 @@ static int semCheckReservedLock(sqlite3_file *id, int *pResOut) {
       int tErrno = errno;
       if( EAGAIN != tErrno ){
         rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_CHECKRESERVEDLOCK);
-        pFile->lastErrno = tErrno;
+        storeLastErrno(pFile, tErrno);
       } else {
         /* someone else has the lock when we are in NO_LOCK */
         reserved = (pFile->eFileLock < SHARED_LOCK);
@@ -26766,7 +27972,7 @@ static int semCheckReservedLock(sqlite3_file *id, int *pResOut) {
 ** This routine will only increase a lock.  Use the sqlite3OsUnlock()
 ** routine to lower a locking level.
 */
-static int semLock(sqlite3_file *id, int eFileLock) {
+static int semXLock(sqlite3_file *id, int eFileLock) {
   unixFile *pFile = (unixFile*)id;
   sem_t *pSem = pFile->pInode->pSem;
   int rc = SQLITE_OK;
@@ -26799,14 +28005,14 @@ static int semLock(sqlite3_file *id, int eFileLock) {
 ** If the locking level of the file descriptor is already at or below
 ** the requested locking level, this routine is a no-op.
 */
-static int semUnlock(sqlite3_file *id, int eFileLock) {
+static int semXUnlock(sqlite3_file *id, int eFileLock) {
   unixFile *pFile = (unixFile*)id;
   sem_t *pSem = pFile->pInode->pSem;
 
   assert( pFile );
   assert( pSem );
   OSTRACE(("UNLOCK  %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock,
-           pFile->eFileLock, getpid()));
+           pFile->eFileLock, osGetpid(0)));
   assert( eFileLock<=SHARED_LOCK );
   
   /* no-op if possible */
@@ -26825,7 +28031,7 @@ static int semUnlock(sqlite3_file *id, int eFileLock) {
     int rc, tErrno = errno;
     rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
     if( IS_LOCK_ERROR(rc) ){
-      pFile->lastErrno = tErrno;
+      storeLastErrno(pFile, tErrno);
     }
     return rc; 
   }
@@ -26836,10 +28042,10 @@ static int semUnlock(sqlite3_file *id, int eFileLock) {
 /*
  ** Close a file.
  */
-static int semClose(sqlite3_file *id) {
+static int semXClose(sqlite3_file *id) {
   if( id ){
     unixFile *pFile = (unixFile*)id;
-    semUnlock(id, NO_LOCK);
+    semXUnlock(id, NO_LOCK);
     assert( pFile );
     unixEnterMutex();
     releaseInodeInfo(pFile);
@@ -26927,7 +28133,7 @@ static int afpSetLock(
                     setLockFlag ? SQLITE_IOERR_LOCK : SQLITE_IOERR_UNLOCK);
 #endif /* SQLITE_IGNORE_AFP_LOCK_ERRORS */
     if( IS_LOCK_ERROR(rc) ){
-      pFile->lastErrno = tErrno;
+      storeLastErrno(pFile, tErrno);
     }
     return rc;
   } else {
@@ -27020,7 +28226,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){
   assert( pFile );
   OSTRACE(("LOCK    %d %s was %s(%s,%d) pid=%d (afp)\n", pFile->h,
            azFileLock(eFileLock), azFileLock(pFile->eFileLock),
-           azFileLock(pInode->eFileLock), pInode->nShared , getpid()));
+           azFileLock(pInode->eFileLock), pInode->nShared , osGetpid(0)));
 
   /* If there is already a lock of this type or more restrictive on the
   ** unixFile, do nothing. Don't use the afp_end_lock: exit path, as
@@ -27110,7 +28316,7 @@ static int afpLock(sqlite3_file *id, int eFileLock){
     lrc2 = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0);
     
     if( IS_LOCK_ERROR(lrc1) ) {
-      pFile->lastErrno = lrc1Errno;
+      storeLastErrno(pFile, lrc1Errno);
       rc = lrc1;
       goto afp_end_lock;
     } else if( IS_LOCK_ERROR(lrc2) ){
@@ -27206,7 +28412,7 @@ static int afpUnlock(sqlite3_file *id, int eFileLock) {
   assert( pFile );
   OSTRACE(("UNLOCK  %d %d was %d(%d,%d) pid=%d (afp)\n", pFile->h, eFileLock,
            pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared,
-           getpid()));
+           osGetpid(0)));
 
   assert( eFileLock<=SHARED_LOCK );
   if( pFile->eFileLock<=eFileLock ){
@@ -27369,7 +28575,7 @@ static int nfsUnlock(sqlite3_file *id, int eFileLock){
 ** NB:  If you define USE_PREAD or USE_PREAD64, then it might also
 ** be necessary to define _XOPEN_SOURCE to be 500.  This varies from
 ** one system to another.  Since SQLite does not define USE_PREAD
-** any any form by default, we will not attempt to define _XOPEN_SOURCE.
+** in any form by default, we will not attempt to define _XOPEN_SOURCE.
 ** See tickets #2741 and #2681.
 **
 ** To avoid stomping the errno value on a failed read the lastErrno value
@@ -27397,9 +28603,9 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
     SimulateIOError( newOffset-- );
     if( newOffset!=offset ){
       if( newOffset == -1 ){
-        ((unixFile*)id)->lastErrno = errno;
+        storeLastErrno((unixFile*)id, errno);
       }else{
-        ((unixFile*)id)->lastErrno = 0;
+        storeLastErrno((unixFile*)id, 0);
       }
       return -1;
     }
@@ -27409,7 +28615,7 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){
     if( got<0 ){
       if( errno==EINTR ){ got = 1; continue; }
       prior = 0;
-      ((unixFile*)id)->lastErrno = errno;
+      storeLastErrno((unixFile*)id,  errno);
       break;
     }else if( got>0 ){
       cnt -= got;
@@ -27474,7 +28680,7 @@ static int unixRead(
     /* lastErrno set by seekAndRead */
     return SQLITE_IOERR_READ;
   }else{
-    pFile->lastErrno = 0; /* not a system error */
+    storeLastErrno(pFile, 0);   /* not a system error */
     /* Unread parts of the buffer must be zero-filled */
     memset(&((char*)pBuf)[got], 0, amt-got);
     return SQLITE_IOERR_SHORT_READ;
@@ -27503,9 +28709,9 @@ static int seekAndWriteFd(
   TIMER_START;
 
 #if defined(USE_PREAD)
-  do{ rc = osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR );
+  do{ rc = (int)osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR );
 #elif defined(USE_PREAD64)
-  do{ rc = osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR);
+  do{ rc = (int)osPwrite64(fd, pBuf, nBuf, iOff);}while( rc<0 && errno==EINTR);
 #else
   do{
     i64 iSeek = lseek(fd, iOff, SEEK_SET);
@@ -27615,7 +28821,7 @@ static int unixWrite(
       /* lastErrno set by seekAndWrite */
       return SQLITE_IOERR_WRITE;
     }else{
-      pFile->lastErrno = 0; /* not a system error */
+      storeLastErrno(pFile, 0); /* not a system error */
       return SQLITE_FULL;
     }
   }
@@ -27636,9 +28842,9 @@ SQLITE_API int sqlite3_fullsync_count = 0;
 ** We do not trust systems to provide a working fdatasync().  Some do.
 ** Others do no.  To be safe, we will stick with the (slightly slower)
 ** fsync(). If you know that your system does support fdatasync() correctly,
-** then simply compile with -Dfdatasync=fdatasync
+** then simply compile with -Dfdatasync=fdatasync or -DHAVE_FDATASYNC
 */
-#if !defined(fdatasync)
+#if !defined(fdatasync) && !HAVE_FDATASYNC
 # define fdatasync fsync
 #endif
 
@@ -27824,7 +29030,7 @@ static int unixSync(sqlite3_file *id, int flags){
   rc = full_fsync(pFile->h, isFullsync, isDataOnly);
   SimulateIOError( rc=1 );
   if( rc ){
-    pFile->lastErrno = errno;
+    storeLastErrno(pFile, errno);
     return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath);
   }
 
@@ -27866,9 +29072,9 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){
     nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
   }
 
-  rc = robust_ftruncate(pFile->h, (off_t)nByte);
+  rc = robust_ftruncate(pFile->h, nByte);
   if( rc ){
-    pFile->lastErrno = errno;
+    storeLastErrno(pFile, errno);
     return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
   }else{
 #ifdef SQLITE_DEBUG
@@ -27908,7 +29114,7 @@ static int unixFileSize(sqlite3_file *id, i64 *pSize){
   rc = osFstat(((unixFile*)id)->h, &buf);
   SimulateIOError( rc=1 );
   if( rc!=0 ){
-    ((unixFile*)id)->lastErrno = errno;
+    storeLastErrno((unixFile*)id, errno);
     return SQLITE_IOERR_FSTAT;
   }
   *pSize = buf.st_size;
@@ -27944,7 +29150,9 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
     i64 nSize;                    /* Required file size */
     struct stat buf;              /* Used to hold return values of fstat() */
    
-    if( osFstat(pFile->h, &buf) ) return SQLITE_IOERR_FSTAT;
+    if( osFstat(pFile->h, &buf) ){
+      return SQLITE_IOERR_FSTAT;
+    }
 
     nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk;
     if( nSize>(i64)buf.st_size ){
@@ -27959,24 +29167,28 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
       }while( err==EINTR );
       if( err ) return SQLITE_IOERR_WRITE;
 #else
-      /* If the OS does not have posix_fallocate(), fake it. First use
-      ** ftruncate() to set the file size, then write a single byte to
-      ** the last byte in each block within the extended region. This
-      ** is the same technique used by glibc to implement posix_fallocate()
-      ** on systems that do not have a real fallocate() system call.
+      /* If the OS does not have posix_fallocate(), fake it. Write a 
+      ** single byte to the last byte in each block that falls entirely
+      ** within the extended region. Then, if required, a single byte
+      ** at offset (nSize-1), to set the size of the file correctly.
+      ** This is a similar technique to that used by glibc on systems
+      ** that do not have a real fallocate() call.
       */
       int nBlk = buf.st_blksize;  /* File-system block size */
+      int nWrite = 0;             /* Number of bytes written by seekAndWrite */
       i64 iWrite;                 /* Next offset to write to */
 
-      if( robust_ftruncate(pFile->h, nSize) ){
-        pFile->lastErrno = errno;
-        return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
-      }
       iWrite = ((buf.st_size + 2*nBlk - 1)/nBlk)*nBlk-1;
-      while( iWrite<nSize ){
-        int nWrite = seekAndWrite(pFile, iWrite, "", 1);
+      assert( iWrite>=buf.st_size );
+      assert( (iWrite/nBlk)==((buf.st_size+nBlk-1)/nBlk) );
+      assert( ((iWrite+1)%nBlk)==0 );
+      for(/*no-op*/; iWrite<nSize; iWrite+=nBlk ){
+        nWrite = seekAndWrite(pFile, iWrite, "", 1);
+        if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
+      }
+      if( nWrite==0 || (nSize%nBlk) ){
+        nWrite = seekAndWrite(pFile, nSize-1, "", 1);
         if( nWrite!=1 ) return SQLITE_IOERR_WRITE;
-        iWrite += nBlk;
       }
 #endif
     }
@@ -27987,7 +29199,7 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
     int rc;
     if( pFile->szChunk<=0 ){
       if( robust_ftruncate(pFile->h, nByte) ){
-        pFile->lastErrno = errno;
+        storeLastErrno(pFile, errno);
         return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath);
       }
     }
@@ -28001,7 +29213,7 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){
 }
 
 /*
-** If *pArg is inititially negative then this is a query.  Set *pArg to
+** If *pArg is initially negative then this is a query.  Set *pArg to
 ** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.
 **
 ** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags.
@@ -28025,11 +29237,15 @@ static int unixGetTempname(int nBuf, char *zBuf);
 static int unixFileControl(sqlite3_file *id, int op, void *pArg){
   unixFile *pFile = (unixFile*)id;
   switch( op ){
+    case SQLITE_FCNTL_WAL_BLOCK: {
+      /* pFile->ctrlFlags |= UNIXFILE_BLOCK; // Deferred feature */
+      return SQLITE_OK;
+    }
     case SQLITE_FCNTL_LOCKSTATE: {
       *(int*)pArg = pFile->eFileLock;
       return SQLITE_OK;
     }
-    case SQLITE_LAST_ERRNO: {
+    case SQLITE_FCNTL_LAST_ERRNO: {
       *(int*)pArg = pFile->lastErrno;
       return SQLITE_OK;
     }
@@ -28057,7 +29273,7 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
       return SQLITE_OK;
     }
     case SQLITE_FCNTL_TEMPFILENAME: {
-      char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
+      char *zTFile = sqlite3_malloc64( pFile->pVfs->mxPathname );
       if( zTFile ){
         unixGetTempname(pFile->pVfs->mxPathname, zTFile);
         *(char**)pArg = zTFile;
@@ -28098,8 +29314,8 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
     }
 #endif
 #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
-    case SQLITE_SET_LOCKPROXYFILE:
-    case SQLITE_GET_LOCKPROXYFILE: {
+    case SQLITE_FCNTL_SET_LOCKPROXYFILE:
+    case SQLITE_FCNTL_GET_LOCKPROXYFILE: {
       return proxyFileControl(id,op,pArg);
     }
 #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
@@ -28208,7 +29424,7 @@ static int unixSectorSize(sqlite3_file *id){
 ** Return the device characteristics for the file.
 **
 ** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default.
-** However, that choice is contraversial since technically the underlying
+** However, that choice is controversial since technically the underlying
 ** file system does not always provide powersafe overwrites.  (In other
 ** words, after a power-loss event, parts of the file that were never
 ** written might end up being altered.)  However, non-PSOW behavior is very,
@@ -28239,7 +29455,9 @@ static int unixDeviceCharacteristics(sqlite3_file *id){
 ** Instead, it should be called via macro osGetpagesize().
 */
 static int unixGetpagesize(void){
-#if defined(_BSD_SOURCE)
+#if OS_VXWORKS
+  return 1024;
+#elif defined(_BSD_SOURCE)
   return getpagesize();
 #else
   return (int)sysconf(_SC_PAGESIZE);
@@ -28332,15 +29550,17 @@ struct unixShm {
 ** otherwise.
 */
 static int unixShmSystemLock(
-  unixShmNode *pShmNode, /* Apply locks to this open shared-memory segment */
+  unixFile *pFile,       /* Open connection to the WAL file */
   int lockType,          /* F_UNLCK, F_RDLCK, or F_WRLCK */
   int ofst,              /* First byte of the locking range */
   int n                  /* Number of bytes to lock */
 ){
-  struct flock f;       /* The posix advisory locking structure */
-  int rc = SQLITE_OK;   /* Result code form fcntl() */
+  unixShmNode *pShmNode; /* Apply locks to this open shared-memory segment */
+  struct flock f;        /* The posix advisory locking structure */
+  int rc = SQLITE_OK;    /* Result code form fcntl() */
 
   /* Access to the unixShmNode object is serialized by the caller */
+  pShmNode = pFile->pInode->pShmNode;
   assert( sqlite3_mutex_held(pShmNode->mutex) || pShmNode->nRef==0 );
 
   /* Shared locks never span more than one byte */
@@ -28350,6 +29570,7 @@ static int unixShmSystemLock(
   assert( n>=1 && n<SQLITE_SHM_NLOCK );
 
   if( pShmNode->h>=0 ){
+    int lkType;
     /* Initialize the locking parameters */
     memset(&f, 0, sizeof(f));
     f.l_type = lockType;
@@ -28357,8 +29578,10 @@ static int unixShmSystemLock(
     f.l_start = ofst;
     f.l_len = n;
 
-    rc = osFcntl(pShmNode->h, F_SETLK, &f);
+    lkType = (pFile->ctrlFlags & UNIXFILE_BLOCK)!=0 ? F_SETLKW : F_SETLK;
+    rc = osFcntl(pShmNode->h, lkType, &f);
     rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
+    pFile->ctrlFlags &= ~UNIXFILE_BLOCK;
   }
 
   /* Update the global lock state and do debug tracing */
@@ -28491,7 +29714,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
   int nShmFilename;               /* Size of the SHM filename in bytes */
 
   /* Allocate space for the new unixShm object. */
-  p = sqlite3_malloc( sizeof(*p) );
+  p = sqlite3_malloc64( sizeof(*p) );
   if( p==0 ) return SQLITE_NOMEM;
   memset(p, 0, sizeof(*p));
   assert( pDbFd->pShm==0 );
@@ -28504,6 +29727,9 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
   pShmNode = pInode->pShmNode;
   if( pShmNode==0 ){
     struct stat sStat;                 /* fstat() info for database file */
+#ifndef SQLITE_SHM_DIRECTORY
+    const char *zBasePath = pDbFd->zPath;
+#endif
 
     /* Call fstat() to figure out the permissions on the database file. If
     ** a new *-shm file is created, an attempt will be made to create it
@@ -28517,9 +29743,9 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
 #ifdef SQLITE_SHM_DIRECTORY
     nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31;
 #else
-    nShmFilename = 6 + (int)strlen(pDbFd->zPath);
+    nShmFilename = 6 + (int)strlen(zBasePath);
 #endif
-    pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nShmFilename );
+    pShmNode = sqlite3_malloc64( sizeof(*pShmNode) + nShmFilename );
     if( pShmNode==0 ){
       rc = SQLITE_NOMEM;
       goto shm_open_err;
@@ -28531,7 +29757,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
                      SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x",
                      (u32)sStat.st_ino, (u32)sStat.st_dev);
 #else
-    sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", pDbFd->zPath);
+    sqlite3_snprintf(nShmFilename, zShmFilename, "%s-shm", zBasePath);
     sqlite3FileSuffix3(pDbFd->zPath, zShmFilename);
 #endif
     pShmNode->h = -1;
@@ -28565,13 +29791,13 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
       ** If not, truncate the file to zero length. 
       */
       rc = SQLITE_OK;
-      if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
+      if( unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
         if( robust_ftruncate(pShmNode->h, 0) ){
           rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename);
         }
       }
       if( rc==SQLITE_OK ){
-        rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1);
+        rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1);
       }
       if( rc ) goto shm_open_err;
     }
@@ -28729,7 +29955,7 @@ static int unixShmMap(
           goto shmpage_out;
         }
       }else{
-        pMem = sqlite3_malloc(szRegion);
+        pMem = sqlite3_malloc64(szRegion);
         if( pMem==0 ){
           rc = SQLITE_NOMEM;
           goto shmpage_out;
@@ -28803,7 +30029,7 @@ static int unixShmLock(
 
     /* Unlock the system-level locks */
     if( (mask & allMask)==0 ){
-      rc = unixShmSystemLock(pShmNode, F_UNLCK, ofst+UNIX_SHM_BASE, n);
+      rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n);
     }else{
       rc = SQLITE_OK;
     }
@@ -28831,7 +30057,7 @@ static int unixShmLock(
     /* Get shared locks at the system level, if necessary */
     if( rc==SQLITE_OK ){
       if( (allShared & mask)==0 ){
-        rc = unixShmSystemLock(pShmNode, F_RDLCK, ofst+UNIX_SHM_BASE, n);
+        rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n);
       }else{
         rc = SQLITE_OK;
       }
@@ -28856,7 +30082,7 @@ static int unixShmLock(
     ** also mark the local connection as being locked.
     */
     if( rc==SQLITE_OK ){
-      rc = unixShmSystemLock(pShmNode, F_WRLCK, ofst+UNIX_SHM_BASE, n);
+      rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n);
       if( rc==SQLITE_OK ){
         assert( (p->sharedMask & mask)==0 );
         p->exclMask |= mask;
@@ -28865,7 +30091,7 @@ static int unixShmLock(
   }
   sqlite3_mutex_leave(pShmNode->mutex);
   OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
-           p->id, getpid(), p->sharedMask, p->exclMask));
+           p->id, osGetpid(0), p->sharedMask, p->exclMask));
   return rc;
 }
 
@@ -28924,7 +30150,9 @@ static int unixShmUnmap(
   assert( pShmNode->nRef>0 );
   pShmNode->nRef--;
   if( pShmNode->nRef==0 ){
-    if( deleteFlag && pShmNode->h>=0 ) osUnlink(pShmNode->zFilename);
+    if( deleteFlag && pShmNode->h>=0 ){
+      osUnlink(pShmNode->zFilename);
+    }
     unixShmPurge(pDbFd);
   }
   unixLeaveMutex();
@@ -29180,7 +30408,7 @@ static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){
 ** looks at the filesystem type and tries to guess the best locking
 ** strategy from that.
 **
-** For finder-funtion F, two objects are created:
+** For finder-function F, two objects are created:
 **
 **    (1) The real finder-function named "FImpt()".
 **
@@ -29201,7 +30429,7 @@ static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){
 **   *  An I/O method finder function called FINDER that returns a pointer
 **      to the METHOD object in the previous bullet.
 */
-#define IOMETHODS(FINDER, METHOD, VERSION, CLOSE, LOCK, UNLOCK, CKLOCK)      \
+#define IOMETHODS(FINDER,METHOD,VERSION,CLOSE,LOCK,UNLOCK,CKLOCK,SHMMAP)     \
 static const sqlite3_io_methods METHOD = {                                   \
    VERSION,                    /* iVersion */                                \
    CLOSE,                      /* xClose */                                  \
@@ -29216,7 +30444,7 @@ static const sqlite3_io_methods METHOD = {                                   \
    unixFileControl,            /* xFileControl */                            \
    unixSectorSize,             /* xSectorSize */                             \
    unixDeviceCharacteristics,  /* xDeviceCapabilities */                     \
-   unixShmMap,                 /* xShmMap */                                 \
+   SHMMAP,                     /* xShmMap */                                 \
    unixShmLock,                /* xShmLock */                                \
    unixShmBarrier,             /* xShmBarrier */                             \
    unixShmUnmap,               /* xShmUnmap */                               \
@@ -29242,16 +30470,18 @@ IOMETHODS(
   unixClose,                /* xClose method */
   unixLock,                 /* xLock method */
   unixUnlock,               /* xUnlock method */
-  unixCheckReservedLock     /* xCheckReservedLock method */
+  unixCheckReservedLock,    /* xCheckReservedLock method */
+  unixShmMap                /* xShmMap method */
 )
 IOMETHODS(
   nolockIoFinder,           /* Finder function name */
   nolockIoMethods,          /* sqlite3_io_methods object name */
-  1,                        /* shared memory is disabled */
+  3,                        /* shared memory is disabled */
   nolockClose,              /* xClose method */
   nolockLock,               /* xLock method */
   nolockUnlock,             /* xUnlock method */
-  nolockCheckReservedLock   /* xCheckReservedLock method */
+  nolockCheckReservedLock,  /* xCheckReservedLock method */
+  0                         /* xShmMap method */
 )
 IOMETHODS(
   dotlockIoFinder,          /* Finder function name */
@@ -29260,10 +30490,11 @@ IOMETHODS(
   dotlockClose,             /* xClose method */
   dotlockLock,              /* xLock method */
   dotlockUnlock,            /* xUnlock method */
-  dotlockCheckReservedLock  /* xCheckReservedLock method */
+  dotlockCheckReservedLock, /* xCheckReservedLock method */
+  0                         /* xShmMap method */
 )
 
-#if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS
+#if SQLITE_ENABLE_LOCKING_STYLE
 IOMETHODS(
   flockIoFinder,            /* Finder function name */
   flockIoMethods,           /* sqlite3_io_methods object name */
@@ -29271,7 +30502,8 @@ IOMETHODS(
   flockClose,               /* xClose method */
   flockLock,                /* xLock method */
   flockUnlock,              /* xUnlock method */
-  flockCheckReservedLock    /* xCheckReservedLock method */
+  flockCheckReservedLock,   /* xCheckReservedLock method */
+  0                         /* xShmMap method */
 )
 #endif
 
@@ -29280,10 +30512,11 @@ IOMETHODS(
   semIoFinder,              /* Finder function name */
   semIoMethods,             /* sqlite3_io_methods object name */
   1,                        /* shared memory is disabled */
-  semClose,                 /* xClose method */
-  semLock,                  /* xLock method */
-  semUnlock,                /* xUnlock method */
-  semCheckReservedLock      /* xCheckReservedLock method */
+  semXClose,                /* xClose method */
+  semXLock,                 /* xLock method */
+  semXUnlock,               /* xUnlock method */
+  semXCheckReservedLock,    /* xCheckReservedLock method */
+  0                         /* xShmMap method */
 )
 #endif
 
@@ -29295,7 +30528,8 @@ IOMETHODS(
   afpClose,                 /* xClose method */
   afpLock,                  /* xLock method */
   afpUnlock,                /* xUnlock method */
-  afpCheckReservedLock      /* xCheckReservedLock method */
+  afpCheckReservedLock,     /* xCheckReservedLock method */
+  0                         /* xShmMap method */
 )
 #endif
 
@@ -29320,7 +30554,8 @@ IOMETHODS(
   proxyClose,               /* xClose method */
   proxyLock,                /* xLock method */
   proxyUnlock,              /* xUnlock method */
-  proxyCheckReservedLock    /* xCheckReservedLock method */
+  proxyCheckReservedLock,   /* xCheckReservedLock method */
+  0                         /* xShmMap method */
 )
 #endif
 
@@ -29333,7 +30568,8 @@ IOMETHODS(
   unixClose,                 /* xClose method */
   unixLock,                  /* xLock method */
   nfsUnlock,                 /* xUnlock method */
-  unixCheckReservedLock      /* xCheckReservedLock method */
+  unixCheckReservedLock,     /* xCheckReservedLock method */
+  0                          /* xShmMap method */
 )
 #endif
 
@@ -29403,15 +30639,13 @@ static const sqlite3_io_methods
 
 #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
 
-#if OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE
-/* 
-** This "finder" function attempts to determine the best locking strategy 
-** for the database file "filePath".  It then returns the sqlite3_io_methods
-** object that implements that strategy.
-**
-** This is for VXWorks only.
+#if OS_VXWORKS
+/*
+** This "finder" function for VxWorks checks to see if posix advisory
+** locking works.  If it does, then that is what is used.  If it does not
+** work, then fallback to named semaphore locking.
 */
-static const sqlite3_io_methods *autolockIoFinderImpl(
+static const sqlite3_io_methods *vxworksIoFinderImpl(
   const char *filePath,    /* name of the database file */
   unixFile *pNew           /* the open file object */
 ){
@@ -29437,12 +30671,12 @@ static const sqlite3_io_methods *autolockIoFinderImpl(
   }
 }
 static const sqlite3_io_methods 
-  *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl;
+  *(*const vxworksIoFinder)(const char*,unixFile*) = vxworksIoFinderImpl;
 
-#endif /* OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE */
+#endif /* OS_VXWORKS */
 
 /*
-** An abstract type for a pointer to a IO method finder function:
+** An abstract type for a pointer to an IO method finder function:
 */
 typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*);
 
@@ -29558,7 +30792,7 @@ static int fillInUnixFile(
     ** the afpLockingContext.
     */
     afpLockingContext *pCtx;
-    pNew->lockingContext = pCtx = sqlite3_malloc( sizeof(*pCtx) );
+    pNew->lockingContext = pCtx = sqlite3_malloc64( sizeof(*pCtx) );
     if( pCtx==0 ){
       rc = SQLITE_NOMEM;
     }else{
@@ -29588,7 +30822,7 @@ static int fillInUnixFile(
     int nFilename;
     assert( zFilename!=0 );
     nFilename = (int)strlen(zFilename) + 6;
-    zLockFile = (char *)sqlite3_malloc(nFilename);
+    zLockFile = (char *)sqlite3_malloc64(nFilename);
     if( zLockFile==0 ){
       rc = SQLITE_NOMEM;
     }else{
@@ -29621,7 +30855,7 @@ static int fillInUnixFile(
   }
 #endif
   
-  pNew->lastErrno = 0;
+  storeLastErrno(pNew, 0);
 #if OS_VXWORKS
   if( rc!=SQLITE_OK ){
     if( h>=0 ) robust_close(pNew, h, __LINE__);
@@ -29756,7 +30990,7 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
   ** descriptor on the same path, fail, and return an error to SQLite.
   **
   ** Even if a subsequent open() call does succeed, the consequences of
-  ** not searching for a resusable file descriptor are not dire.  */
+  ** not searching for a reusable file descriptor are not dire.  */
   if( 0==osStat(zPath, &sStat) ){
     unixInodeInfo *pInode;
 
@@ -29787,7 +31021,7 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
 ** written to *pMode. If an IO error occurs, an SQLite error code is 
 ** returned and the value of *pMode is not modified.
 **
-** In most cases cases, this routine sets *pMode to 0, which will become
+** In most cases, this routine sets *pMode to 0, which will become
 ** an indication to robust_open() to create the file using
 ** SQLITE_DEFAULT_FILE_PERMISSIONS adjusted by the umask.
 ** But if the file being opened is a WAL or regular journal file, then 
@@ -29952,8 +31186,8 @@ static int unixOpen(
   ** the same instant might all reset the PRNG.  But multiple resets
   ** are harmless.
   */
-  if( randomnessPid!=getpid() ){
-    randomnessPid = getpid();
+  if( randomnessPid!=osGetpid(0) ){
+    randomnessPid = osGetpid(0);
     sqlite3_randomness(0,0);
   }
 
@@ -29965,7 +31199,7 @@ static int unixOpen(
     if( pUnused ){
       fd = pUnused->fd;
     }else{
-      pUnused = sqlite3_malloc(sizeof(*pUnused));
+      pUnused = sqlite3_malloc64(sizeof(*pUnused));
       if( !pUnused ){
         return SQLITE_NOMEM;
       }
@@ -30069,13 +31303,16 @@ static int unixOpen(
   
 #if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE
   if( fstatfs(fd, &fsInfo) == -1 ){
-    ((unixFile*)pFile)->lastErrno = errno;
+    storeLastErrno(p, errno);
     robust_close(p, fd, __LINE__);
     return SQLITE_IOERR_ACCESS;
   }
   if (0 == strncmp("msdos", fsInfo.f_fstypename, 5)) {
     ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS;
   }
+  if (0 == strncmp("exfat", fsInfo.f_fstypename, 5)) {
+    ((unixFile*)pFile)->fsFlags |= SQLITE_FSFLAGS_IS_MSDOS;
+  }
 #endif
 
   /* Set up appropriate ctrlFlags */
@@ -30098,19 +31335,6 @@ static int unixOpen(
     if( envforce!=NULL ){
       useProxy = atoi(envforce)>0;
     }else{
-      if( statfs(zPath, &fsInfo) == -1 ){
-        /* In theory, the close(fd) call is sub-optimal. If the file opened
-        ** with fd is a database file, and there are other connections open
-        ** on that file that are currently holding advisory locks on it,
-        ** then the call to close() will cancel those locks. In practice,
-        ** we're assuming that statfs() doesn't fail very often. At least
-        ** not while other file descriptors opened by the same process on
-        ** the same file are working.  */
-        p->lastErrno = errno;
-        robust_close(p, fd, __LINE__);
-        rc = SQLITE_IOERR_ACCESS;
-        goto open_finished;
-      }
       useProxy = !(fsInfo.f_flags&MNT_LOCAL);
     }
     if( useProxy ){
@@ -30156,7 +31380,7 @@ static int unixDelete(
   if( osUnlink(zPath)==(-1) ){
     if( errno==ENOENT
 #if OS_VXWORKS
-        || errno==0x380003
+        || osAccess(zPath,0)!=0
 #endif
     ){
       rc = SQLITE_IOERR_DELETE_NOENT;
@@ -30354,8 +31578,8 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){
   ** tests repeatable.
   */
   memset(zBuf, 0, nBuf);
-  randomnessPid = getpid();  
-#if !defined(SQLITE_TEST)
+  randomnessPid = osGetpid(0);  
+#if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS)
   {
     int fd, got;
     fd = robust_open("/dev/urandom", O_RDONLY, 0);
@@ -30536,9 +31760,10 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
 **
 ** C APIs
 **
-**  sqlite3_file_control(db, dbname, SQLITE_SET_LOCKPROXYFILE,
+**  sqlite3_file_control(db, dbname, SQLITE_FCNTL_SET_LOCKPROXYFILE,
 **                       <proxy_path> | ":auto:");
-**  sqlite3_file_control(db, dbname, SQLITE_GET_LOCKPROXYFILE, &<proxy_path>);
+**  sqlite3_file_control(db, dbname, SQLITE_FCNTL_GET_LOCKPROXYFILE,
+**                       &<proxy_path>);
 **
 **
 ** SQL pragmas
@@ -30579,7 +31804,7 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
 ** proxy path against the values stored in the conch.  The conch file is
 ** stored in the same directory as the database file and the file name
 ** is patterned after the database file name as ".<databasename>-conch".
-** If the conch file does not exist, or it's contents do not match the
+** If the conch file does not exist, or its contents do not match the
 ** host ID and/or proxy path, then the lock is escalated to an exclusive
 ** lock and the conch file contents is updated with the host ID and proxy
 ** path and the lock is downgraded to a shared lock again.  If the conch
@@ -30631,7 +31856,7 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
 ** setting the environment variable SQLITE_FORCE_PROXY_LOCKING to 1 will
 ** force proxy locking to be used for every database file opened, and 0
 ** will force automatic proxy locking to be disabled for all database
-** files (explicity calling the SQLITE_SET_LOCKPROXYFILE pragma or
+** files (explicitly calling the SQLITE_FCNTL_SET_LOCKPROXYFILE pragma or
 ** sqlite_file_control API is not affected by SQLITE_FORCE_PROXY_LOCKING).
 */
 
@@ -30652,6 +31877,7 @@ struct proxyLockingContext {
   char *lockProxyPath;         /* Name of the proxy lock file */
   char *dbPath;                /* Name of the open file */
   int conchHeld;               /* 1 if the conch is held, -1 if lockless */
+  int nFails;                  /* Number of conch taking failures */
   void *oldLockingContext;     /* Original lockingcontext to restore on close */
   sqlite3_io_methods const *pOldMethod;     /* Original I/O methods for close */
 };
@@ -30673,7 +31899,7 @@ static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){
   {
     if( !confstr(_CS_DARWIN_USER_TEMP_DIR, lPath, maxLen) ){
       OSTRACE(("GETLOCKPATH  failed %s errno=%d pid=%d\n",
-               lPath, errno, getpid()));
+               lPath, errno, osGetpid(0)));
       return SQLITE_IOERR_LOCK;
     }
     len = strlcat(lPath, "sqliteplocks", maxLen);    
@@ -30695,7 +31921,7 @@ static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){
   }
   lPath[i+len]='\0';
   strlcat(lPath, ":auto:", maxLen);
-  OSTRACE(("GETLOCKPATH  proxy lock path=%s pid=%d\n", lPath, getpid()));
+  OSTRACE(("GETLOCKPATH  proxy lock path=%s pid=%d\n", lPath, osGetpid(0)));
   return SQLITE_OK;
 }
 
@@ -30722,7 +31948,7 @@ static int proxyCreateLockPath(const char *lockPath){
           if( err!=EEXIST ) {
             OSTRACE(("CREATELOCKPATH  FAILED creating %s, "
                      "'%s' proxy lock path=%s pid=%d\n",
-                     buf, strerror(err), lockPath, getpid()));
+                     buf, strerror(err), lockPath, osGetpid(0)));
             return err;
           }
         }
@@ -30731,7 +31957,7 @@ static int proxyCreateLockPath(const char *lockPath){
     }
     buf[i] = lockPath[i];
   }
-  OSTRACE(("CREATELOCKPATH  proxy lock path=%s pid=%d\n", lockPath, getpid()));
+  OSTRACE(("CREATELOCKPATH  proxy lock path=%s pid=%d\n", lockPath, osGetpid(0)));
   return 0;
 }
 
@@ -30765,7 +31991,7 @@ static int proxyCreateUnixFile(
   if( pUnused ){
     fd = pUnused->fd;
   }else{
-    pUnused = sqlite3_malloc(sizeof(*pUnused));
+    pUnused = sqlite3_malloc64(sizeof(*pUnused));
     if( !pUnused ){
       return SQLITE_NOMEM;
     }
@@ -30798,7 +32024,7 @@ static int proxyCreateUnixFile(
     }
   }
   
-  pNew = (unixFile *)sqlite3_malloc(sizeof(*pNew));
+  pNew = (unixFile *)sqlite3_malloc64(sizeof(*pNew));
   if( pNew==NULL ){
     rc = SQLITE_NOMEM;
     goto end_create_proxy;
@@ -30831,8 +32057,10 @@ SQLITE_API int sqlite3_hostid_num = 0;
 
 #define PROXY_HOSTIDLEN    16  /* conch file host id length */
 
+#ifdef HAVE_GETHOSTUUID
 /* Not always defined in the headers as it ought to be */
 extern int gethostuuid(uuid_t id, const struct timespec *wait);
+#endif
 
 /* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN 
 ** bytes of writable memory.
@@ -30840,10 +32068,9 @@ extern int gethostuuid(uuid_t id, const struct timespec *wait);
 static int proxyGetHostID(unsigned char *pHostID, int *pError){
   assert(PROXY_HOSTIDLEN == sizeof(uuid_t));
   memset(pHostID, 0, PROXY_HOSTIDLEN);
-#if defined(__MAX_OS_X_VERSION_MIN_REQUIRED)\
-               && __MAC_OS_X_VERSION_MIN_REQUIRED<1050
+#ifdef HAVE_GETHOSTUUID
   {
-    static const struct timespec timeout = {1, 0}; /* 1 sec timeout */
+    struct timespec timeout = {1, 0}; /* 1 sec timeout */
     if( gethostuuid(pHostID, &timeout) ){
       int err = errno;
       if( pError ){
@@ -30958,7 +32185,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
        */
       struct stat buf;
       if( osFstat(conchFile->h, &buf) ){
-        pFile->lastErrno = errno;
+        storeLastErrno(pFile, errno);
         return SQLITE_IOERR_LOCK;
       }
       
@@ -30978,7 +32205,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
         char tBuf[PROXY_MAXCONCHLEN];
         int len = osPread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0);
         if( len<0 ){
-          pFile->lastErrno = errno;
+          storeLastErrno(pFile, errno);
           return SQLITE_IOERR_LOCK;
         }
         if( len>PROXY_PATHINDEX && tBuf[0]==(char)PROXY_CONCHVERSION){
@@ -30998,7 +32225,7 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){
       if( 0==proxyBreakConchLock(pFile, myHostID) ){
         rc = SQLITE_OK;
         if( lockType==EXCLUSIVE_LOCK ){
-          rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK);          
+          rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK);
         }
         if( !rc ){
           rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType);
@@ -31036,11 +32263,12 @@ static int proxyTakeConch(unixFile *pFile){
     int forceNewLockPath = 0;
     
     OSTRACE(("TAKECONCH  %d for %s pid=%d\n", conchFile->h,
-             (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), getpid()));
+             (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"),
+             osGetpid(0)));
 
     rc = proxyGetHostID(myHostID, &pError);
     if( (rc&0xff)==SQLITE_IOERR ){
-      pFile->lastErrno = pError;
+      storeLastErrno(pFile, pError);
       goto end_takeconch;
     }
     rc = proxyConchLock(pFile, myHostID, SHARED_LOCK);
@@ -31051,7 +32279,7 @@ static int proxyTakeConch(unixFile *pFile){
     readLen = seekAndRead((unixFile*)conchFile, 0, readBuf, PROXY_MAXCONCHLEN);
     if( readLen<0 ){
       /* I/O error: lastErrno set by seekAndRead */
-      pFile->lastErrno = conchFile->lastErrno;
+      storeLastErrno(pFile, conchFile->lastErrno);
       rc = SQLITE_IOERR_READ;
       goto end_takeconch;
     }else if( readLen<=(PROXY_HEADERLEN+PROXY_HOSTIDLEN) || 
@@ -31124,7 +32352,7 @@ static int proxyTakeConch(unixFile *pFile){
           rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK);
         }
       }else{
-        rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, EXCLUSIVE_LOCK);
+        rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK);
       }
       if( rc==SQLITE_OK ){
         char writeBuffer[PROXY_MAXCONCHLEN];
@@ -31133,7 +32361,8 @@ static int proxyTakeConch(unixFile *pFile){
         writeBuffer[0] = (char)PROXY_CONCHVERSION;
         memcpy(&writeBuffer[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN);
         if( pCtx->lockProxyPath!=NULL ){
-          strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath, MAXPATHLEN);
+          strlcpy(&writeBuffer[PROXY_PATHINDEX], pCtx->lockProxyPath,
+                  MAXPATHLEN);
         }else{
           strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAXPATHLEN);
         }
@@ -31245,7 +32474,7 @@ static int proxyReleaseConch(unixFile *pFile){
   conchFile = pCtx->conchFile;
   OSTRACE(("RELEASECONCH  %d for %s pid=%d\n", conchFile->h,
            (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), 
-           getpid()));
+           osGetpid(0)));
   if( pCtx->conchHeld>0 ){
     rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK);
   }
@@ -31257,7 +32486,7 @@ static int proxyReleaseConch(unixFile *pFile){
 
 /*
 ** Given the name of a database file, compute the name of its conch file.
-** Store the conch filename in memory obtained from sqlite3_malloc().
+** Store the conch filename in memory obtained from sqlite3_malloc64().
 ** Make *pConchPath point to the new name.  Return SQLITE_OK on success
 ** or SQLITE_NOMEM if unable to obtain memory.
 **
@@ -31273,7 +32502,7 @@ static int proxyCreateConchPathname(char *dbPath, char **pConchPath){
 
   /* Allocate space for the conch filename and initialize the name to
   ** the name of the original database file. */  
-  *pConchPath = conchPath = (char *)sqlite3_malloc(len + 8);
+  *pConchPath = conchPath = (char *)sqlite3_malloc64(len + 8);
   if( conchPath==0 ){
     return SQLITE_NOMEM;
   }
@@ -31345,7 +32574,8 @@ static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){
     /* afp style keeps a reference to the db path in the filePath field 
     ** of the struct */
     assert( (int)strlen((char*)pFile->lockingContext)<=MAXPATHLEN );
-    strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath, MAXPATHLEN);
+    strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath,
+            MAXPATHLEN);
   } else
 #endif
   if( pFile->pMethod == &dotlockIoMethods ){
@@ -31386,9 +32616,9 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
   }
   
   OSTRACE(("TRANSPROXY  %d for %s pid=%d\n", pFile->h,
-           (lockPath ? lockPath : ":auto:"), getpid()));
+           (lockPath ? lockPath : ":auto:"), osGetpid(0)));
 
-  pCtx = sqlite3_malloc( sizeof(*pCtx) );
+  pCtx = sqlite3_malloc64( sizeof(*pCtx) );
   if( pCtx==0 ){
     return SQLITE_NOMEM;
   }
@@ -31458,7 +32688,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
 */
 static int proxyFileControl(sqlite3_file *id, int op, void *pArg){
   switch( op ){
-    case SQLITE_GET_LOCKPROXYFILE: {
+    case SQLITE_FCNTL_GET_LOCKPROXYFILE: {
       unixFile *pFile = (unixFile*)id;
       if( pFile->pMethod == &proxyIoMethods ){
         proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext;
@@ -31473,13 +32703,16 @@ static int proxyFileControl(sqlite3_file *id, int op, void *pArg){
       }
       return SQLITE_OK;
     }
-    case SQLITE_SET_LOCKPROXYFILE: {
+    case SQLITE_FCNTL_SET_LOCKPROXYFILE: {
       unixFile *pFile = (unixFile*)id;
       int rc = SQLITE_OK;
       int isProxyStyle = (pFile->pMethod == &proxyIoMethods);
       if( pArg==NULL || (const char *)pArg==0 ){
         if( isProxyStyle ){
-          /* turn off proxy locking - not supported */
+          /* turn off proxy locking - not supported.  If support is added for
+          ** switching proxy locking mode off then it will need to fail if
+          ** the journal mode is WAL mode. 
+          */
           rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/;
         }else{
           /* turn off proxy locking - already off - NOOP */
@@ -31670,7 +32903,7 @@ static int proxyClose(sqlite3_file *id) {
 ** necessarily been initialized when this routine is called, and so they
 ** should not be used.
 */
-SQLITE_API int sqlite3_os_init(void){ 
+SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){ 
   /* 
   ** The following macro defines an initializer for an sqlite3_vfs object.
   ** The name of the VFS is NAME.  The pAppData is a pointer to a pointer
@@ -31724,8 +32957,10 @@ SQLITE_API int sqlite3_os_init(void){
   ** array cannot be const.
   */
   static sqlite3_vfs aVfs[] = {
-#if SQLITE_ENABLE_LOCKING_STYLE && (OS_VXWORKS || defined(__APPLE__))
+#if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
     UNIXVFS("unix",          autolockIoFinder ),
+#elif OS_VXWORKS
+    UNIXVFS("unix",          vxworksIoFinder ),
 #else
     UNIXVFS("unix",          posixIoFinder ),
 #endif
@@ -31735,11 +32970,11 @@ SQLITE_API int sqlite3_os_init(void){
 #if OS_VXWORKS
     UNIXVFS("unix-namedsem", semIoFinder ),
 #endif
-#if SQLITE_ENABLE_LOCKING_STYLE
+#if SQLITE_ENABLE_LOCKING_STYLE || OS_VXWORKS
     UNIXVFS("unix-posix",    posixIoFinder ),
-#if !OS_VXWORKS
-    UNIXVFS("unix-flock",    flockIoFinder ),
 #endif
+#if SQLITE_ENABLE_LOCKING_STYLE
+    UNIXVFS("unix-flock",    flockIoFinder ),
 #endif
 #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__)
     UNIXVFS("unix-afp",      afpIoFinder ),
@@ -31767,7 +33002,7 @@ SQLITE_API int sqlite3_os_init(void){
 ** to release dynamically allocated objects.  But not on unix.
 ** This routine is a no-op for unix.
 */
-SQLITE_API int sqlite3_os_end(void){ 
+SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void){ 
   return SQLITE_OK; 
 }
  
@@ -31827,16 +33062,6 @@ SQLITE_API int sqlite3_os_end(void){
 # error "The MEMORY_DEBUG macro is obsolete.  Use SQLITE_DEBUG instead."
 #endif
 
-#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
-# ifndef SQLITE_DEBUG_OS_TRACE
-#   define SQLITE_DEBUG_OS_TRACE 0
-# endif
-  int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE;
-# define OSTRACE(X)          if( sqlite3OSTrace ) sqlite3DebugPrintf X
-#else
-# define OSTRACE(X)
-#endif
-
 /*
 ** Macros for performance tracing.  Normally turned off.  Only works
 ** on i486 hardware.
@@ -32017,6 +33242,11 @@ SQLITE_API int sqlite3_open_file_count = 0;
  with SQLITE_OMIT_WAL."
 #endif
 
+#if !SQLITE_OS_WINNT && SQLITE_MAX_MMAP_SIZE>0
+#  error "Memory mapped files require support from the Windows NT kernel,\
+ compile with SQLITE_MAX_MMAP_SIZE=0."
+#endif
+
 /*
 ** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions
 ** based on the sub-platform)?
@@ -32146,10 +33376,11 @@ SQLITE_API int sqlite3_open_file_count = 0;
 
 /*
 ** Do we need to manually define the Win32 file mapping APIs for use with WAL
-** mode (e.g. these APIs are available in the Windows CE SDK; however, they
-** are not present in the header file)?
+** mode or memory mapped files (e.g. these APIs are available in the Windows
+** CE SDK; however, they are not present in the header file)?
 */
-#if SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL)
+#if SQLITE_WIN32_FILEMAPPING_API && \
+        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
 /*
 ** Two of the file mapping APIs are different under WinRT.  Figure out which
 ** set we need.
@@ -32174,10 +33405,12 @@ WINBASEAPI LPVOID WINAPI MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, SIZE_T);
 #endif /* SQLITE_OS_WINRT */
 
 /*
-** This file mapping API is common to both Win32 and WinRT.
+** These file mapping APIs are common to both Win32 and WinRT.
 */
+
+WINBASEAPI BOOL WINAPI FlushViewOfFile(LPCVOID, SIZE_T);
 WINBASEAPI BOOL WINAPI UnmapViewOfFile(LPCVOID);
-#endif /* SQLITE_WIN32_FILEMAPPING_API && !defined(SQLITE_OMIT_WAL) */
+#endif /* SQLITE_WIN32_FILEMAPPING_API */
 
 /*
 ** Some Microsoft compilers lack this definition.
@@ -32393,9 +33626,9 @@ SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void);
 ** can manually set this value to 1 to emulate Win98 behavior.
 */
 #ifdef SQLITE_TEST
-SQLITE_API LONG volatile sqlite3_os_type = 0;
+SQLITE_API LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0;
 #else
-static LONG volatile sqlite3_os_type = 0;
+static LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0;
 #endif
 
 #ifndef SYSCALL
@@ -32470,7 +33703,7 @@ static struct win_syscall {
         LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
 
 #if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
-        !defined(SQLITE_OMIT_WAL))
+        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
   { "CreateFileMappingA",      (SYSCALL)CreateFileMappingA,      0 },
 #else
   { "CreateFileMappingA",      (SYSCALL)0,                       0 },
@@ -32480,7 +33713,7 @@ static struct win_syscall {
         DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent)
 
 #if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
-        !defined(SQLITE_OMIT_WAL))
+        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
   { "CreateFileMappingW",      (SYSCALL)CreateFileMappingW,      0 },
 #else
   { "CreateFileMappingW",      (SYSCALL)0,                       0 },
@@ -32820,7 +34053,8 @@ static struct win_syscall {
         LPOVERLAPPED))aSyscall[48].pCurrent)
 #endif
 
-#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL))
+#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && \
+        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
   { "MapViewOfFile",           (SYSCALL)MapViewOfFile,           0 },
 #else
   { "MapViewOfFile",           (SYSCALL)0,                       0 },
@@ -32890,7 +34124,7 @@ static struct win_syscall {
 #define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
         LPOVERLAPPED))aSyscall[58].pCurrent)
 
-#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL)
+#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
   { "UnmapViewOfFile",         (SYSCALL)UnmapViewOfFile,         0 },
 #else
   { "UnmapViewOfFile",         (SYSCALL)0,                       0 },
@@ -32926,7 +34160,7 @@ static struct win_syscall {
 #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
         DWORD))aSyscall[63].pCurrent)
 
-#if SQLITE_OS_WINRT
+#if !SQLITE_OS_WINCE
   { "WaitForSingleObjectEx",   (SYSCALL)WaitForSingleObjectEx,   0 },
 #else
   { "WaitForSingleObjectEx",   (SYSCALL)0,                       0 },
@@ -32953,7 +34187,7 @@ static struct win_syscall {
 #define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
         FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent)
 
-#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
+#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
   { "MapViewOfFileFromApp",    (SYSCALL)MapViewOfFileFromApp,    0 },
 #else
   { "MapViewOfFileFromApp",    (SYSCALL)0,                       0 },
@@ -33017,7 +34251,7 @@ static struct win_syscall {
 
 #define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[74].pCurrent)
 
-#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)
+#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
   { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
 #else
   { "CreateFileMappingFromApp", (SYSCALL)0,                      0 },
@@ -33038,10 +34272,36 @@ static struct win_syscall {
 #else
   { "InterlockedCompareExchange", (SYSCALL)InterlockedCompareExchange, 0 },
 
-#define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG volatile*, \
-        LONG,LONG))aSyscall[76].pCurrent)
+#define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG \
+        SQLITE_WIN32_VOLATILE*, LONG,LONG))aSyscall[76].pCurrent)
 #endif /* defined(InterlockedCompareExchange) */
 
+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
+  { "UuidCreate",               (SYSCALL)UuidCreate,             0 },
+#else
+  { "UuidCreate",               (SYSCALL)0,                      0 },
+#endif
+
+#define osUuidCreate ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[77].pCurrent)
+
+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
+  { "UuidCreateSequential",     (SYSCALL)UuidCreateSequential,   0 },
+#else
+  { "UuidCreateSequential",     (SYSCALL)0,                      0 },
+#endif
+
+#define osUuidCreateSequential \
+        ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[78].pCurrent)
+
+#if !defined(SQLITE_NO_SYNC) && SQLITE_MAX_MMAP_SIZE>0
+  { "FlushViewOfFile",          (SYSCALL)FlushViewOfFile,        0 },
+#else
+  { "FlushViewOfFile",          (SYSCALL)0,                      0 },
+#endif
+
+#define osFlushViewOfFile \
+        ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent)
+
 }; /* End of the overrideable system calls */
 
 /*
@@ -33135,7 +34395,7 @@ static const char *winNextSystemCall(sqlite3_vfs *p, const char *zName){
 ** "pnLargest" argument, if non-zero, will be used to return the size of the
 ** largest committed free block in the heap, in bytes.
 */
-SQLITE_API int sqlite3_win32_compact_heap(LPUINT pnLargest){
+SQLITE_API int SQLITE_STDCALL sqlite3_win32_compact_heap(LPUINT pnLargest){
   int rc = SQLITE_OK;
   UINT nLargest = 0;
   HANDLE hHeap;
@@ -33175,12 +34435,12 @@ SQLITE_API int sqlite3_win32_compact_heap(LPUINT pnLargest){
 ** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will
 ** be returned and no changes will be made to the Win32 native heap.
 */
-SQLITE_API int sqlite3_win32_reset_heap(){
+SQLITE_API int SQLITE_STDCALL sqlite3_win32_reset_heap(){
   int rc;
   MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
   MUTEX_LOGIC( sqlite3_mutex *pMem; )    /* The memsys static mutex */
-  MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
-  MUTEX_LOGIC( pMem = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); )
+  MUTEX_LOGIC( pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); )
+  MUTEX_LOGIC( pMem = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); )
   sqlite3_mutex_enter(pMaster);
   sqlite3_mutex_enter(pMem);
   winMemAssertMagic();
@@ -33220,7 +34480,7 @@ SQLITE_API int sqlite3_win32_reset_heap(){
 ** (if available).
 */
 
-SQLITE_API void sqlite3_win32_write_debug(const char *zBuf, int nBuf){
+SQLITE_API void SQLITE_STDCALL sqlite3_win32_write_debug(const char *zBuf, int nBuf){
   char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE];
   int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */
   if( nMin<-1 ) nMin = -1; /* all negative values become -1. */
@@ -33260,7 +34520,7 @@ SQLITE_API void sqlite3_win32_write_debug(const char *zBuf, int nBuf){
 static HANDLE sleepObj = NULL;
 #endif
 
-SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){
+SQLITE_API void SQLITE_STDCALL sqlite3_win32_sleep(DWORD milliseconds){
 #if SQLITE_OS_WINRT
   if ( sleepObj==NULL ){
     sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET,
@@ -33273,6 +34533,16 @@ SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){
 #endif
 }
 
+#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \
+        SQLITE_THREADSAFE>0
+SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){
+  DWORD rc;
+  while( (rc = osWaitForSingleObjectEx(hObject, INFINITE,
+                                       TRUE))==WAIT_IO_COMPLETION ){}
+  return rc;
+}
+#endif
+
 /*
 ** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
 ** or WinCE.  Return false (zero) for Win95, Win98, or WinME.
@@ -33299,20 +34569,25 @@ SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){
 ** This function determines if the machine is running a version of Windows
 ** based on the NT kernel.
 */
-SQLITE_API int sqlite3_win32_is_nt(void){
-#if defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX
+SQLITE_API int SQLITE_STDCALL sqlite3_win32_is_nt(void){
+#if SQLITE_OS_WINRT
+  /*
+  ** NOTE: The WinRT sub-platform is always assumed to be based on the NT
+  **       kernel.
+  */
+  return 1;
+#elif defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX
   if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){
-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
-        defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WIN8
-    OSVERSIONINFOW sInfo;
+#if defined(SQLITE_WIN32_HAS_ANSI)
+    OSVERSIONINFOA sInfo;
     sInfo.dwOSVersionInfoSize = sizeof(sInfo);
-    osGetVersionExW(&sInfo);
+    osGetVersionExA(&sInfo);
     osInterlockedCompareExchange(&sqlite3_os_type,
         (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0);
-#elif defined(SQLITE_WIN32_HAS_ANSI)
-    OSVERSIONINFOA sInfo;
+#elif defined(SQLITE_WIN32_HAS_WIDE)
+    OSVERSIONINFOW sInfo;
     sInfo.dwOSVersionInfoSize = sizeof(sInfo);
-    osGetVersionExA(&sInfo);
+    osGetVersionExW(&sInfo);
     osInterlockedCompareExchange(&sqlite3_os_type,
         (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0);
 #endif
@@ -33321,6 +34596,10 @@ SQLITE_API int sqlite3_win32_is_nt(void){
 #elif SQLITE_TEST
   return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2;
 #else
+  /*
+  ** NOTE: All sub-platforms where the GetVersionEx[AW] functions are
+  **       deprecated are always assumed to be based on the NT kernel.
+  */
   return 1;
 #endif
 }
@@ -33644,7 +34923,7 @@ static char *winUnicodeToMbcs(LPCWSTR zWideFilename){
 ** Convert multibyte character string to UTF-8.  Space to hold the
 ** returned string is obtained from sqlite3_malloc().
 */
-SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){
+SQLITE_API char *SQLITE_STDCALL sqlite3_win32_mbcs_to_utf8(const char *zFilename){
   char *zFilenameUtf8;
   LPWSTR zTmpWide;
 
@@ -33661,7 +34940,7 @@ SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){
 ** Convert UTF-8 to multibyte character string.  Space to hold the
 ** returned string is obtained from sqlite3_malloc().
 */
-SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){
+SQLITE_API char *SQLITE_STDCALL sqlite3_win32_utf8_to_mbcs(const char *zFilename){
   char *zFilenameMbcs;
   LPWSTR zTmpWide;
 
@@ -33681,7 +34960,7 @@ SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){
 ** argument is the name of the directory to use.  The return value will be
 ** SQLITE_OK if successful.
 */
-SQLITE_API int sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
+SQLITE_API int SQLITE_STDCALL sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
   char **ppDirectory = 0;
 #ifndef SQLITE_OMIT_AUTOINIT
   int rc = sqlite3_initialize();
@@ -33906,11 +35185,11 @@ static int winRetryIoerr(int *pnRetry, DWORD *pError){
 /*
 ** Log a I/O error retry episode.
 */
-static void winLogIoerr(int nRetry){
+static void winLogIoerr(int nRetry, int lineno){
   if( nRetry ){
-    sqlite3_log(SQLITE_IOERR,
-      "delayed %dms for lock/sharing conflict",
-      winIoerrRetryDelay*nRetry*(nRetry+1)/2
+    sqlite3_log(SQLITE_NOTICE,
+      "delayed %dms for lock/sharing conflict at line %d",
+      winIoerrRetryDelay*nRetry*(nRetry+1)/2, lineno
     );
   }
 }
@@ -34390,7 +35669,8 @@ static int winClose(sqlite3_file *id){
   assert( pFile->pShm==0 );
 #endif
   assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE );
-  OSTRACE(("CLOSE file=%p\n", pFile->h));
+  OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p\n",
+           osGetCurrentProcessId(), pFile, pFile->h));
 
 #if SQLITE_MAX_MMAP_SIZE>0
   winUnmapfile(pFile);
@@ -34419,7 +35699,8 @@ static int winClose(sqlite3_file *id){
     pFile->h = NULL;
   }
   OpenCounter(-1);
-  OSTRACE(("CLOSE file=%p, rc=%s\n", pFile->h, rc ? "ok" : "failed"));
+  OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p, rc=%s\n",
+           osGetCurrentProcessId(), pFile, pFile->h, rc ? "ok" : "failed"));
   return rc ? SQLITE_OK
             : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(),
                           "winClose", pFile->zPath);
@@ -34436,7 +35717,7 @@ static int winRead(
   int amt,                   /* Number of bytes to read */
   sqlite3_int64 offset       /* Begin reading at this offset */
 ){
-#if !SQLITE_OS_WINCE
+#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
   OVERLAPPED overlapped;          /* The offset for ReadFile. */
 #endif
   winFile *pFile = (winFile*)id;  /* file handle */
@@ -34447,7 +35728,8 @@ static int winRead(
   assert( amt>0 );
   assert( offset>=0 );
   SimulateIOError(return SQLITE_IOERR_READ);
-  OSTRACE(("READ file=%p, buffer=%p, amount=%d, offset=%lld, lock=%d\n",
+  OSTRACE(("READ pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, "
+           "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile,
            pFile->h, pBuf, amt, offset, pFile->locktype));
 
 #if SQLITE_MAX_MMAP_SIZE>0
@@ -34456,7 +35738,8 @@ static int winRead(
   if( offset<pFile->mmapSize ){
     if( offset+amt <= pFile->mmapSize ){
       memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt);
-      OSTRACE(("READ-MMAP file=%p, rc=SQLITE_OK\n", pFile->h));
+      OSTRACE(("READ-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
+               osGetCurrentProcessId(), pFile, pFile->h));
       return SQLITE_OK;
     }else{
       int nCopy = (int)(pFile->mmapSize - offset);
@@ -34468,9 +35751,10 @@ static int winRead(
   }
 #endif
 
-#if SQLITE_OS_WINCE
+#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
   if( winSeekFile(pFile, offset) ){
-    OSTRACE(("READ file=%p, rc=SQLITE_FULL\n", pFile->h));
+    OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n",
+             osGetCurrentProcessId(), pFile, pFile->h));
     return SQLITE_FULL;
   }
   while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
@@ -34484,19 +35768,22 @@ static int winRead(
     DWORD lastErrno;
     if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
     pFile->lastErrno = lastErrno;
-    OSTRACE(("READ file=%p, rc=SQLITE_IOERR_READ\n", pFile->h));
+    OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_READ\n",
+             osGetCurrentProcessId(), pFile, pFile->h));
     return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
                        "winRead", pFile->zPath);
   }
-  winLogIoerr(nRetry);
+  winLogIoerr(nRetry, __LINE__);
   if( nRead<(DWORD)amt ){
     /* Unread parts of the buffer must be zero-filled */
     memset(&((char*)pBuf)[nRead], 0, amt-nRead);
-    OSTRACE(("READ file=%p, rc=SQLITE_IOERR_SHORT_READ\n", pFile->h));
+    OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_SHORT_READ\n",
+             osGetCurrentProcessId(), pFile, pFile->h));
     return SQLITE_IOERR_SHORT_READ;
   }
 
-  OSTRACE(("READ file=%p, rc=SQLITE_OK\n", pFile->h));
+  OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
+           osGetCurrentProcessId(), pFile, pFile->h));
   return SQLITE_OK;
 }
 
@@ -34519,7 +35806,8 @@ static int winWrite(
   SimulateIOError(return SQLITE_IOERR_WRITE);
   SimulateDiskfullError(return SQLITE_FULL);
 
-  OSTRACE(("WRITE file=%p, buffer=%p, amount=%d, offset=%lld, lock=%d\n",
+  OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, "
+           "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile,
            pFile->h, pBuf, amt, offset, pFile->locktype));
 
 #if SQLITE_MAX_MMAP_SIZE>0
@@ -34528,7 +35816,8 @@ static int winWrite(
   if( offset<pFile->mmapSize ){
     if( offset+amt <= pFile->mmapSize ){
       memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt);
-      OSTRACE(("WRITE-MMAP file=%p, rc=SQLITE_OK\n", pFile->h));
+      OSTRACE(("WRITE-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
+               osGetCurrentProcessId(), pFile, pFile->h));
       return SQLITE_OK;
     }else{
       int nCopy = (int)(pFile->mmapSize - offset);
@@ -34540,13 +35829,13 @@ static int winWrite(
   }
 #endif
 
-#if SQLITE_OS_WINCE
+#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
   rc = winSeekFile(pFile, offset);
   if( rc==0 ){
 #else
   {
 #endif
-#if !SQLITE_OS_WINCE
+#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
     OVERLAPPED overlapped;        /* The offset for WriteFile. */
 #endif
     u8 *aRem = (u8 *)pBuf;        /* Data yet to be written */
@@ -34554,14 +35843,14 @@ static int winWrite(
     DWORD nWrite;                 /* Bytes written by each WriteFile() call */
     DWORD lastErrno = NO_ERROR;   /* Value returned by GetLastError() */
 
-#if !SQLITE_OS_WINCE
+#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
     memset(&overlapped, 0, sizeof(OVERLAPPED));
     overlapped.Offset = (LONG)(offset & 0xffffffff);
     overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
 #endif
 
     while( nRem>0 ){
-#if SQLITE_OS_WINCE
+#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
       if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
 #else
       if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
@@ -34574,7 +35863,7 @@ static int winWrite(
         lastErrno = osGetLastError();
         break;
       }
-#if !SQLITE_OS_WINCE
+#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
       offset += nWrite;
       overlapped.Offset = (LONG)(offset & 0xffffffff);
       overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
@@ -34591,17 +35880,20 @@ static int winWrite(
   if( rc ){
     if(   ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL )
        || ( pFile->lastErrno==ERROR_DISK_FULL )){
-      OSTRACE(("WRITE file=%p, rc=SQLITE_FULL\n", pFile->h));
+      OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n",
+               osGetCurrentProcessId(), pFile, pFile->h));
       return winLogError(SQLITE_FULL, pFile->lastErrno,
                          "winWrite1", pFile->zPath);
     }
-    OSTRACE(("WRITE file=%p, rc=SQLITE_IOERR_WRITE\n", pFile->h));
+    OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_WRITE\n",
+             osGetCurrentProcessId(), pFile, pFile->h));
     return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno,
                        "winWrite2", pFile->zPath);
   }else{
-    winLogIoerr(nRetry);
+    winLogIoerr(nRetry, __LINE__);
   }
-  OSTRACE(("WRITE file=%p, rc=SQLITE_OK\n", pFile->h));
+  OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
+           osGetCurrentProcessId(), pFile, pFile->h));
   return SQLITE_OK;
 }
 
@@ -34615,8 +35907,8 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
 
   assert( pFile );
   SimulateIOError(return SQLITE_IOERR_TRUNCATE);
-  OSTRACE(("TRUNCATE file=%p, size=%lld, lock=%d\n",
-           pFile->h, nByte, pFile->locktype));
+  OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, size=%lld, lock=%d\n",
+           osGetCurrentProcessId(), pFile, pFile->h, nByte, pFile->locktype));
 
   /* If the user has configured a chunk-size for this file, truncate the
   ** file so that it consists of an integer number of chunks (i.e. the
@@ -34648,7 +35940,8 @@ static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
   }
 #endif
 
-  OSTRACE(("TRUNCATE file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
+  OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, rc=%s\n",
+           osGetCurrentProcessId(), pFile, pFile->h, sqlite3ErrName(rc)));
   return rc;
 }
 
@@ -34672,7 +35965,7 @@ static int winSync(sqlite3_file *id, int flags){
   BOOL rc;
 #endif
 #if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \
-    (defined(SQLITE_TEST) && defined(SQLITE_DEBUG))
+    defined(SQLITE_HAVE_OS_TRACE)
   /*
   ** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or
   ** OSTRACE() macros.
@@ -34693,8 +35986,9 @@ static int winSync(sqlite3_file *id, int flags){
   */
   SimulateDiskfullError( return SQLITE_FULL );
 
-  OSTRACE(("SYNC file=%p, flags=%x, lock=%d\n",
-           pFile->h, flags, pFile->locktype));
+  OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, flags=%x, lock=%d\n",
+           osGetCurrentProcessId(), pFile, pFile->h, flags,
+           pFile->locktype));
 
 #ifndef SQLITE_TEST
   UNUSED_PARAMETER(flags);
@@ -34709,19 +36003,38 @@ static int winSync(sqlite3_file *id, int flags){
   ** no-op
   */
 #ifdef SQLITE_NO_SYNC
-  OSTRACE(("SYNC-NOP file=%p, rc=SQLITE_OK\n", pFile->h));
+  OSTRACE(("SYNC-NOP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
+           osGetCurrentProcessId(), pFile, pFile->h));
   return SQLITE_OK;
 #else
+#if SQLITE_MAX_MMAP_SIZE>0
+  if( pFile->pMapRegion ){
+    if( osFlushViewOfFile(pFile->pMapRegion, 0) ){
+      OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, "
+               "rc=SQLITE_OK\n", osGetCurrentProcessId(),
+               pFile, pFile->pMapRegion));
+    }else{
+      pFile->lastErrno = osGetLastError();
+      OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, "
+               "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(),
+               pFile, pFile->pMapRegion));
+      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
+                         "winSync1", pFile->zPath);
+    }
+  }
+#endif
   rc = osFlushFileBuffers(pFile->h);
   SimulateIOError( rc=FALSE );
   if( rc ){
-    OSTRACE(("SYNC file=%p, rc=SQLITE_OK\n", pFile->h));
+    OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
+             osGetCurrentProcessId(), pFile, pFile->h));
     return SQLITE_OK;
   }else{
     pFile->lastErrno = osGetLastError();
-    OSTRACE(("SYNC file=%p, rc=SQLITE_IOERR_FSYNC\n", pFile->h));
+    OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_FSYNC\n",
+             osGetCurrentProcessId(), pFile, pFile->h));
     return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno,
-                       "winSync", pFile->zPath);
+                       "winSync2", pFile->zPath);
   }
 #endif
 }
@@ -35097,7 +36410,7 @@ static int winUnlock(sqlite3_file *id, int locktype){
 }
 
 /*
-** If *pArg is inititially negative then this is a query.  Set *pArg to
+** If *pArg is initially negative then this is a query.  Set *pArg to
 ** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.
 **
 ** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags.
@@ -35329,7 +36642,7 @@ struct winShmNode {
   int nRef;                  /* Number of winShm objects pointing to this */
   winShm *pFirst;            /* All winShm objects pointing to this */
   winShmNode *pNext;         /* Next in list of all winShmNode objects */
-#ifdef SQLITE_DEBUG
+#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
   u8 nextShmId;              /* Next available winShm.id value */
 #endif
 };
@@ -35360,7 +36673,7 @@ struct winShm {
   u8 hasMutex;               /* True if holding the winShmNode mutex */
   u16 sharedMask;            /* Mask of shared locks held */
   u16 exclMask;              /* Mask of exclusive locks held */
-#ifdef SQLITE_DEBUG
+#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
   u8 id;                     /* Id of this connection with its winShmNode */
 #endif
 };
@@ -35551,7 +36864,7 @@ static int winOpenSharedMemory(winFile *pDbFd){
 
   /* Make the new connection a child of the winShmNode */
   p->pShmNode = pShmNode;
-#ifdef SQLITE_DEBUG
+#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
   p->id = pShmNode->nextShmId++;
 #endif
   pShmNode->nRef++;
@@ -35771,16 +37084,16 @@ static int winShmMap(
   void volatile **pp              /* OUT: Mapped memory */
 ){
   winFile *pDbFd = (winFile*)fd;
-  winShm *p = pDbFd->pShm;
+  winShm *pShm = pDbFd->pShm;
   winShmNode *pShmNode;
   int rc = SQLITE_OK;
 
-  if( !p ){
+  if( !pShm ){
     rc = winOpenSharedMemory(pDbFd);
     if( rc!=SQLITE_OK ) return rc;
-    p = pDbFd->pShm;
+    pShm = pDbFd->pShm;
   }
-  pShmNode = p->pShmNode;
+  pShmNode = pShm->pShmNode;
 
   sqlite3_mutex_enter(pShmNode->mutex);
   assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
@@ -35820,7 +37133,7 @@ static int winShmMap(
     }
 
     /* Map the requested memory region into this processes address space. */
-    apNew = (struct ShmRegion *)sqlite3_realloc(
+    apNew = (struct ShmRegion *)sqlite3_realloc64(
         pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
     );
     if( !apNew ){
@@ -36111,7 +37424,7 @@ static int winUnfetch(sqlite3_file *fd, i64 iOff, void *p){
   }else{
     /* FIXME:  If Windows truly always prevents truncating or deleting a
     ** file while a mapping is held, then the following winUnmapfile() call
-    ** is unnecessary can can be omitted - potentially improving
+    ** is unnecessary can be omitted - potentially improving
     ** performance.  */
     winUnmapfile(pFd);
   }
@@ -36692,7 +38005,7 @@ static int winOpen(
     }
   }
 #endif
-  winLogIoerr(cnt);
+  winLogIoerr(cnt, __LINE__);
 
   OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name,
            dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));
@@ -36876,7 +38189,7 @@ static int winDelete(
   if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
     rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename);
   }else{
-    winLogIoerr(cnt);
+    winLogIoerr(cnt, __LINE__);
   }
   sqlite3_free(zConverted);
   OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc)));
@@ -36926,7 +38239,7 @@ static int winAccess(
         attr = sAttrData.dwFileAttributes;
       }
     }else{
-      winLogIoerr(cnt);
+      winLogIoerr(cnt, __LINE__);
       if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){
         sqlite3_free(zConverted);
         return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess",
@@ -37267,7 +38580,7 @@ static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
 static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
   int n = 0;
   UNUSED_PARAMETER(pVfs);
-#if defined(SQLITE_TEST)
+#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS)
   n = nBuf;
   memset(zBuf, 0, nBuf);
 #else
@@ -37301,7 +38614,23 @@ static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
     memcpy(&zBuf[n], &i, sizeof(i));
     n += sizeof(i);
   }
+#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
+  if( sizeof(UUID)<=nBuf-n ){
+    UUID id;
+    memset(&id, 0, sizeof(UUID));
+    osUuidCreate(&id);
+    memcpy(zBuf, &id, sizeof(UUID));
+    n += sizeof(UUID);
+  }
+  if( sizeof(UUID)<=nBuf-n ){
+    UUID id;
+    memset(&id, 0, sizeof(UUID));
+    osUuidCreateSequential(&id);
+    memcpy(zBuf, &id, sizeof(UUID));
+    n += sizeof(UUID);
+  }
 #endif
+#endif /* defined(SQLITE_TEST) || defined(SQLITE_ZERO_PRNG_SEED) */
   return n;
 }
 
@@ -37425,7 +38754,7 @@ static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
 /*
 ** Initialize and deinitialize the operating system interface.
 */
-SQLITE_API int sqlite3_os_init(void){
+SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){
   static sqlite3_vfs winVfs = {
     3,                   /* iVersion */
     sizeof(winFile),     /* szOsFile */
@@ -37479,7 +38808,7 @@ SQLITE_API int sqlite3_os_init(void){
 
   /* Double-check that the aSyscall[] array has been constructed
   ** correctly.  See ticket [bb3a86e890c8e96ab] */
-  assert( ArraySize(aSyscall)==77 );
+  assert( ArraySize(aSyscall)==80 );
 
   /* get memory map allocation granularity */
   memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
@@ -37500,7 +38829,7 @@ SQLITE_API int sqlite3_os_init(void){
   return SQLITE_OK;
 }
 
-SQLITE_API int sqlite3_os_end(void){
+SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void){
 #if SQLITE_OS_WINRT
   if( sleepObj!=NULL ){
     osCloseHandle(sleepObj);
@@ -37856,7 +39185,7 @@ SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){
   ** bits to act as the reference */
   pBitvec = sqlite3BitvecCreate( sz );
   pV = sqlite3MallocZero( (sz+7)/8 + 1 );
-  pTmpSpace = sqlite3_malloc(BITVEC_SZ);
+  pTmpSpace = sqlite3_malloc64(BITVEC_SZ);
   if( pBitvec==0 || pV==0 || pTmpSpace==0  ) goto bitvec_end;
 
   /* NULL pBitvec tests */
@@ -37955,102 +39284,73 @@ struct PCache {
   PgHdr *pPage1;                      /* Reference to page 1 */
 };
 
-/*
-** Some of the assert() macros in this code are too expensive to run
-** even during normal debugging.  Use them only rarely on long-running
-** tests.  Enable the expensive asserts using the
-** -DSQLITE_ENABLE_EXPENSIVE_ASSERT=1 compile-time option.
-*/
-#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
-# define expensive_assert(X)  assert(X)
-#else
-# define expensive_assert(X)
-#endif
-
 /********************************** Linked List Management ********************/
 
-#if !defined(NDEBUG) && defined(SQLITE_ENABLE_EXPENSIVE_ASSERT)
-/*
-** Check that the pCache->pSynced variable is set correctly. If it
-** is not, either fail an assert or return zero. Otherwise, return
-** non-zero. This is only used in debugging builds, as follows:
-**
-**   expensive_assert( pcacheCheckSynced(pCache) );
-*/
-static int pcacheCheckSynced(PCache *pCache){
-  PgHdr *p;
-  for(p=pCache->pDirtyTail; p!=pCache->pSynced; p=p->pDirtyPrev){
-    assert( p->nRef || (p->flags&PGHDR_NEED_SYNC) );
-  }
-  return (p==0 || p->nRef || (p->flags&PGHDR_NEED_SYNC)==0);
-}
-#endif /* !NDEBUG && SQLITE_ENABLE_EXPENSIVE_ASSERT */
+/* Allowed values for second argument to pcacheManageDirtyList() */
+#define PCACHE_DIRTYLIST_REMOVE   1    /* Remove pPage from dirty list */
+#define PCACHE_DIRTYLIST_ADD      2    /* Add pPage to the dirty list */
+#define PCACHE_DIRTYLIST_FRONT    3    /* Move pPage to the front of the list */
 
 /*
-** Remove page pPage from the list of dirty pages.
+** Manage pPage's participation on the dirty list.  Bits of the addRemove
+** argument determines what operation to do.  The 0x01 bit means first
+** remove pPage from the dirty list.  The 0x02 means add pPage back to
+** the dirty list.  Doing both moves pPage to the front of the dirty list.
 */
-static void pcacheRemoveFromDirtyList(PgHdr *pPage){
+static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){
   PCache *p = pPage->pCache;
 
-  assert( pPage->pDirtyNext || pPage==p->pDirtyTail );
-  assert( pPage->pDirtyPrev || pPage==p->pDirty );
-
-  /* Update the PCache1.pSynced variable if necessary. */
-  if( p->pSynced==pPage ){
-    PgHdr *pSynced = pPage->pDirtyPrev;
-    while( pSynced && (pSynced->flags&PGHDR_NEED_SYNC) ){
-      pSynced = pSynced->pDirtyPrev;
+  if( addRemove & PCACHE_DIRTYLIST_REMOVE ){
+    assert( pPage->pDirtyNext || pPage==p->pDirtyTail );
+    assert( pPage->pDirtyPrev || pPage==p->pDirty );
+  
+    /* Update the PCache1.pSynced variable if necessary. */
+    if( p->pSynced==pPage ){
+      PgHdr *pSynced = pPage->pDirtyPrev;
+      while( pSynced && (pSynced->flags&PGHDR_NEED_SYNC) ){
+        pSynced = pSynced->pDirtyPrev;
+      }
+      p->pSynced = pSynced;
     }
-    p->pSynced = pSynced;
-  }
-
-  if( pPage->pDirtyNext ){
-    pPage->pDirtyNext->pDirtyPrev = pPage->pDirtyPrev;
-  }else{
-    assert( pPage==p->pDirtyTail );
-    p->pDirtyTail = pPage->pDirtyPrev;
-  }
-  if( pPage->pDirtyPrev ){
-    pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext;
-  }else{
-    assert( pPage==p->pDirty );
-    p->pDirty = pPage->pDirtyNext;
-    if( p->pDirty==0 && p->bPurgeable ){
-      assert( p->eCreate==1 );
-      p->eCreate = 2;
+  
+    if( pPage->pDirtyNext ){
+      pPage->pDirtyNext->pDirtyPrev = pPage->pDirtyPrev;
+    }else{
+      assert( pPage==p->pDirtyTail );
+      p->pDirtyTail = pPage->pDirtyPrev;
     }
+    if( pPage->pDirtyPrev ){
+      pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext;
+    }else{
+      assert( pPage==p->pDirty );
+      p->pDirty = pPage->pDirtyNext;
+      if( p->pDirty==0 && p->bPurgeable ){
+        assert( p->eCreate==1 );
+        p->eCreate = 2;
+      }
+    }
+    pPage->pDirtyNext = 0;
+    pPage->pDirtyPrev = 0;
   }
-  pPage->pDirtyNext = 0;
-  pPage->pDirtyPrev = 0;
-
-  expensive_assert( pcacheCheckSynced(p) );
-}
-
-/*
-** Add page pPage to the head of the dirty list (PCache1.pDirty is set to
-** pPage).
-*/
-static void pcacheAddToDirtyList(PgHdr *pPage){
-  PCache *p = pPage->pCache;
-
-  assert( pPage->pDirtyNext==0 && pPage->pDirtyPrev==0 && p->pDirty!=pPage );
-
-  pPage->pDirtyNext = p->pDirty;
-  if( pPage->pDirtyNext ){
-    assert( pPage->pDirtyNext->pDirtyPrev==0 );
-    pPage->pDirtyNext->pDirtyPrev = pPage;
-  }else if( p->bPurgeable ){
-    assert( p->eCreate==2 );
-    p->eCreate = 1;
-  }
-  p->pDirty = pPage;
-  if( !p->pDirtyTail ){
-    p->pDirtyTail = pPage;
-  }
-  if( !p->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) ){
-    p->pSynced = pPage;
+  if( addRemove & PCACHE_DIRTYLIST_ADD ){
+    assert( pPage->pDirtyNext==0 && pPage->pDirtyPrev==0 && p->pDirty!=pPage );
+  
+    pPage->pDirtyNext = p->pDirty;
+    if( pPage->pDirtyNext ){
+      assert( pPage->pDirtyNext->pDirtyPrev==0 );
+      pPage->pDirtyNext->pDirtyPrev = pPage;
+    }else{
+      p->pDirtyTail = pPage;
+      if( p->bPurgeable ){
+        assert( p->eCreate==2 );
+        p->eCreate = 1;
+      }
+    }
+    p->pDirty = pPage;
+    if( !p->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) ){
+      p->pSynced = pPage;
+    }
   }
-  expensive_assert( pcacheCheckSynced(p) );
 }
 
 /*
@@ -38058,12 +39358,30 @@ static void pcacheAddToDirtyList(PgHdr *pPage){
 ** being used for an in-memory database, this function is a no-op.
 */
 static void pcacheUnpin(PgHdr *p){
-  PCache *pCache = p->pCache;
-  if( pCache->bPurgeable ){
+  if( p->pCache->bPurgeable ){
     if( p->pgno==1 ){
-      pCache->pPage1 = 0;
+      p->pCache->pPage1 = 0;
     }
-    sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 0);
+    sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0);
+  }
+}
+
+/*
+** Compute the number of pages of cache requested.  p->szCache is the
+** cache size requested by the "PRAGMA cache_size" statement.
+**
+**
+*/
+static int numberOfCachePages(PCache *p){
+  if( p->szCache>=0 ){
+    /* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the
+    ** suggested cache size is set to N. */
+    return p->szCache;
+  }else{
+    /* IMPLEMENTATION-OF: R-61436-13639 If the argument N is negative, then
+    ** the number of cache pages is adjusted to use approximately abs(N*1024)
+    ** bytes of memory. */
+    return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
   }
 }
 
@@ -38099,7 +39417,7 @@ SQLITE_PRIVATE int sqlite3PcacheSize(void){ return sizeof(PCache); }
 ** The caller discovers how much space needs to be allocated by 
 ** calling sqlite3PcacheSize().
 */
-SQLITE_PRIVATE void sqlite3PcacheOpen(
+SQLITE_PRIVATE int sqlite3PcacheOpen(
   int szPage,                  /* Size of every page */
   int szExtra,                 /* Extra space associated with each page */
   int bPurgeable,              /* True if pages are on backing store */
@@ -38108,76 +39426,76 @@ SQLITE_PRIVATE void sqlite3PcacheOpen(
   PCache *p                    /* Preallocated space for the PCache */
 ){
   memset(p, 0, sizeof(PCache));
-  p->szPage = szPage;
+  p->szPage = 1;
   p->szExtra = szExtra;
   p->bPurgeable = bPurgeable;
   p->eCreate = 2;
   p->xStress = xStress;
   p->pStress = pStress;
   p->szCache = 100;
+  return sqlite3PcacheSetPageSize(p, szPage);
 }
 
 /*
 ** Change the page size for PCache object. The caller must ensure that there
 ** are no outstanding page references when this function is called.
 */
-SQLITE_PRIVATE void sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
+SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
   assert( pCache->nRef==0 && pCache->pDirty==0 );
-  if( pCache->pCache ){
-    sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
-    pCache->pCache = 0;
+  if( pCache->szPage ){
+    sqlite3_pcache *pNew;
+    pNew = sqlite3GlobalConfig.pcache2.xCreate(
+                szPage, pCache->szExtra + ROUND8(sizeof(PgHdr)),
+                pCache->bPurgeable
+    );
+    if( pNew==0 ) return SQLITE_NOMEM;
+    sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache));
+    if( pCache->pCache ){
+      sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
+    }
+    pCache->pCache = pNew;
     pCache->pPage1 = 0;
+    pCache->szPage = szPage;
   }
-  pCache->szPage = szPage;
-}
-
-/*
-** Compute the number of pages of cache requested.
-*/
-static int numberOfCachePages(PCache *p){
-  if( p->szCache>=0 ){
-    return p->szCache;
-  }else{
-    return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
-  }
+  return SQLITE_OK;
 }
 
 /*
 ** Try to obtain a page from the cache.
+**
+** This routine returns a pointer to an sqlite3_pcache_page object if
+** such an object is already in cache, or if a new one is created.
+** This routine returns a NULL pointer if the object was not in cache
+** and could not be created.
+**
+** The createFlags should be 0 to check for existing pages and should
+** be 3 (not 1, but 3) to try to create a new page.
+**
+** If the createFlag is 0, then NULL is always returned if the page
+** is not already in the cache.  If createFlag is 1, then a new page
+** is created only if that can be done without spilling dirty pages
+** and without exceeding the cache size limit.
+**
+** The caller needs to invoke sqlite3PcacheFetchFinish() to properly
+** initialize the sqlite3_pcache_page object and convert it into a
+** PgHdr object.  The sqlite3PcacheFetch() and sqlite3PcacheFetchFinish()
+** routines are split this way for performance reasons. When separated
+** they can both (usually) operate without having to push values to
+** the stack on entry and pop them back off on exit, which saves a
+** lot of pushing and popping.
 */
-SQLITE_PRIVATE int sqlite3PcacheFetch(
+SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch(
   PCache *pCache,       /* Obtain the page from this cache */
   Pgno pgno,            /* Page number to obtain */
-  int createFlag,       /* If true, create page if it does not exist already */
-  PgHdr **ppPage        /* Write the page here */
+  int createFlag        /* If true, create page if it does not exist already */
 ){
-  sqlite3_pcache_page *pPage;
-  PgHdr *pPgHdr = 0;
   int eCreate;
 
   assert( pCache!=0 );
-  assert( createFlag==1 || createFlag==0 );
+  assert( pCache->pCache!=0 );
+  assert( createFlag==3 || createFlag==0 );
   assert( pgno>0 );
 
-  /* If the pluggable cache (sqlite3_pcache*) has not been allocated,
-  ** allocate it now.
-  */
-  if( !pCache->pCache ){
-    sqlite3_pcache *p;
-    if( !createFlag ){
-      *ppPage = 0;
-      return SQLITE_OK;
-    }
-    p = sqlite3GlobalConfig.pcache2.xCreate(
-        pCache->szPage, pCache->szExtra + sizeof(PgHdr), pCache->bPurgeable
-    );
-    if( !p ){
-      return SQLITE_NOMEM;
-    }
-    sqlite3GlobalConfig.pcache2.xCachesize(p, numberOfCachePages(pCache));
-    pCache->pCache = p;
-  }
-
   /* eCreate defines what to do if the page does not exist.
   **    0     Do not allocate a new page.  (createFlag==0)
   **    1     Allocate a new page if doing so is inexpensive.
@@ -38185,89 +39503,135 @@ SQLITE_PRIVATE int sqlite3PcacheFetch(
   **    2     Allocate a new page even it doing so is difficult.
   **          (createFlag==1 AND !(bPurgeable AND pDirty)
   */
-  eCreate = createFlag==0 ? 0 : pCache->eCreate;
-  assert( (createFlag*(1+(!pCache->bPurgeable||!pCache->pDirty)))==eCreate );
-  pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
-  if( !pPage && eCreate==1 ){
-    PgHdr *pPg;
+  eCreate = createFlag & pCache->eCreate;
+  assert( eCreate==0 || eCreate==1 || eCreate==2 );
+  assert( createFlag==0 || pCache->eCreate==eCreate );
+  assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) );
+  return sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
+}
 
-    /* Find a dirty page to write-out and recycle. First try to find a 
-    ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC
-    ** cleared), but if that is not possible settle for any other 
-    ** unreferenced dirty page.
-    */
-    expensive_assert( pcacheCheckSynced(pCache) );
-    for(pPg=pCache->pSynced; 
-        pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); 
-        pPg=pPg->pDirtyPrev
-    );
-    pCache->pSynced = pPg;
-    if( !pPg ){
-      for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev);
-    }
-    if( pPg ){
-      int rc;
+/*
+** If the sqlite3PcacheFetch() routine is unable to allocate a new
+** page because new clean pages are available for reuse and the cache
+** size limit has been reached, then this routine can be invoked to 
+** try harder to allocate a page.  This routine might invoke the stress
+** callback to spill dirty pages to the journal.  It will then try to
+** allocate the new page and will only fail to allocate a new page on
+** an OOM error.
+**
+** This routine should be invoked only after sqlite3PcacheFetch() fails.
+*/
+SQLITE_PRIVATE int sqlite3PcacheFetchStress(
+  PCache *pCache,                 /* Obtain the page from this cache */
+  Pgno pgno,                      /* Page number to obtain */
+  sqlite3_pcache_page **ppPage    /* Write result here */
+){
+  PgHdr *pPg;
+  if( pCache->eCreate==2 ) return 0;
+
+
+  /* Find a dirty page to write-out and recycle. First try to find a 
+  ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC
+  ** cleared), but if that is not possible settle for any other 
+  ** unreferenced dirty page.
+  */
+  for(pPg=pCache->pSynced; 
+      pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); 
+      pPg=pPg->pDirtyPrev
+  );
+  pCache->pSynced = pPg;
+  if( !pPg ){
+    for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev);
+  }
+  if( pPg ){
+    int rc;
 #ifdef SQLITE_LOG_CACHE_SPILL
-      sqlite3_log(SQLITE_FULL, 
-                  "spill page %d making room for %d - cache used: %d/%d",
-                  pPg->pgno, pgno,
-                  sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache),
-                  numberOfCachePages(pCache));
-#endif
-      rc = pCache->xStress(pCache->pStress, pPg);
-      if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
-        return rc;
-      }
+    sqlite3_log(SQLITE_FULL, 
+                "spill page %d making room for %d - cache used: %d/%d",
+                pPg->pgno, pgno,
+                sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache),
+                numberOfCachePages(pCache));
+#endif
+    rc = pCache->xStress(pCache->pStress, pPg);
+    if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
+      return rc;
     }
-
-    pPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2);
   }
+  *ppPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2);
+  return *ppPage==0 ? SQLITE_NOMEM : SQLITE_OK;
+}
 
-  if( pPage ){
-    pPgHdr = (PgHdr *)pPage->pExtra;
-
-    if( !pPgHdr->pPage ){
-      memset(pPgHdr, 0, sizeof(PgHdr));
-      pPgHdr->pPage = pPage;
-      pPgHdr->pData = pPage->pBuf;
-      pPgHdr->pExtra = (void *)&pPgHdr[1];
-      memset(pPgHdr->pExtra, 0, pCache->szExtra);
-      pPgHdr->pCache = pCache;
-      pPgHdr->pgno = pgno;
-    }
-    assert( pPgHdr->pCache==pCache );
-    assert( pPgHdr->pgno==pgno );
-    assert( pPgHdr->pData==pPage->pBuf );
-    assert( pPgHdr->pExtra==(void *)&pPgHdr[1] );
-
-    if( 0==pPgHdr->nRef ){
-      pCache->nRef++;
-    }
-    pPgHdr->nRef++;
-    if( pgno==1 ){
-      pCache->pPage1 = pPgHdr;
-    }
+/*
+** This is a helper routine for sqlite3PcacheFetchFinish()
+**
+** In the uncommon case where the page being fetched has not been
+** initialized, this routine is invoked to do the initialization.
+** This routine is broken out into a separate function since it
+** requires extra stack manipulation that can be avoided in the common
+** case.
+*/
+static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit(
+  PCache *pCache,             /* Obtain the page from this cache */
+  Pgno pgno,                  /* Page number obtained */
+  sqlite3_pcache_page *pPage  /* Page obtained by prior PcacheFetch() call */
+){
+  PgHdr *pPgHdr;
+  assert( pPage!=0 );
+  pPgHdr = (PgHdr*)pPage->pExtra;
+  assert( pPgHdr->pPage==0 );
+ memset(pPgHdr, 0, sizeof(PgHdr));
+  pPgHdr->pPage = pPage;
+  pPgHdr->pData = pPage->pBuf;
+  pPgHdr->pExtra = (void *)&pPgHdr[1];
+  memset(pPgHdr->pExtra, 0, pCache->szExtra);
+  pPgHdr->pCache = pCache;
+  pPgHdr->pgno = pgno;
+  return sqlite3PcacheFetchFinish(pCache,pgno,pPage);
+}
+
+/*
+** This routine converts the sqlite3_pcache_page object returned by
+** sqlite3PcacheFetch() into an initialized PgHdr object.  This routine
+** must be called after sqlite3PcacheFetch() in order to get a usable
+** result.
+*/
+SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish(
+  PCache *pCache,             /* Obtain the page from this cache */
+  Pgno pgno,                  /* Page number obtained */
+  sqlite3_pcache_page *pPage  /* Page obtained by prior PcacheFetch() call */
+){
+  PgHdr *pPgHdr;
+
+  if( pPage==0 ) return 0;
+  pPgHdr = (PgHdr *)pPage->pExtra;
+
+  if( !pPgHdr->pPage ){
+    return pcacheFetchFinishWithInit(pCache, pgno, pPage);
+  }
+  if( 0==pPgHdr->nRef ){
+    pCache->nRef++;
   }
-  *ppPage = pPgHdr;
-  return (pPgHdr==0 && eCreate) ? SQLITE_NOMEM : SQLITE_OK;
+  pPgHdr->nRef++;
+  if( pgno==1 ){
+    pCache->pPage1 = pPgHdr;
+  }
+  return pPgHdr;
 }
 
 /*
 ** Decrement the reference count on a page. If the page is clean and the
-** reference count drops to 0, then it is made elible for recycling.
+** reference count drops to 0, then it is made eligible for recycling.
 */
-SQLITE_PRIVATE void sqlite3PcacheRelease(PgHdr *p){
+SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){
   assert( p->nRef>0 );
   p->nRef--;
   if( p->nRef==0 ){
-    PCache *pCache = p->pCache;
-    pCache->nRef--;
+    p->pCache->nRef--;
     if( (p->flags&PGHDR_DIRTY)==0 ){
       pcacheUnpin(p);
-    }else{
+    }else if( p->pDirtyPrev!=0 ){
       /* Move the page to the head of the dirty list. */
-      pcacheRemoveFromDirtyList(p);
-      pcacheAddToDirtyList(p);
+      pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
     }
   }
 }
@@ -38286,17 +39650,15 @@ SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr *p){
 ** page pointed to by p is invalid.
 */
 SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){
-  PCache *pCache;
   assert( p->nRef==1 );
   if( p->flags&PGHDR_DIRTY ){
-    pcacheRemoveFromDirtyList(p);
+    pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
   }
-  pCache = p->pCache;
-  pCache->nRef--;
+  p->pCache->nRef--;
   if( p->pgno==1 ){
-    pCache->pPage1 = 0;
+    p->pCache->pPage1 = 0;
   }
-  sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, p->pPage, 1);
+  sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 1);
 }
 
 /*
@@ -38308,7 +39670,7 @@ SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){
   assert( p->nRef>0 );
   if( 0==(p->flags & PGHDR_DIRTY) ){
     p->flags |= PGHDR_DIRTY;
-    pcacheAddToDirtyList( p);
+    pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD);
   }
 }
 
@@ -38318,7 +39680,7 @@ SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){
 */
 SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){
   if( (p->flags & PGHDR_DIRTY) ){
-    pcacheRemoveFromDirtyList(p);
+    pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
     p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC);
     if( p->nRef==0 ){
       pcacheUnpin(p);
@@ -38357,8 +39719,7 @@ SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){
   sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
   p->pgno = newPgno;
   if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
-    pcacheRemoveFromDirtyList(p);
-    pcacheAddToDirtyList(p);
+    pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
   }
 }
 
@@ -38399,9 +39760,8 @@ SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
 ** Close a cache.
 */
 SQLITE_PRIVATE void sqlite3PcacheClose(PCache *pCache){
-  if( pCache->pCache ){
-    sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
-  }
+  assert( pCache->pCache!=0 );
+  sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
 }
 
 /* 
@@ -38510,11 +39870,8 @@ SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr *p){
 ** Return the total number of pages in the cache.
 */
 SQLITE_PRIVATE int sqlite3PcachePagecount(PCache *pCache){
-  int nPage = 0;
-  if( pCache->pCache ){
-    nPage = sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache);
-  }
-  return nPage;
+  assert( pCache->pCache!=0 );
+  return sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache);
 }
 
 #ifdef SQLITE_TEST
@@ -38530,22 +39887,27 @@ SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *pCache){
 ** Set the suggested cache-size value.
 */
 SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){
+  assert( pCache->pCache!=0 );
   pCache->szCache = mxPage;
-  if( pCache->pCache ){
-    sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache,
-                                           numberOfCachePages(pCache));
-  }
+  sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache,
+                                         numberOfCachePages(pCache));
 }
 
 /*
 ** Free up as much memory as possible from the page cache.
 */
 SQLITE_PRIVATE void sqlite3PcacheShrink(PCache *pCache){
-  if( pCache->pCache ){
-    sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache);
-  }
+  assert( pCache->pCache!=0 );
+  sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache);
 }
 
+/*
+** Return the size of the header added by this middleware layer
+** in the page-cache hierarchy.
+*/
+SQLITE_PRIVATE int sqlite3HeaderSizePcache(void){ return ROUND8(sizeof(PgHdr)); }
+
+
 #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
 /*
 ** For all dirty pages currently in the cache, invoke the specified
@@ -38577,7 +39939,7 @@ SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHd
 ** This file implements the default page cache implementation (the
 ** sqlite3_pcache interface). It also contains part of the implementation
 ** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features.
-** If the default page cache implementation is overriden, then neither of
+** If the default page cache implementation is overridden, then neither of
 ** these two features are available.
 */
 
@@ -38588,7 +39950,7 @@ typedef struct PgFreeslot PgFreeslot;
 typedef struct PGroup PGroup;
 
 /* Each page cache (or PCache) belongs to a PGroup.  A PGroup is a set 
-** of one or more PCaches that are able to recycle each others unpinned
+** of one or more PCaches that are able to recycle each other's unpinned
 ** pages when they are under memory pressure.  A PGroup is an instance of
 ** the following object.
 **
@@ -38758,7 +40120,6 @@ SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
 static void *pcache1Alloc(int nByte){
   void *p = 0;
   assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
-  sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
   if( nByte<=pcache1.szSlot ){
     sqlite3_mutex_enter(pcache1.mutex);
     p = (PgHdr1 *)pcache1.pFree;
@@ -38767,7 +40128,8 @@ static void *pcache1Alloc(int nByte){
       pcache1.nFreeSlot--;
       pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
       assert( pcache1.nFreeSlot>=0 );
-      sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1);
+      sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
+      sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1);
     }
     sqlite3_mutex_leave(pcache1.mutex);
   }
@@ -38780,7 +40142,8 @@ static void *pcache1Alloc(int nByte){
     if( p ){
       int sz = sqlite3MallocSize(p);
       sqlite3_mutex_enter(pcache1.mutex);
-      sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
+      sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
+      sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
       sqlite3_mutex_leave(pcache1.mutex);
     }
 #endif
@@ -38798,7 +40161,7 @@ static int pcache1Free(void *p){
   if( p>=pcache1.pStart && p<pcache1.pEnd ){
     PgFreeslot *pSlot;
     sqlite3_mutex_enter(pcache1.mutex);
-    sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, -1);
+    sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_USED, 1);
     pSlot = (PgFreeslot*)p;
     pSlot->pNext = pcache1.pFree;
     pcache1.pFree = pSlot;
@@ -38812,7 +40175,7 @@ static int pcache1Free(void *p){
     nFreed = sqlite3MallocSize(p);
 #ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
     sqlite3_mutex_enter(pcache1.mutex);
-    sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -nFreed);
+    sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_OVERFLOW, nFreed);
     sqlite3_mutex_leave(pcache1.mutex);
 #endif
     sqlite3_free(p);
@@ -38859,7 +40222,7 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
     pPg = 0;
   }
 #else
-  pPg = pcache1Alloc(sizeof(PgHdr1) + pCache->szPage + pCache->szExtra);
+  pPg = pcache1Alloc(ROUND8(sizeof(PgHdr1)) + pCache->szPage + pCache->szExtra);
   p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
 #endif
   pcache1EnterMutex(pCache->pGroup);
@@ -38946,7 +40309,7 @@ static int pcache1UnderMemoryPressure(PCache1 *pCache){
 **
 ** The PCache mutex must be held when this function is called.
 */
-static int pcache1ResizeHash(PCache1 *p){
+static void pcache1ResizeHash(PCache1 *p){
   PgHdr1 **apNew;
   unsigned int nNew;
   unsigned int i;
@@ -38978,8 +40341,6 @@ static int pcache1ResizeHash(PCache1 *p){
     p->apHash = apNew;
     p->nHash = nNew;
   }
-
-  return (p->apHash ? SQLITE_OK : SQLITE_NOMEM);
 }
 
 /*
@@ -39114,6 +40475,9 @@ static void pcache1Shutdown(void *NotUsed){
   memset(&pcache1, 0, sizeof(pcache1));
 }
 
+/* forward declaration */
+static void pcache1Destroy(sqlite3_pcache *p);
+
 /*
 ** Implementation of the sqlite3_pcache.xCreate method.
 **
@@ -39158,12 +40522,17 @@ static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
     pCache->szPage = szPage;
     pCache->szExtra = szExtra;
     pCache->bPurgeable = (bPurgeable ? 1 : 0);
+    pcache1EnterMutex(pGroup);
+    pcache1ResizeHash(pCache);
     if( bPurgeable ){
       pCache->nMin = 10;
-      pcache1EnterMutex(pGroup);
       pGroup->nMinPage += pCache->nMin;
       pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
-      pcache1LeaveMutex(pGroup);
+    }
+    pcache1LeaveMutex(pGroup);
+    if( pCache->nHash==0 ){
+      pcache1Destroy((sqlite3_pcache*)pCache);
+      pCache = 0;
     }
   }
   return (sqlite3_pcache *)pCache;
@@ -39219,6 +40588,95 @@ static int pcache1Pagecount(sqlite3_pcache *p){
   return n;
 }
 
+
+/*
+** Implement steps 3, 4, and 5 of the pcache1Fetch() algorithm described
+** in the header of the pcache1Fetch() procedure.
+**
+** This steps are broken out into a separate procedure because they are
+** usually not needed, and by avoiding the stack initialization required
+** for these steps, the main pcache1Fetch() procedure can run faster.
+*/
+static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2(
+  PCache1 *pCache, 
+  unsigned int iKey, 
+  int createFlag
+){
+  unsigned int nPinned;
+  PGroup *pGroup = pCache->pGroup;
+  PgHdr1 *pPage = 0;
+
+  /* Step 3: Abort if createFlag is 1 but the cache is nearly full */
+  assert( pCache->nPage >= pCache->nRecyclable );
+  nPinned = pCache->nPage - pCache->nRecyclable;
+  assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage );
+  assert( pCache->n90pct == pCache->nMax*9/10 );
+  if( createFlag==1 && (
+        nPinned>=pGroup->mxPinned
+     || nPinned>=pCache->n90pct
+     || (pcache1UnderMemoryPressure(pCache) && pCache->nRecyclable<nPinned)
+  )){
+    return 0;
+  }
+
+  if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache);
+  assert( pCache->nHash>0 && pCache->apHash );
+
+  /* Step 4. Try to recycle a page. */
+  if( pCache->bPurgeable && pGroup->pLruTail && (
+         (pCache->nPage+1>=pCache->nMax)
+      || pGroup->nCurrentPage>=pGroup->nMaxPage
+      || pcache1UnderMemoryPressure(pCache)
+  )){
+    PCache1 *pOther;
+    pPage = pGroup->pLruTail;
+    assert( pPage->isPinned==0 );
+    pcache1RemoveFromHash(pPage);
+    pcache1PinPage(pPage);
+    pOther = pPage->pCache;
+
+    /* We want to verify that szPage and szExtra are the same for pOther
+    ** and pCache.  Assert that we can verify this by comparing sums. */
+    assert( (pCache->szPage & (pCache->szPage-1))==0 && pCache->szPage>=512 );
+    assert( pCache->szExtra<512 );
+    assert( (pOther->szPage & (pOther->szPage-1))==0 && pOther->szPage>=512 );
+    assert( pOther->szExtra<512 );
+
+    if( pOther->szPage+pOther->szExtra != pCache->szPage+pCache->szExtra ){
+      pcache1FreePage(pPage);
+      pPage = 0;
+    }else{
+      pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable);
+    }
+  }
+
+  /* Step 5. If a usable page buffer has still not been found, 
+  ** attempt to allocate a new one. 
+  */
+  if( !pPage ){
+    if( createFlag==1 ) sqlite3BeginBenignMalloc();
+    pPage = pcache1AllocPage(pCache);
+    if( createFlag==1 ) sqlite3EndBenignMalloc();
+  }
+
+  if( pPage ){
+    unsigned int h = iKey % pCache->nHash;
+    pCache->nPage++;
+    pPage->iKey = iKey;
+    pPage->pNext = pCache->apHash[h];
+    pPage->pCache = pCache;
+    pPage->pLruPrev = 0;
+    pPage->pLruNext = 0;
+    pPage->isPinned = 1;
+    *(void **)pPage->page.pExtra = 0;
+    pCache->apHash[h] = pPage;
+    if( iKey>pCache->iMaxKey ){
+      pCache->iMaxKey = iKey;
+    }
+  }
+  return pPage;
+}
+
 /*
 ** Implementation of the sqlite3_pcache.xFetch method. 
 **
@@ -39278,9 +40736,7 @@ static sqlite3_pcache_page *pcache1Fetch(
   unsigned int iKey, 
   int createFlag
 ){
-  unsigned int nPinned;
   PCache1 *pCache = (PCache1 *)p;
-  PGroup *pGroup;
   PgHdr1 *pPage = 0;
 
   assert( offsetof(PgHdr1,page)==0 );
@@ -39288,107 +40744,22 @@ static sqlite3_pcache_page *pcache1Fetch(
   assert( pCache->bPurgeable || pCache->nMin==0 );
   assert( pCache->bPurgeable==0 || pCache->nMin==10 );
   assert( pCache->nMin==0 || pCache->bPurgeable );
-  pcache1EnterMutex(pGroup = pCache->pGroup);
+  assert( pCache->nHash>0 );
+  pcache1EnterMutex(pCache->pGroup);
 
   /* Step 1: Search the hash table for an existing entry. */
-  if( pCache->nHash>0 ){
-    unsigned int h = iKey % pCache->nHash;
-    for(pPage=pCache->apHash[h]; pPage&&pPage->iKey!=iKey; pPage=pPage->pNext);
-  }
+  pPage = pCache->apHash[iKey % pCache->nHash];
+  while( pPage && pPage->iKey!=iKey ){ pPage = pPage->pNext; }
 
   /* Step 2: Abort if no existing page is found and createFlag is 0 */
   if( pPage ){
     if( !pPage->isPinned ) pcache1PinPage(pPage);
-    goto fetch_out;
-  }
-  if( createFlag==0 ){
-    goto fetch_out;
-  }
-
-  /* The pGroup local variable will normally be initialized by the
-  ** pcache1EnterMutex() macro above.  But if SQLITE_MUTEX_OMIT is defined,
-  ** then pcache1EnterMutex() is a no-op, so we have to initialize the
-  ** local variable here.  Delaying the initialization of pGroup is an
-  ** optimization:  The common case is to exit the module before reaching
-  ** this point.
-  */
-#ifdef SQLITE_MUTEX_OMIT
-  pGroup = pCache->pGroup;
-#endif
-
-  /* Step 3: Abort if createFlag is 1 but the cache is nearly full */
-  assert( pCache->nPage >= pCache->nRecyclable );
-  nPinned = pCache->nPage - pCache->nRecyclable;
-  assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage );
-  assert( pCache->n90pct == pCache->nMax*9/10 );
-  if( createFlag==1 && (
-        nPinned>=pGroup->mxPinned
-     || nPinned>=pCache->n90pct
-     || pcache1UnderMemoryPressure(pCache)
-  )){
-    goto fetch_out;
-  }
-
-  if( pCache->nPage>=pCache->nHash && pcache1ResizeHash(pCache) ){
-    goto fetch_out;
-  }
-  assert( pCache->nHash>0 && pCache->apHash );
-
-  /* Step 4. Try to recycle a page. */
-  if( pCache->bPurgeable && pGroup->pLruTail && (
-         (pCache->nPage+1>=pCache->nMax)
-      || pGroup->nCurrentPage>=pGroup->nMaxPage
-      || pcache1UnderMemoryPressure(pCache)
-  )){
-    PCache1 *pOther;
-    pPage = pGroup->pLruTail;
-    assert( pPage->isPinned==0 );
-    pcache1RemoveFromHash(pPage);
-    pcache1PinPage(pPage);
-    pOther = pPage->pCache;
-
-    /* We want to verify that szPage and szExtra are the same for pOther
-    ** and pCache.  Assert that we can verify this by comparing sums. */
-    assert( (pCache->szPage & (pCache->szPage-1))==0 && pCache->szPage>=512 );
-    assert( pCache->szExtra<512 );
-    assert( (pOther->szPage & (pOther->szPage-1))==0 && pOther->szPage>=512 );
-    assert( pOther->szExtra<512 );
-
-    if( pOther->szPage+pOther->szExtra != pCache->szPage+pCache->szExtra ){
-      pcache1FreePage(pPage);
-      pPage = 0;
-    }else{
-      pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable);
-    }
-  }
-
-  /* Step 5. If a usable page buffer has still not been found, 
-  ** attempt to allocate a new one. 
-  */
-  if( !pPage ){
-    if( createFlag==1 ) sqlite3BeginBenignMalloc();
-    pPage = pcache1AllocPage(pCache);
-    if( createFlag==1 ) sqlite3EndBenignMalloc();
-  }
-
-  if( pPage ){
-    unsigned int h = iKey % pCache->nHash;
-    pCache->nPage++;
-    pPage->iKey = iKey;
-    pPage->pNext = pCache->apHash[h];
-    pPage->pCache = pCache;
-    pPage->pLruPrev = 0;
-    pPage->pLruNext = 0;
-    pPage->isPinned = 1;
-    *(void **)pPage->page.pExtra = 0;
-    pCache->apHash[h] = pPage;
-  }
-
-fetch_out:
-  if( pPage && iKey>pCache->iMaxKey ){
-    pCache->iMaxKey = iKey;
+  }else if( createFlag ){
+    /* Steps 3, 4, and 5 implemented by this subroutine */
+    pPage = pcache1FetchStage2(pCache, iKey, createFlag);
   }
-  pcache1LeaveMutex(pGroup);
+  assert( pPage==0 || pCache->iMaxKey>=iKey );
+  pcache1LeaveMutex(pCache->pGroup);
   return (sqlite3_pcache_page*)pPage;
 }
 
@@ -39536,6 +40907,19 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void){
   sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods);
 }
 
+/*
+** Return the size of the header on each page of this PCACHE implementation.
+*/
+SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void){ return ROUND8(sizeof(PgHdr1)); }
+
+/*
+** Return the global mutex used by this PCACHE implementation.  The
+** sqlite3_status() routine needs access to this mutex.
+*/
+SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void){
+  return pcache1.mutex;
+}
+
 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
 /*
 ** This function is called to free superfluous dynamically allocated memory
@@ -39647,7 +41031,7 @@ SQLITE_PRIVATE void sqlite3PcacheStats(
 ** No INSERTs may occurs after a SMALLEST.  An assertion will fail if
 ** that is attempted.
 **
-** The cost of an INSERT is roughly constant.  (Sometime new memory
+** The cost of an INSERT is roughly constant.  (Sometimes new memory
 ** has to be allocated on an INSERT.)  The cost of a TEST with a new
 ** batch number is O(NlogN) where N is the number of elements in the RowSet.
 ** The cost of a TEST using the same batch number is O(logN).  The cost
@@ -40039,8 +41423,8 @@ SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){
 ** Check to see if element iRowid was inserted into the rowset as
 ** part of any insert batch prior to iBatch.  Return 1 or 0.
 **
-** If this is the first test of a new batch and if there exist entires
-** on pRowSet->pEntry, then sort those entires into the forest at
+** If this is the first test of a new batch and if there exist entries
+** on pRowSet->pEntry, then sort those entries into the forest at
 ** pRowSet->pForest so that they can be tested.
 */
 SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){
@@ -40322,12 +41706,12 @@ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal);
 ** Definition: Two databases (or the same database at two points it time)
 ** are said to be "logically equivalent" if they give the same answer to
 ** all queries.  Note in particular the content of freelist leaf
-** pages can be changed arbitarily without effecting the logical equivalence
+** pages can be changed arbitrarily without affecting the logical equivalence
 ** of the database.
 ** 
 ** (7) At any time, if any subset, including the empty set and the total set,
 **     of the unsynced changes to a rollback journal are removed and the 
-**     journal is rolled back, the resulting database file will be logical
+**     journal is rolled back, the resulting database file will be logically
 **     equivalent to the database file at the beginning of the transaction.
 ** 
 ** (8) When a transaction is rolled back, the xTruncate method of the VFS
@@ -40624,7 +42008,7 @@ int sqlite3PagerTrace=1;  /* True to enable tracing */
 **
 ** The exception is when the database file is unlocked as the pager moves
 ** from ERROR to OPEN state. At this point there may be a hot-journal file 
-** in the file-system that needs to be rolled back (as part of a OPEN->SHARED
+** in the file-system that needs to be rolled back (as part of an OPEN->SHARED
 ** transition, by the same pager or any other). If the call to xUnlock()
 ** fails at this point and the pager is left holding an EXCLUSIVE lock, this
 ** can confuse the call to xCheckReservedLock() call made later as part
@@ -40707,7 +42091,7 @@ struct PagerSavepoint {
 #define SPILLFLAG_NOSYNC      0x04      /* Spill is ok, but do not sync */
 
 /*
-** A open page cache is an instance of struct Pager. A description of
+** An open page cache is an instance of struct Pager. A description of
 ** some of the more important member variables follows:
 **
 ** eState
@@ -40879,7 +42263,7 @@ struct Pager {
 
   /**************************************************************************
   ** The following block contains those class members that change during
-  ** routine opertion.  Class members not in this block are either fixed
+  ** routine operation.  Class members not in this block are either fixed
   ** when the pager is first created or else only change when there is a
   ** significant mode change (such as changing the page_size, locking_mode,
   ** or the journal_mode).  From another view, these class members describe
@@ -40892,6 +42276,8 @@ struct Pager {
   u8 setMaster;               /* True if a m-j name has been written to jrnl */
   u8 doNotSpill;              /* Do not spill the cache when non-zero */
   u8 subjInMemory;            /* True to use in-memory sub-journals */
+  u8 bUseFetch;               /* True to use xFetch() */
+  u8 hasBeenUsed;             /* True if any content previously read from this pager*/
   Pgno dbSize;                /* Number of pages in the database */
   Pgno dbOrigSize;            /* dbSize before the current transaction */
   Pgno dbFileSize;            /* Number of pages in the database file */
@@ -40909,9 +42295,9 @@ struct Pager {
   sqlite3_backup *pBackup;    /* Pointer to list of ongoing backup processes */
   PagerSavepoint *aSavepoint; /* Array of active savepoints */
   int nSavepoint;             /* Number of elements in aSavepoint[] */
+  u32 iDataVersion;           /* Changes whenever database content changes */
   char dbFileVers[16];        /* Changes whenever database file changes */
 
-  u8 bUseFetch;               /* True to use xFetch() */
   int nMmapOut;               /* Number of mmap pages currently outstanding */
   sqlite3_int64 szMmap;       /* Desired maximum mmap size */
   PgHdr *pMmapFreelist;       /* List of free mmap page headers (pDirty) */
@@ -41924,29 +43310,23 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){
 }
 
 /*
-** Find a page in the hash table given its page number. Return
-** a pointer to the page or NULL if the requested page is not 
-** already in memory.
-*/
-static PgHdr *pager_lookup(Pager *pPager, Pgno pgno){
-  PgHdr *p = 0;                     /* Return value */
-
-  /* It is not possible for a call to PcacheFetch() with createFlag==0 to
-  ** fail, since no attempt to allocate dynamic memory will be made.
-  */
-  (void)sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &p);
-  return p;
-}
-
-/*
 ** Discard the entire contents of the in-memory page-cache.
 */
 static void pager_reset(Pager *pPager){
+  pPager->iDataVersion++;
   sqlite3BackupRestart(pPager->pBackup);
   sqlite3PcacheClear(pPager->pPCache);
 }
 
 /*
+** Return the pPager->iDataVersion value
+*/
+SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager *pPager){
+  assert( pPager->eState>PAGER_OPEN );
+  return pPager->iDataVersion;
+}
+
+/*
 ** Free all structures in the Pager.aSavepoint[] array and set both
 ** Pager.aSavepoint and Pager.nSavepoint to zero. Close the sub-journal
 ** if it is open and the pager is not in exclusive mode.
@@ -42202,6 +43582,14 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
         rc = SQLITE_OK;
       }else{
         rc = sqlite3OsTruncate(pPager->jfd, 0);
+        if( rc==SQLITE_OK && pPager->fullSync ){
+          /* Make sure the new file size is written into the inode right away.
+          ** Otherwise the journal might resurrect following a power loss and
+          ** cause the last transaction to roll back.  See
+          ** https://bugzilla.mozilla.org/show_bug.cgi?id=1072773
+          */
+          rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags);
+        }
       }
       pPager->journalOff = 0;
     }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST
@@ -42230,7 +43618,7 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
 #ifdef SQLITE_CHECK_PAGES
   sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash);
   if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){
-    PgHdr *p = pager_lookup(pPager, 1);
+    PgHdr *p = sqlite3PagerLookup(pPager, 1);
     if( p ){
       p->pageHash = 0;
       sqlite3PagerUnrefNotNull(p);
@@ -42509,7 +43897,7 @@ static int pager_playback_one_page(
   if( pagerUseWal(pPager) ){
     pPg = 0;
   }else{
-    pPg = pager_lookup(pPager, pgno);
+    pPg = sqlite3PagerLookup(pPager, pgno);
   }
   assert( pPg || !MEMDB );
   assert( pPager->eState!=PAGER_OPEN || pPg==0 );
@@ -42689,7 +44077,7 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){
   rc = sqlite3OsFileSize(pMaster, &nMasterJournal);
   if( rc!=SQLITE_OK ) goto delmaster_out;
   nMasterPtr = pVfs->mxPathname+1;
-  zMasterJournal = sqlite3Malloc((int)nMasterJournal + nMasterPtr + 1);
+  zMasterJournal = sqlite3Malloc(nMasterJournal + nMasterPtr + 1);
   if( !zMasterJournal ){
     rc = SQLITE_NOMEM;
     goto delmaster_out;
@@ -42758,7 +44146,7 @@ delmaster_out:
 ** If the file on disk is currently larger than nPage pages, then use the VFS
 ** xTruncate() method to truncate it.
 **
-** Or, it might might be the case that the file on disk is smaller than 
+** Or, it might be the case that the file on disk is smaller than 
 ** nPage pages. Some operating system implementations can get confused if 
 ** you try to truncate a file to some size that is larger than it 
 ** currently is, so detect this case and write a single zero byte to 
@@ -42817,7 +44205,7 @@ SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *pFile){
 /*
 ** Set the value of the Pager.sectorSize variable for the given
 ** pager based on the value returned by the xSectorSize method
-** of the open database file. The sector size will be used used 
+** of the open database file. The sector size will be used 
 ** to determine the size and alignment of journal header and 
 ** master journal pointers within created journal files.
 **
@@ -43152,7 +44540,7 @@ static int readDbPage(PgHdr *pPg, u32 iFrame){
       **
       ** For an encrypted database, the situation is more complex:  bytes
       ** 24..39 of the database are white noise.  But the probability of
-      ** white noising equaling 16 bytes of 0xff is vanishingly small so
+      ** white noise equaling 16 bytes of 0xff is vanishingly small so
       ** we should still be ok.
       */
       memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers));
@@ -43286,9 +44674,7 @@ static int pagerWalFrames(
 ){
   int rc;                         /* Return code */
   int nList;                      /* Number of pages in pList */
-#if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES)
   PgHdr *p;                       /* For looping over pages */
-#endif
 
   assert( pPager->pWal );
   assert( pList );
@@ -43305,7 +44691,6 @@ static int pagerWalFrames(
     ** any pages with page numbers greater than nTruncate into the WAL file.
     ** They will never be read by any client. So remove them from the pDirty
     ** list here. */
-    PgHdr *p;
     PgHdr **ppNext = &pList;
     nList = 0;
     for(p=pList; (*ppNext = p)!=0; p=p->pDirty){
@@ -43325,7 +44710,6 @@ static int pagerWalFrames(
       pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags
   );
   if( rc==SQLITE_OK && pPager->pBackup ){
-    PgHdr *p;
     for(p=pList; p; p=p->pDirty){
       sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData);
     }
@@ -43879,11 +45263,15 @@ SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nR
 
     if( rc==SQLITE_OK ){
       pager_reset(pPager);
-      pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
-      pPager->pageSize = pageSize;
+      rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
+    }
+    if( rc==SQLITE_OK ){
       sqlite3PageFree(pPager->pTmpSpace);
       pPager->pTmpSpace = pNew;
-      sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
+      pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
+      pPager->pageSize = pageSize;
+    }else{
+      sqlite3PageFree(pNew);
     }
   }
 
@@ -44017,7 +45405,7 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){
   int rc;                              /* Return code */
 
   /* Check that this is either a no-op (because the requested lock is 
-  ** already held, or one of the transistions that the busy-handler
+  ** already held), or one of the transitions that the busy-handler
   ** may be invoked during, according to the comment above
   ** sqlite3PagerSetBusyhandler().
   */
@@ -44136,7 +45524,7 @@ static int pagerAcquireMapPage(
   PgHdr **ppPage                  /* OUT: Acquired page object */
 ){
   PgHdr *p;                       /* Memory mapped page to return */
-
+  
   if( pPager->pMmapFreelist ){
     *ppPage = p = pPager->pMmapFreelist;
     pPager->pMmapFreelist = p->pDirty;
@@ -44645,8 +46033,8 @@ static int pagerStress(void *p, PgHdr *pPg){
   ** a rollback or by user request, respectively.
   **
   ** Spilling is also prohibited when in an error state since that could
-  ** lead to database corruption.   In the current implementaton it 
-  ** is impossible for sqlite3PcacheFetch() to be called with createFlag==1
+  ** lead to database corruption.   In the current implementation it 
+  ** is impossible for sqlite3PcacheFetch() to be called with createFlag==3
   ** while in the error state, hence it is impossible for this routine to
   ** be called in the error state.  Nevertheless, we include a NEVER()
   ** test for the error state as a safeguard against future changes.
@@ -44982,22 +46370,23 @@ act_like_temp_file:
     testcase( rc!=SQLITE_OK );
   }
 
-  /* If an error occurred in either of the blocks above, free the 
-  ** Pager structure and close the file.
+  /* Initialize the PCache object. */
+  if( rc==SQLITE_OK ){
+    assert( nExtra<1000 );
+    nExtra = ROUND8(nExtra);
+    rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb,
+                           !memDb?pagerStress:0, (void *)pPager, pPager->pPCache);
+  }
+
+  /* If an error occurred above, free the  Pager structure and close the file.
   */
   if( rc!=SQLITE_OK ){
-    assert( !pPager->pTmpSpace );
     sqlite3OsClose(pPager->fd);
+    sqlite3PageFree(pPager->pTmpSpace);
     sqlite3_free(pPager);
     return rc;
   }
 
-  /* Initialize the PCache object. */
-  assert( nExtra<1000 );
-  nExtra = ROUND8(nExtra);
-  sqlite3PcacheOpen(szPageDflt, nExtra, !memDb,
-                    !memDb?pagerStress:0, (void *)pPager, pPager->pPCache);
-
   PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename));
   IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename))
 
@@ -45184,7 +46573,7 @@ static int hasHotJournal(Pager *pPager, int *pExists){
             *pExists = (first!=0);
           }else if( rc==SQLITE_CANTOPEN ){
             /* If we cannot open the rollback journal file in order to see if
-            ** its has a zero header, that might be due to an I/O error, or
+            ** it has a zero header, that might be due to an I/O error, or
             ** it might be due to the race condition described above and in
             ** ticket #3883.  Either way, assume that the journal is hot.
             ** This might be a false positive.  But if it is, then the
@@ -45366,16 +46755,12 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
       );
     }
 
-    if( !pPager->tempFile && (
-        pPager->pBackup 
-     || sqlite3PcachePagecount(pPager->pPCache)>0 
-     || USEFETCH(pPager)
-    )){
-      /* The shared-lock has just been acquired on the database file
-      ** and there are already pages in the cache (from a previous
-      ** read or write transaction).  Check to see if the database
-      ** has been modified.  If the database has changed, flush the
-      ** cache.
+    if( !pPager->tempFile && pPager->hasBeenUsed ){
+      /* The shared-lock has just been acquired then check to
+      ** see if the database has been modified.  If the database has changed,
+      ** flush the cache.  The pPager->hasBeenUsed flag prevents this from
+      ** occurring on the very first access to a file, in order to save a
+      ** single unnecessary sqlite3OsRead() call at the start-up.
       **
       ** Database changes is detected by looking at 15 bytes beginning
       ** at offset 24 into the file.  The first 4 of these 16 bytes are
@@ -45540,13 +46925,13 @@ SQLITE_PRIVATE int sqlite3PagerAcquire(
   if( pgno==0 ){
     return SQLITE_CORRUPT_BKPT;
   }
+  pPager->hasBeenUsed = 1;
 
   /* If the pager is in the error state, return an error immediately. 
   ** Otherwise, request the page from the PCache layer. */
   if( pPager->errCode!=SQLITE_OK ){
     rc = pPager->errCode;
   }else{
-
     if( bMmapOk && pagerUseWal(pPager) ){
       rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
       if( rc!=SQLITE_OK ) goto pager_acquire_err;
@@ -45561,7 +46946,7 @@ SQLITE_PRIVATE int sqlite3PagerAcquire(
 
       if( rc==SQLITE_OK && pData ){
         if( pPager->eState>PAGER_READER ){
-          (void)sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &pPg);
+          pPg = sqlite3PagerLookup(pPager, pgno);
         }
         if( pPg==0 ){
           rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
@@ -45579,7 +46964,16 @@ SQLITE_PRIVATE int sqlite3PagerAcquire(
       }
     }
 
-    rc = sqlite3PcacheFetch(pPager->pPCache, pgno, 1, ppPage);
+    {
+      sqlite3_pcache_page *pBase;
+      pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3);
+      if( pBase==0 ){
+        rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase);
+        if( rc!=SQLITE_OK ) goto pager_acquire_err;
+      }
+      pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase);
+      if( pPg==0 ) rc = SQLITE_NOMEM;
+    }
   }
 
   if( rc!=SQLITE_OK ){
@@ -45676,13 +47070,13 @@ pager_acquire_err:
 ** has ever happened.
 */
 SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
-  PgHdr *pPg = 0;
+  sqlite3_pcache_page *pPage;
   assert( pPager!=0 );
   assert( pgno!=0 );
   assert( pPager->pPCache!=0 );
-  assert( pPager->eState>=PAGER_READER && pPager->eState!=PAGER_ERROR );
-  sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &pPg);
-  return pPg;
+  pPage = sqlite3PcacheFetch(pPager->pPCache, pgno, 0);
+  assert( pPage==0 || pPager->hasBeenUsed );
+  return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage);
 }
 
 /*
@@ -46019,109 +47413,120 @@ static int pager_write(PgHdr *pPg){
 }
 
 /*
-** Mark a data page as writeable. This routine must be called before 
-** making changes to a page. The caller must check the return value 
-** of this function and be careful not to change any page data unless 
-** this routine returns SQLITE_OK.
-**
-** The difference between this function and pager_write() is that this
-** function also deals with the special case where 2 or more pages
-** fit on a single disk sector. In this case all co-resident pages
-** must have been written to the journal file before returning.
+** This is a variant of sqlite3PagerWrite() that runs when the sector size
+** is larger than the page size.  SQLite makes the (reasonable) assumption that
+** all bytes of a sector are written together by hardware.  Hence, all bytes of
+** a sector need to be journalled in case of a power loss in the middle of
+** a write.
 **
-** If an error occurs, SQLITE_NOMEM or an IO error code is returned
-** as appropriate. Otherwise, SQLITE_OK.
+** Usually, the sector size is less than or equal to the page size, in which
+** case pages can be individually written.  This routine only runs in the exceptional
+** case where the page size is smaller than the sector size.
 */
-SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){
-  int rc = SQLITE_OK;
-
-  PgHdr *pPg = pDbPage;
-  Pager *pPager = pPg->pPager;
+static SQLITE_NOINLINE int pagerWriteLargeSector(PgHdr *pPg){
+  int rc = SQLITE_OK;            /* Return code */
+  Pgno nPageCount;               /* Total number of pages in database file */
+  Pgno pg1;                      /* First page of the sector pPg is located on. */
+  int nPage = 0;                 /* Number of pages starting at pg1 to journal */
+  int ii;                        /* Loop counter */
+  int needSync = 0;              /* True if any page has PGHDR_NEED_SYNC */
+  Pager *pPager = pPg->pPager;   /* The pager that owns pPg */
+  Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
 
-  assert( (pPg->flags & PGHDR_MMAP)==0 );
-  assert( pPager->eState>=PAGER_WRITER_LOCKED );
-  assert( pPager->eState!=PAGER_ERROR );
-  assert( assert_pager_state(pPager) );
+  /* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow
+  ** a journal header to be written between the pages journaled by
+  ** this function.
+  */
+  assert( !MEMDB );
+  assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)==0 );
+  pPager->doNotSpill |= SPILLFLAG_NOSYNC;
 
-  if( pPager->sectorSize > (u32)pPager->pageSize ){
-    Pgno nPageCount;          /* Total number of pages in database file */
-    Pgno pg1;                 /* First page of the sector pPg is located on. */
-    int nPage = 0;            /* Number of pages starting at pg1 to journal */
-    int ii;                   /* Loop counter */
-    int needSync = 0;         /* True if any page has PGHDR_NEED_SYNC */
-    Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
-
-    /* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow
-    ** a journal header to be written between the pages journaled by
-    ** this function.
-    */
-    assert( !MEMDB );
-    assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)==0 );
-    pPager->doNotSpill |= SPILLFLAG_NOSYNC;
+  /* This trick assumes that both the page-size and sector-size are
+  ** an integer power of 2. It sets variable pg1 to the identifier
+  ** of the first page of the sector pPg is located on.
+  */
+  pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1;
 
-    /* This trick assumes that both the page-size and sector-size are
-    ** an integer power of 2. It sets variable pg1 to the identifier
-    ** of the first page of the sector pPg is located on.
-    */
-    pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1;
+  nPageCount = pPager->dbSize;
+  if( pPg->pgno>nPageCount ){
+    nPage = (pPg->pgno - pg1)+1;
+  }else if( (pg1+nPagePerSector-1)>nPageCount ){
+    nPage = nPageCount+1-pg1;
+  }else{
+    nPage = nPagePerSector;
+  }
+  assert(nPage>0);
+  assert(pg1<=pPg->pgno);
+  assert((pg1+nPage)>pPg->pgno);
 
-    nPageCount = pPager->dbSize;
-    if( pPg->pgno>nPageCount ){
-      nPage = (pPg->pgno - pg1)+1;
-    }else if( (pg1+nPagePerSector-1)>nPageCount ){
-      nPage = nPageCount+1-pg1;
-    }else{
-      nPage = nPagePerSector;
-    }
-    assert(nPage>0);
-    assert(pg1<=pPg->pgno);
-    assert((pg1+nPage)>pPg->pgno);
-
-    for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){
-      Pgno pg = pg1+ii;
-      PgHdr *pPage;
-      if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){
-        if( pg!=PAGER_MJ_PGNO(pPager) ){
-          rc = sqlite3PagerGet(pPager, pg, &pPage);
-          if( rc==SQLITE_OK ){
-            rc = pager_write(pPage);
-            if( pPage->flags&PGHDR_NEED_SYNC ){
-              needSync = 1;
-            }
-            sqlite3PagerUnrefNotNull(pPage);
+  for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){
+    Pgno pg = pg1+ii;
+    PgHdr *pPage;
+    if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){
+      if( pg!=PAGER_MJ_PGNO(pPager) ){
+        rc = sqlite3PagerGet(pPager, pg, &pPage);
+        if( rc==SQLITE_OK ){
+          rc = pager_write(pPage);
+          if( pPage->flags&PGHDR_NEED_SYNC ){
+            needSync = 1;
           }
+          sqlite3PagerUnrefNotNull(pPage);
         }
-      }else if( (pPage = pager_lookup(pPager, pg))!=0 ){
-        if( pPage->flags&PGHDR_NEED_SYNC ){
-          needSync = 1;
-        }
-        sqlite3PagerUnrefNotNull(pPage);
       }
+    }else if( (pPage = sqlite3PagerLookup(pPager, pg))!=0 ){
+      if( pPage->flags&PGHDR_NEED_SYNC ){
+        needSync = 1;
+      }
+      sqlite3PagerUnrefNotNull(pPage);
     }
+  }
 
-    /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages 
-    ** starting at pg1, then it needs to be set for all of them. Because
-    ** writing to any of these nPage pages may damage the others, the
-    ** journal file must contain sync()ed copies of all of them
-    ** before any of them can be written out to the database file.
-    */
-    if( rc==SQLITE_OK && needSync ){
-      assert( !MEMDB );
-      for(ii=0; ii<nPage; ii++){
-        PgHdr *pPage = pager_lookup(pPager, pg1+ii);
-        if( pPage ){
-          pPage->flags |= PGHDR_NEED_SYNC;
-          sqlite3PagerUnrefNotNull(pPage);
-        }
+  /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages 
+  ** starting at pg1, then it needs to be set for all of them. Because
+  ** writing to any of these nPage pages may damage the others, the
+  ** journal file must contain sync()ed copies of all of them
+  ** before any of them can be written out to the database file.
+  */
+  if( rc==SQLITE_OK && needSync ){
+    assert( !MEMDB );
+    for(ii=0; ii<nPage; ii++){
+      PgHdr *pPage = sqlite3PagerLookup(pPager, pg1+ii);
+      if( pPage ){
+        pPage->flags |= PGHDR_NEED_SYNC;
+        sqlite3PagerUnrefNotNull(pPage);
       }
     }
+  }
+
+  assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)!=0 );
+  pPager->doNotSpill &= ~SPILLFLAG_NOSYNC;
+  return rc;
+}
 
-    assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)!=0 );
-    pPager->doNotSpill &= ~SPILLFLAG_NOSYNC;
+/*
+** Mark a data page as writeable. This routine must be called before 
+** making changes to a page. The caller must check the return value 
+** of this function and be careful not to change any page data unless 
+** this routine returns SQLITE_OK.
+**
+** The difference between this function and pager_write() is that this
+** function also deals with the special case where 2 or more pages
+** fit on a single disk sector. In this case all co-resident pages
+** must have been written to the journal file before returning.
+**
+** If an error occurs, SQLITE_NOMEM or an IO error code is returned
+** as appropriate. Otherwise, SQLITE_OK.
+*/
+SQLITE_PRIVATE int sqlite3PagerWrite(PgHdr *pPg){
+  assert( (pPg->flags & PGHDR_MMAP)==0 );
+  assert( pPg->pPager->eState>=PAGER_WRITER_LOCKED );
+  assert( pPg->pPager->eState!=PAGER_ERROR );
+  assert( assert_pager_state(pPg->pPager) );
+  if( pPg->pPager->sectorSize > (u32)pPg->pPager->pageSize ){
+    return pagerWriteLargeSector(pPg);
   }else{
-    rc = pager_write(pDbPage);
+    return pager_write(pPg);
   }
-  return rc;
 }
 
 /*
@@ -46537,6 +47942,7 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager *pPager){
   }
 
   PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
+  pPager->iDataVersion++;
   rc = pager_end_transaction(pPager, pPager->setMaster, 1);
   return pager_error(pPager, rc);
 }
@@ -47017,7 +48423,7 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i
   ** for the page moved there.
   */
   pPg->flags &= ~PGHDR_NEED_SYNC;
-  pPgOld = pager_lookup(pPager, pgno);
+  pPgOld = sqlite3PagerLookup(pPager, pgno);
   assert( !pPgOld || pPgOld->nRef==1 );
   if( pPgOld ){
     pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
@@ -47078,6 +48484,18 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i
 #endif
 
 /*
+** The page handle passed as the first argument refers to a dirty page 
+** with a page number other than iNew. This function changes the page's 
+** page number to iNew and sets the value of the PgHdr.flags field to 
+** the value passed as the third parameter.
+*/
+SQLITE_PRIVATE void sqlite3PagerRekey(DbPage *pPg, Pgno iNew, u16 flags){
+  assert( pPg->pgno!=iNew );
+  pPg->flags = flags;
+  sqlite3PcacheMove(pPg, iNew);
+}
+
+/*
 ** Return a pointer to the data for the specified page.
 */
 SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *pPg){
@@ -47222,6 +48640,8 @@ SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){
         }
         assert( state==pPager->eState );
       }
+    }else if( eMode==PAGER_JOURNALMODE_OFF ){
+      sqlite3OsClose(pPager->jfd);
     }
   }
 
@@ -47293,7 +48713,8 @@ SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog,
   int rc = SQLITE_OK;
   if( pPager->pWal ){
     rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
-        pPager->xBusyHandler, pPager->pBusyHandlerArg,
+        (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
+        pPager->pBusyHandlerArg,
         pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
         pnLog, pnCkpt
     );
@@ -47470,11 +48891,12 @@ SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager){
 ** is empty, return 0.
 */
 SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){
-  assert( pPager->eState==PAGER_READER );
+  assert( pPager->eState>=PAGER_READER );
   return sqlite3WalFramesize(pPager->pWal);
 }
 #endif
 
+
 #endif /* SQLITE_OMIT_DISKIO */
 
 /************** End of pager.c ***********************************************/
@@ -48002,7 +49424,7 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
   if( pWal->nWiData<=iPage ){
     int nByte = sizeof(u32*)*(iPage+1);
     volatile u32 **apNew;
-    apNew = (volatile u32 **)sqlite3_realloc((void *)pWal->apWiData, nByte);
+    apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
     if( !apNew ){
       *ppPage = 0;
       return SQLITE_NOMEM;
@@ -48054,7 +49476,7 @@ static volatile WalIndexHdr *walIndexHdr(Wal *pWal){
 ** The argument to this macro must be of type u32. On a little-endian
 ** architecture, it returns the u32 value that results from interpreting
 ** the 4 bytes as a big-endian value. On a big-endian architecture, it
-** returns the value that would be produced by intepreting the 4 bytes
+** returns the value that would be produced by interpreting the 4 bytes
 ** of the input value as a little-endian integer.
 */
 #define BYTESWAP32(x) ( \
@@ -48268,9 +49690,10 @@ static void walUnlockShared(Wal *pWal, int lockIdx){
                          SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED);
   WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx)));
 }
-static int walLockExclusive(Wal *pWal, int lockIdx, int n){
+static int walLockExclusive(Wal *pWal, int lockIdx, int n, int fBlock){
   int rc;
   if( pWal->exclusiveMode ) return SQLITE_OK;
+  if( fBlock ) sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_WAL_BLOCK, 0);
   rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
                         SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE);
   WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal,
@@ -48468,7 +49891,7 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
     assert( idx <= HASHTABLE_NSLOT/2 + 1 );
     
     /* If this is the first entry to be added to this hash-table, zero the
-    ** entire hash table and aPgno[] array before proceding. 
+    ** entire hash table and aPgno[] array before proceeding. 
     */
     if( idx==1 ){
       int nByte = (int)((u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]);
@@ -48556,7 +49979,7 @@ static int walIndexRecover(Wal *pWal){
   assert( pWal->writeLock );
   iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock;
   nLock = SQLITE_SHM_NLOCK - iLock;
-  rc = walLockExclusive(pWal, iLock, nLock);
+  rc = walLockExclusive(pWal, iLock, nLock, 0);
   if( rc ){
     return rc;
   }
@@ -48626,7 +50049,7 @@ static int walIndexRecover(Wal *pWal){
 
     /* Malloc a buffer to read frames into. */
     szFrame = szPage + WAL_FRAME_HDRSIZE;
-    aFrame = (u8 *)sqlite3_malloc(szFrame);
+    aFrame = (u8 *)sqlite3_malloc64(szFrame);
     if( !aFrame ){
       rc = SQLITE_NOMEM;
       goto recovery_error;
@@ -48984,7 +50407,7 @@ static void walMergesort(
 ** Free an iterator allocated by walIteratorInit().
 */
 static void walIteratorFree(WalIterator *p){
-  sqlite3ScratchFree(p);
+  sqlite3_free(p);
 }
 
 /*
@@ -49019,7 +50442,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
   nByte = sizeof(WalIterator) 
         + (nSegment-1)*sizeof(struct WalSegment)
         + iLast*sizeof(ht_slot);
-  p = (WalIterator *)sqlite3ScratchMalloc(nByte);
+  p = (WalIterator *)sqlite3_malloc64(nByte);
   if( !p ){
     return SQLITE_NOMEM;
   }
@@ -49029,7 +50452,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
   /* Allocate temporary space used by the merge-sort routine. This block
   ** of memory will be freed before this function returns.
   */
-  aTmp = (ht_slot *)sqlite3ScratchMalloc(
+  aTmp = (ht_slot *)sqlite3_malloc64(
       sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
   );
   if( !aTmp ){
@@ -49066,7 +50489,7 @@ static int walIteratorInit(Wal *pWal, WalIterator **pp){
       p->aSegment[i].aPgno = (u32 *)aPgno;
     }
   }
-  sqlite3ScratchFree(aTmp);
+  sqlite3_free(aTmp);
 
   if( rc!=SQLITE_OK ){
     walIteratorFree(p);
@@ -49090,7 +50513,7 @@ static int walBusyLock(
 ){
   int rc;
   do {
-    rc = walLockExclusive(pWal, lockIdx, n);
+    rc = walLockExclusive(pWal, lockIdx, n, 0);
   }while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) );
   return rc;
 }
@@ -49104,6 +50527,38 @@ static int walPagesize(Wal *pWal){
 }
 
 /*
+** The following is guaranteed when this function is called:
+**
+**   a) the WRITER lock is held,
+**   b) the entire log file has been checkpointed, and
+**   c) any existing readers are reading exclusively from the database
+**      file - there are no readers that may attempt to read a frame from
+**      the log file.
+**
+** This function updates the shared-memory structures so that the next
+** client to write to the database (which may be this one) does so by
+** writing frames into the start of the log file.
+**
+** The value of parameter salt1 is used as the aSalt[1] value in the 
+** new wal-index header. It should be passed a pseudo-random value (i.e. 
+** one obtained from sqlite3_randomness()).
+*/
+static void walRestartHdr(Wal *pWal, u32 salt1){
+  volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
+  int i;                          /* Loop counter */
+  u32 *aSalt = pWal->hdr.aSalt;   /* Big-endian salt values */
+  pWal->nCkpt++;
+  pWal->hdr.mxFrame = 0;
+  sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
+  memcpy(&pWal->hdr.aSalt[1], &salt1, 4);
+  walIndexWriteHdr(pWal);
+  pInfo->nBackfill = 0;
+  pInfo->aReadMark[1] = 0;
+  for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
+  assert( pInfo->aReadMark[0]==0 );
+}
+
+/*
 ** Copy as much content as we can from the WAL back into the database file
 ** in response to an sqlite3_wal_checkpoint() request or the equivalent.
 **
@@ -49126,7 +50581,7 @@ static int walPagesize(Wal *pWal){
 ** database file.
 **
 ** This routine uses and updates the nBackfill field of the wal-index header.
-** This is the only routine tha will increase the value of nBackfill.  
+** This is the only routine that will increase the value of nBackfill.  
 ** (A WAL reset or recovery will revert nBackfill to zero, but not increase
 ** its value.)
 **
@@ -49137,12 +50592,12 @@ static int walPagesize(Wal *pWal){
 static int walCheckpoint(
   Wal *pWal,                      /* Wal connection */
   int eMode,                      /* One of PASSIVE, FULL or RESTART */
-  int (*xBusyCall)(void*),        /* Function to call when busy */
+  int (*xBusy)(void*),            /* Function to call when busy */
   void *pBusyArg,                 /* Context argument for xBusyHandler */
   int sync_flags,                 /* Flags for OsSync() (or 0) */
   u8 *zBuf                        /* Temporary buffer to use */
 ){
-  int rc;                         /* Return code */
+  int rc = SQLITE_OK;             /* Return code */
   int szPage;                     /* Database page-size */
   WalIterator *pIter = 0;         /* Wal iterator context */
   u32 iDbpage = 0;                /* Next database page to write */
@@ -49151,123 +50606,154 @@ static int walCheckpoint(
   u32 mxPage;                     /* Max database page to write */
   int i;                          /* Loop counter */
   volatile WalCkptInfo *pInfo;    /* The checkpoint status information */
-  int (*xBusy)(void*) = 0;        /* Function to call when waiting for locks */
 
   szPage = walPagesize(pWal);
   testcase( szPage<=32768 );
   testcase( szPage>=65536 );
   pInfo = walCkptInfo(pWal);
-  if( pInfo->nBackfill>=pWal->hdr.mxFrame ) return SQLITE_OK;
+  if( pInfo->nBackfill<pWal->hdr.mxFrame ){
 
-  /* Allocate the iterator */
-  rc = walIteratorInit(pWal, &pIter);
-  if( rc!=SQLITE_OK ){
-    return rc;
-  }
-  assert( pIter );
+    /* Allocate the iterator */
+    rc = walIteratorInit(pWal, &pIter);
+    if( rc!=SQLITE_OK ){
+      return rc;
+    }
+    assert( pIter );
 
-  if( eMode!=SQLITE_CHECKPOINT_PASSIVE ) xBusy = xBusyCall;
+    /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
+    ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
+    assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
 
-  /* Compute in mxSafeFrame the index of the last frame of the WAL that is
-  ** safe to write into the database.  Frames beyond mxSafeFrame might
-  ** overwrite database pages that are in use by active readers and thus
-  ** cannot be backfilled from the WAL.
-  */
-  mxSafeFrame = pWal->hdr.mxFrame;
-  mxPage = pWal->hdr.nPage;
-  for(i=1; i<WAL_NREADER; i++){
-    u32 y = pInfo->aReadMark[i];
-    if( mxSafeFrame>y ){
-      assert( y<=pWal->hdr.mxFrame );
-      rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
-      if( rc==SQLITE_OK ){
-        pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
-        walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
-      }else if( rc==SQLITE_BUSY ){
-        mxSafeFrame = y;
-        xBusy = 0;
-      }else{
-        goto walcheckpoint_out;
+    /* Compute in mxSafeFrame the index of the last frame of the WAL that is
+    ** safe to write into the database.  Frames beyond mxSafeFrame might
+    ** overwrite database pages that are in use by active readers and thus
+    ** cannot be backfilled from the WAL.
+    */
+    mxSafeFrame = pWal->hdr.mxFrame;
+    mxPage = pWal->hdr.nPage;
+    for(i=1; i<WAL_NREADER; i++){
+      /* Thread-sanitizer reports that the following is an unsafe read,
+      ** as some other thread may be in the process of updating the value
+      ** of the aReadMark[] slot. The assumption here is that if that is
+      ** happening, the other client may only be increasing the value,
+      ** not decreasing it. So assuming either that either the "old" or
+      ** "new" version of the value is read, and not some arbitrary value
+      ** that would never be written by a real client, things are still 
+      ** safe.  */
+      u32 y = pInfo->aReadMark[i];
+      if( mxSafeFrame>y ){
+        assert( y<=pWal->hdr.mxFrame );
+        rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
+        if( rc==SQLITE_OK ){
+          pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
+          walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
+        }else if( rc==SQLITE_BUSY ){
+          mxSafeFrame = y;
+          xBusy = 0;
+        }else{
+          goto walcheckpoint_out;
+        }
       }
     }
-  }
 
-  if( pInfo->nBackfill<mxSafeFrame
-   && (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0), 1))==SQLITE_OK
-  ){
-    i64 nSize;                    /* Current size of database file */
-    u32 nBackfill = pInfo->nBackfill;
-
-    /* Sync the WAL to disk */
-    if( sync_flags ){
-      rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
-    }
+    if( pInfo->nBackfill<mxSafeFrame
+     && (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0),1))==SQLITE_OK
+    ){
+      i64 nSize;                    /* Current size of database file */
+      u32 nBackfill = pInfo->nBackfill;
 
-    /* If the database may grow as a result of this checkpoint, hint
-    ** about the eventual size of the db file to the VFS layer.
-    */
-    if( rc==SQLITE_OK ){
-      i64 nReq = ((i64)mxPage * szPage);
-      rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
-      if( rc==SQLITE_OK && nSize<nReq ){
-        sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
+      /* Sync the WAL to disk */
+      if( sync_flags ){
+        rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
       }
-    }
 
+      /* If the database may grow as a result of this checkpoint, hint
+      ** about the eventual size of the db file to the VFS layer.
+      */
+      if( rc==SQLITE_OK ){
+        i64 nReq = ((i64)mxPage * szPage);
+        rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
+        if( rc==SQLITE_OK && nSize<nReq ){
+          sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
+        }
+      }
 
-    /* Iterate through the contents of the WAL, copying data to the db file. */
-    while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
-      i64 iOffset;
-      assert( walFramePgno(pWal, iFrame)==iDbpage );
-      if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ) continue;
-      iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
-      /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
-      rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset);
-      if( rc!=SQLITE_OK ) break;
-      iOffset = (iDbpage-1)*(i64)szPage;
-      testcase( IS_BIG_INT(iOffset) );
-      rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
-      if( rc!=SQLITE_OK ) break;
-    }
 
-    /* If work was actually accomplished... */
-    if( rc==SQLITE_OK ){
-      if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
-        i64 szDb = pWal->hdr.nPage*(i64)szPage;
-        testcase( IS_BIG_INT(szDb) );
-        rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
-        if( rc==SQLITE_OK && sync_flags ){
-          rc = sqlite3OsSync(pWal->pDbFd, sync_flags);
+      /* Iterate through the contents of the WAL, copying data to the db file */
+      while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
+        i64 iOffset;
+        assert( walFramePgno(pWal, iFrame)==iDbpage );
+        if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){
+          continue;
         }
+        iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
+        /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
+        rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset);
+        if( rc!=SQLITE_OK ) break;
+        iOffset = (iDbpage-1)*(i64)szPage;
+        testcase( IS_BIG_INT(iOffset) );
+        rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
+        if( rc!=SQLITE_OK ) break;
       }
+
+      /* If work was actually accomplished... */
       if( rc==SQLITE_OK ){
-        pInfo->nBackfill = mxSafeFrame;
+        if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
+          i64 szDb = pWal->hdr.nPage*(i64)szPage;
+          testcase( IS_BIG_INT(szDb) );
+          rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
+          if( rc==SQLITE_OK && sync_flags ){
+            rc = sqlite3OsSync(pWal->pDbFd, sync_flags);
+          }
+        }
+        if( rc==SQLITE_OK ){
+          pInfo->nBackfill = mxSafeFrame;
+        }
       }
-    }
 
-    /* Release the reader lock held while backfilling */
-    walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
-  }
+      /* Release the reader lock held while backfilling */
+      walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
+    }
 
-  if( rc==SQLITE_BUSY ){
-    /* Reset the return code so as not to report a checkpoint failure
-    ** just because there are active readers.  */
-    rc = SQLITE_OK;
+    if( rc==SQLITE_BUSY ){
+      /* Reset the return code so as not to report a checkpoint failure
+      ** just because there are active readers.  */
+      rc = SQLITE_OK;
+    }
   }
 
-  /* If this is an SQLITE_CHECKPOINT_RESTART operation, and the entire wal
-  ** file has been copied into the database file, then block until all
-  ** readers have finished using the wal file. This ensures that the next
-  ** process to write to the database restarts the wal file.
+  /* If this is an SQLITE_CHECKPOINT_RESTART or TRUNCATE operation, and the
+  ** entire wal file has been copied into the database file, then block 
+  ** until all readers have finished using the wal file. This ensures that 
+  ** the next process to write to the database restarts the wal file.
   */
   if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){
     assert( pWal->writeLock );
     if( pInfo->nBackfill<pWal->hdr.mxFrame ){
       rc = SQLITE_BUSY;
-    }else if( eMode==SQLITE_CHECKPOINT_RESTART ){
-      assert( mxSafeFrame==pWal->hdr.mxFrame );
+    }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){
+      u32 salt1;
+      sqlite3_randomness(4, &salt1);
+      assert( pInfo->nBackfill==pWal->hdr.mxFrame );
       rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1);
       if( rc==SQLITE_OK ){
+        if( eMode==SQLITE_CHECKPOINT_TRUNCATE ){
+          /* IMPLEMENTATION-OF: R-44699-57140 This mode works the same way as
+          ** SQLITE_CHECKPOINT_RESTART with the addition that it also
+          ** truncates the log file to zero bytes just prior to a
+          ** successful return.
+          **
+          ** In theory, it might be safe to do this without updating the
+          ** wal-index header in shared memory, as all subsequent reader or
+          ** writer clients should see that the entire log file has been
+          ** checkpointed and behave accordingly. This seems unsafe though,
+          ** as it would leave the system in a state where the contents of
+          ** the wal-index header do not match the contents of the 
+          ** file-system. To avoid this, update the wal-index header to
+          ** indicate that the log file contains zero valid frames.  */
+          walRestartHdr(pWal, salt1);
+          rc = sqlite3OsTruncate(pWal->pWalFd, 0);
+        }
         walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
       }
     }
@@ -49430,7 +50916,7 @@ static int walIndexTryHdr(Wal *pWal, int *pChanged){
 ** wal-index from the WAL before returning.
 **
 ** Set *pChanged to 1 if the wal-index header value in pWal->hdr is
-** changed by this opertion.  If pWal->hdr is unchanged, set *pChanged
+** changed by this operation.  If pWal->hdr is unchanged, set *pChanged
 ** to 0.
 **
 ** If the wal-index header is successfully read, return SQLITE_OK. 
@@ -49468,7 +50954,7 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
         walUnlockShared(pWal, WAL_WRITE_LOCK);
         rc = SQLITE_READONLY_RECOVERY;
       }
-    }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){
+    }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 1)) ){
       pWal->writeLock = 1;
       if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
         badHdr = walIndexTryHdr(pWal, pChanged);
@@ -49634,7 +51120,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
         ** may have been appended to the log before READ_LOCK(0) was obtained.
         ** When holding READ_LOCK(0), the reader ignores the entire log file,
         ** which implies that the database file contains a trustworthy
-        ** snapshoT. Since holding READ_LOCK(0) prevents a checkpoint from
+        ** snapshot. Since holding READ_LOCK(0) prevents a checkpoint from
         ** happening, this is usually correct.
         **
         ** However, if frames have been appended to the log (or if the log 
@@ -49674,7 +51160,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
      && (mxReadMark<pWal->hdr.mxFrame || mxI==0)
     ){
       for(i=1; i<WAL_NREADER; i++){
-        rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
+        rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1, 0);
         if( rc==SQLITE_OK ){
           mxReadMark = pInfo->aReadMark[i] = pWal->hdr.mxFrame;
           mxI = i;
@@ -49840,7 +51326,7 @@ SQLITE_PRIVATE int sqlite3WalFindFrame(
     for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){
       u32 iFrame = aHash[iKey] + iZero;
       if( iFrame<=iLast && aPgno[aHash[iKey]]==pgno ){
-        /* assert( iFrame>iRead ); -- not true if there is corruption */
+        assert( iFrame>iRead || CORRUPT_DB );
         iRead = iFrame;
       }
       if( (nCollide--)==0 ){
@@ -49930,7 +51416,7 @@ SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){
   /* Only one writer allowed at a time.  Get the write lock.  Return
   ** SQLITE_BUSY if unable.
   */
-  rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
+  rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 0);
   if( rc ){
     return rc;
   }
@@ -50005,7 +51491,6 @@ SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *p
     }
     if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal);
   }
-  assert( rc==SQLITE_OK );
   return rc;
 }
 
@@ -50054,7 +51539,6 @@ SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){
   return rc;
 }
 
-
 /*
 ** This function is called just before writing a set of frames to the log
 ** file (see sqlite3WalFrames()). It checks to see if, instead of appending
@@ -50077,7 +51561,7 @@ static int walRestartLog(Wal *pWal){
     if( pInfo->nBackfill>0 ){
       u32 salt1;
       sqlite3_randomness(4, &salt1);
-      rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
+      rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1, 0);
       if( rc==SQLITE_OK ){
         /* If all readers are using WAL_READ_LOCK(0) (in other words if no
         ** readers are currently using the WAL), then the transactions
@@ -50087,20 +51571,8 @@ static int walRestartLog(Wal *pWal){
         ** In theory it would be Ok to update the cache of the header only
         ** at this point. But updating the actual wal-index header is also
         ** safe and means there is no special case for sqlite3WalUndo()
-        ** to handle if this transaction is rolled back.
-        */
-        int i;                    /* Loop counter */
-        u32 *aSalt = pWal->hdr.aSalt;       /* Big-endian salt values */
-
-        pWal->nCkpt++;
-        pWal->hdr.mxFrame = 0;
-        sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
-        aSalt[1] = salt1;
-        walIndexWriteHdr(pWal);
-        pInfo->nBackfill = 0;
-        pInfo->aReadMark[1] = 0;
-        for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
-        assert( pInfo->aReadMark[0]==0 );
+        ** to handle if this transaction is rolled back.  */
+        walRestartHdr(pWal, salt1);
         walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
       }else if( rc!=SQLITE_BUSY ){
         return rc;
@@ -50302,7 +51774,7 @@ SQLITE_PRIVATE int sqlite3WalFrames(
   **
   ** Padding and syncing only occur if this set of frames complete a
   ** transaction and if PRAGMA synchronous=FULL.  If synchronous==NORMAL
-  ** or synchonous==OFF, then no padding or syncing are needed.
+  ** or synchronous==OFF, then no padding or syncing are needed.
   **
   ** If SQLITE_IOCAP_POWERSAFE_OVERWRITE is defined, then padding is not
   ** needed and only the sync is done.  If padding is needed, then the
@@ -50388,7 +51860,7 @@ SQLITE_PRIVATE int sqlite3WalFrames(
 */
 SQLITE_PRIVATE int sqlite3WalCheckpoint(
   Wal *pWal,                      /* Wal connection */
-  int eMode,                      /* PASSIVE, FULL or RESTART */
+  int eMode,                      /* PASSIVE, FULL, RESTART, or TRUNCATE */
   int (*xBusy)(void*),            /* Function to call when busy */
   void *pBusyArg,                 /* Context argument for xBusyHandler */
   int sync_flags,                 /* Flags to sync db file with (or 0) */
@@ -50400,29 +51872,42 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint(
   int rc;                         /* Return code */
   int isChanged = 0;              /* True if a new wal-index header is loaded */
   int eMode2 = eMode;             /* Mode to pass to walCheckpoint() */
+  int (*xBusy2)(void*) = xBusy;   /* Busy handler for eMode2 */
 
   assert( pWal->ckptLock==0 );
   assert( pWal->writeLock==0 );
 
+  /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
+  ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
+  assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
+
   if( pWal->readOnly ) return SQLITE_READONLY;
   WALTRACE(("WAL%p: checkpoint begins\n", pWal));
-  rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
+
+  /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive 
+  ** "checkpoint" lock on the database file. */
+  rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1, 0);
   if( rc ){
-    /* Usually this is SQLITE_BUSY meaning that another thread or process
-    ** is already running a checkpoint, or maybe a recovery.  But it might
-    ** also be SQLITE_IOERR. */
+    /* EVIDENCE-OF: R-10421-19736 If any other process is running a
+    ** checkpoint operation at the same time, the lock cannot be obtained and
+    ** SQLITE_BUSY is returned.
+    ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
+    ** it will not be invoked in this case.
+    */
+    testcase( rc==SQLITE_BUSY );
+    testcase( xBusy!=0 );
     return rc;
   }
   pWal->ckptLock = 1;
 
-  /* If this is a blocking-checkpoint, then obtain the write-lock as well
-  ** to prevent any writers from running while the checkpoint is underway.
-  ** This has to be done before the call to walIndexReadHdr() below.
+  /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
+  ** TRUNCATE modes also obtain the exclusive "writer" lock on the database
+  ** file.
   **
-  ** If the writer lock cannot be obtained, then a passive checkpoint is
-  ** run instead. Since the checkpointer is not holding the writer lock,
-  ** there is no point in blocking waiting for any readers. Assuming no 
-  ** other error occurs, this function will return SQLITE_BUSY to the caller.
+  ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
+  ** immediately, and a busy-handler is configured, it is invoked and the
+  ** writer lock retried until either the busy-handler returns 0 or the
+  ** lock is successfully obtained.
   */
   if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
     rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1);
@@ -50430,6 +51915,7 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint(
       pWal->writeLock = 1;
     }else if( rc==SQLITE_BUSY ){
       eMode2 = SQLITE_CHECKPOINT_PASSIVE;
+      xBusy2 = 0;
       rc = SQLITE_OK;
     }
   }
@@ -50447,7 +51933,7 @@ SQLITE_PRIVATE int sqlite3WalCheckpoint(
     if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
       rc = SQLITE_CORRUPT_BKPT;
     }else{
-      rc = walCheckpoint(pWal, eMode2, xBusy, pBusyArg, sync_flags, zBuf);
+      rc = walCheckpoint(pWal, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
     }
 
     /* If no error occurred, set the output variables. */
@@ -50605,7 +52091,7 @@ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** This file implements a external (disk-based) database using BTrees.
+** This file implements an external (disk-based) database using BTrees.
 ** For a detailed discussion of BTrees, refer to
 **
 **     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
@@ -50731,7 +52217,7 @@ SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){
 **
 ** The flags define the format of this btree page.  The leaf flag means that
 ** this page has no children.  The zerodata flag means that this page carries
-** only keys and no data.  The intkey flag means that the key is a integer
+** only keys and no data.  The intkey flag means that the key is an integer
 ** which is stored in the key size entry of the cell header rather than in
 ** the payload area.
 **
@@ -50868,12 +52354,14 @@ typedef struct BtLock BtLock;
 struct MemPage {
   u8 isInit;           /* True if previously initialized. MUST BE FIRST! */
   u8 nOverflow;        /* Number of overflow cell bodies in aCell[] */
-  u8 intKey;           /* True if intkey flag is set */
-  u8 leaf;             /* True if leaf flag is set */
-  u8 hasData;          /* True if this page stores data */
+  u8 intKey;           /* True if table b-trees.  False for index b-trees */
+  u8 intKeyLeaf;       /* True if the leaf of an intKey table */
+  u8 noPayload;        /* True if internal intKey page (thus w/o data) */
+  u8 leaf;             /* True if a leaf page */
   u8 hdrOffset;        /* 100 for page 1.  0 otherwise */
   u8 childPtrSize;     /* 0 if leaf==1.  4 if leaf==0 */
   u8 max1bytePayload;  /* min(maxLocal,127) */
+  u8 bBusy;            /* Prevent endless loops on corrupt database files */
   u16 maxLocal;        /* Copy of BtShared.maxLocal or BtShared.maxLeaf */
   u16 minLocal;        /* Copy of BtShared.minLocal or BtShared.minLeaf */
   u16 cellOffset;      /* Index in aData of first cell pointer */
@@ -50945,6 +52433,7 @@ struct Btree {
   u8 locked;         /* True if db currently has pBt locked */
   int wantToLock;    /* Number of nested calls to sqlite3BtreeEnter() */
   int nBackup;       /* Number of backup operations reading this btree */
+  u32 iDataVersion;  /* Combines with pBt->pPager->iDataVersion */
   Btree *pNext;      /* List of other sharable Btrees from the same db */
   Btree *pPrev;      /* Back pointer of the same list */
 #ifndef SQLITE_OMIT_SHARED_CACHE
@@ -51011,6 +52500,9 @@ struct BtShared {
 #endif
   u8 inTransaction;     /* Transaction state */
   u8 max1bytePayload;   /* Maximum first byte of cell for a 1-byte payload */
+#ifdef SQLITE_HAS_CODEC
+  u8 optimalReserve;    /* Desired amount of reserved space per page */
+#endif
   u16 btsFlags;         /* Boolean parameters.  See BTS_* macros below */
   u16 maxLocal;         /* Maximum local payload in non-LEAFDATA tables */
   u16 minLocal;         /* Minimum local payload in non-LEAFDATA tables */
@@ -51030,7 +52522,7 @@ struct BtShared {
   BtLock *pLock;        /* List of locks held on this shared-btree struct */
   Btree *pWriter;       /* Btree with currently open write transaction */
 #endif
-  u8 *pTmpSpace;        /* BtShared.pageSize bytes of space for tmp use */
+  u8 *pTmpSpace;        /* Temp space sufficient to hold a single cell */
 };
 
 /*
@@ -51051,12 +52543,10 @@ struct BtShared {
 */
 typedef struct CellInfo CellInfo;
 struct CellInfo {
-  i64 nKey;      /* The key for INTKEY tables, or number of bytes in key */
-  u8 *pCell;     /* Pointer to the start of cell content */
-  u32 nData;     /* Number of bytes of data */
-  u32 nPayload;  /* Total amount of payload */
-  u16 nHeader;   /* Size of the cell content header in bytes */
-  u16 nLocal;    /* Amount of payload held locally */
+  i64 nKey;      /* The key for INTKEY tables, or nPayload otherwise */
+  u8 *pPayload;  /* Pointer to the start of payload */
+  u32 nPayload;  /* Bytes of payload */
+  u16 nLocal;    /* Amount of payload held locally, not on overflow */
   u16 iOverflow; /* Offset to overflow page number.  Zero if no overflow */
   u16 nSize;     /* Size of the cell content on the main b-tree page */
 };
@@ -51085,6 +52575,11 @@ struct CellInfo {
 **
 ** Fields in this structure are accessed under the BtShared.mutex
 ** found at self->pBt->mutex. 
+**
+** skipNext meaning:
+**    eState==SKIPNEXT && skipNext>0:  Next sqlite3BtreeNext() is no-op.
+**    eState==SKIPNEXT && skipNext<0:  Next sqlite3BtreePrevious() is no-op.
+**    eState==FAULT:                   Cursor fault with skipNext as error code.
 */
 struct BtCursor {
   Btree *pBtree;            /* The Btree to which this cursor belongs */
@@ -51097,7 +52592,8 @@ struct BtCursor {
   void *pKey;               /* Saved key that was cursor last known position */
   Pgno pgnoRoot;            /* The root page of this tree */
   int nOvflAlloc;           /* Allocated size of aOverflow[] array */
-  int skipNext;    /* Prev() is noop if negative. Next() is noop if positive */
+  int skipNext;    /* Prev() is noop if negative. Next() is noop if positive.
+                   ** Error code if eState==CURSOR_FAULT */
   u8 curFlags;              /* zero or more BTCF_* flags defined below */
   u8 eState;                /* One of the CURSOR_XXX constants (see below) */
   u8 hints;                             /* As configured by CursorSetHints() */
@@ -51139,11 +52635,11 @@ struct BtCursor {
 **   seek the cursor to the saved position.
 **
 ** CURSOR_FAULT:
-**   A unrecoverable error (an I/O error or a malloc failure) has occurred
+**   An unrecoverable error (an I/O error or a malloc failure) has occurred
 **   on a different connection that shares the BtShared cache with this
 **   cursor.  The error has left the cache in an inconsistent state.
 **   Do nothing else with this cursor.  Any attempt to use the cursor
-**   should return the error code stored in BtCursor.skip
+**   should return the error code stored in BtCursor.skipNext
 */
 #define CURSOR_INVALID           0
 #define CURSOR_VALID             1
@@ -51253,6 +52749,8 @@ struct IntegrityCk {
   int mxErr;        /* Stop accumulating errors when this reaches zero */
   int nErr;         /* Number of messages written to zErrMsg so far */
   int mallocFailed; /* A memory allocation error has occurred */
+  const char *zPfx; /* Error message prefix */
+  int v1, v2;       /* Values for up to two %d fields in zPfx */
   StrAccum errMsg;  /* Accumulate the error message text here */
 };
 
@@ -51288,7 +52786,7 @@ static void lockBtreeMutex(Btree *p){
 ** Release the BtShared mutex associated with B-Tree handle p and
 ** clear the p->locked boolean.
 */
-static void unlockBtreeMutex(Btree *p){
+static void SQLITE_NOINLINE unlockBtreeMutex(Btree *p){
   BtShared *pBt = p->pBt;
   assert( p->locked==1 );
   assert( sqlite3_mutex_held(pBt->mutex) );
@@ -51299,6 +52797,9 @@ static void unlockBtreeMutex(Btree *p){
   p->locked = 0;
 }
 
+/* Forward reference */
+static void SQLITE_NOINLINE btreeLockCarefully(Btree *p);
+
 /*
 ** Enter a mutex on the given BTree object.
 **
@@ -51316,8 +52817,6 @@ static void unlockBtreeMutex(Btree *p){
 ** subsequent Btrees that desire a lock.
 */
 SQLITE_PRIVATE void sqlite3BtreeEnter(Btree *p){
-  Btree *pLater;
-
   /* Some basic sanity checking on the Btree.  The list of Btrees
   ** connected by pNext and pPrev should be in sorted order by
   ** Btree.pBt value. All elements of the list should belong to
@@ -51342,9 +52841,20 @@ SQLITE_PRIVATE void sqlite3BtreeEnter(Btree *p){
   if( !p->sharable ) return;
   p->wantToLock++;
   if( p->locked ) return;
+  btreeLockCarefully(p);
+}
+
+/* This is a helper function for sqlite3BtreeLock(). By moving
+** complex, but seldom used logic, out of sqlite3BtreeLock() and
+** into this routine, we avoid unnecessary stack pointer changes
+** and thus help the sqlite3BtreeLock() routine to run much faster
+** in the common case.
+*/
+static void SQLITE_NOINLINE btreeLockCarefully(Btree *p){
+  Btree *pLater;
 
   /* In most cases, we should be able to acquire the lock we
-  ** want without having to go throught the ascending lock
+  ** want without having to go through the ascending lock
   ** procedure that follows.  Just be sure not to block.
   */
   if( sqlite3_mutex_try(p->pBt->mutex)==SQLITE_OK ){
@@ -51374,10 +52884,12 @@ SQLITE_PRIVATE void sqlite3BtreeEnter(Btree *p){
   }
 }
 
+
 /*
 ** Exit the recursive mutex on a Btree.
 */
 SQLITE_PRIVATE void sqlite3BtreeLeave(Btree *p){
+  assert( sqlite3_mutex_held(p->db->mutex) );
   if( p->sharable ){
     assert( p->wantToLock>0 );
     p->wantToLock--;
@@ -51549,7 +53061,7 @@ SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** This file implements a external (disk-based) database using BTrees.
+** This file implements an external (disk-based) database using BTrees.
 ** See the header comment on "btreeInt.h" for additional information.
 ** Including a description of file format and an overview of operation.
 */
@@ -51625,7 +53137,7 @@ static BtShared *SQLITE_WSD sqlite3SharedCacheList = 0;
 ** The shared cache setting effects only future calls to
 ** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2().
 */
-SQLITE_API int sqlite3_enable_shared_cache(int enable){
+SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int enable){
   sqlite3GlobalConfig.sharedCacheEnabled = enable;
   return SQLITE_OK;
 }
@@ -51714,6 +53226,12 @@ static int hasSharedCacheTableLock(
     for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){
       Index *pIdx = (Index *)sqliteHashData(p);
       if( pIdx->tnum==(int)iRoot ){
+        if( iTab ){
+          /* Two or more indexes share the same root page.  There must
+          ** be imposter tables.  So just return true.  The assert is not
+          ** useful in that case. */
+          return 1;
+        }
         iTab = pIdx->pTable->tnum;
       }
     }
@@ -52026,7 +53544,9 @@ static void invalidateIncrblobCursors(
   BtShared *pBt = pBtree->pBt;
   assert( sqlite3BtreeHoldsMutex(pBtree) );
   for(p=pBt->pCursor; p; p=p->pNext){
-    if( (p->curFlags & BTCF_Incrblob)!=0 && (isClearTable || p->info.nKey==iRow) ){
+    if( (p->curFlags & BTCF_Incrblob)!=0
+     && (isClearTable || p->info.nKey==iRow)
+    ){
       p->eState = CURSOR_INVALID;
     }
   }
@@ -52131,10 +53651,15 @@ static void btreeReleaseAllCursorPages(BtCursor *pCur){
 static int saveCursorPosition(BtCursor *pCur){
   int rc;
 
-  assert( CURSOR_VALID==pCur->eState );
+  assert( CURSOR_VALID==pCur->eState || CURSOR_SKIPNEXT==pCur->eState );
   assert( 0==pCur->pKey );
   assert( cursorHoldsMutex(pCur) );
 
+  if( pCur->eState==CURSOR_SKIPNEXT ){
+    pCur->eState = CURSOR_VALID;
+  }else{
+    pCur->skipNext = 0;
+  }
   rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
   assert( rc==SQLITE_OK );  /* KeySize() cannot fail */
 
@@ -52145,7 +53670,7 @@ static int saveCursorPosition(BtCursor *pCur){
   ** data.
   */
   if( 0==pCur->apPage[0]->intKey ){
-    void *pKey = sqlite3Malloc( (int)pCur->nKey );
+    void *pKey = sqlite3Malloc( pCur->nKey );
     if( pKey ){
       rc = sqlite3BtreeKey(pCur, 0, (int)pCur->nKey, pKey);
       if( rc==SQLITE_OK ){
@@ -52168,18 +53693,44 @@ static int saveCursorPosition(BtCursor *pCur){
   return rc;
 }
 
+/* Forward reference */
+static int SQLITE_NOINLINE saveCursorsOnList(BtCursor*,Pgno,BtCursor*);
+
 /*
 ** Save the positions of all cursors (except pExcept) that are open on
-** the table  with root-page iRoot. Usually, this is called just before cursor
-** pExcept is used to modify the table (BtreeDelete() or BtreeInsert()).
+** the table with root-page iRoot.  "Saving the cursor position" means that
+** the location in the btree is remembered in such a way that it can be
+** moved back to the same spot after the btree has been modified.  This
+** routine is called just before cursor pExcept is used to modify the
+** table, for example in BtreeDelete() or BtreeInsert().
+**
+** Implementation note:  This routine merely checks to see if any cursors
+** need to be saved.  It calls out to saveCursorsOnList() in the (unusual)
+** event that cursors are in need to being saved.
 */
 static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
   BtCursor *p;
   assert( sqlite3_mutex_held(pBt->mutex) );
   assert( pExcept==0 || pExcept->pBt==pBt );
   for(p=pBt->pCursor; p; p=p->pNext){
+    if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ) break;
+  }
+  return p ? saveCursorsOnList(p, iRoot, pExcept) : SQLITE_OK;
+}
+
+/* This helper routine to saveAllCursors does the actual work of saving
+** the cursors if and when a cursor is found that actually requires saving.
+** The common case is that no cursors need to be saved, so this routine is
+** broken out from its caller to avoid unnecessary stack pointer movement.
+*/
+static int SQLITE_NOINLINE saveCursorsOnList(
+  BtCursor *p,         /* The first cursor that needs saving */
+  Pgno iRoot,          /* Only save cursor with this iRoot. Save all if zero */
+  BtCursor *pExcept    /* Do not save this cursor */
+){
+  do{
     if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ){
-      if( p->eState==CURSOR_VALID ){
+      if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){
         int rc = saveCursorPosition(p);
         if( SQLITE_OK!=rc ){
           return rc;
@@ -52189,7 +53740,8 @@ static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){
         btreeReleaseAllCursorPages(p);
       }
     }
-  }
+    p = p->pNext;
+  }while( p );
   return SQLITE_OK;
 }
 
@@ -52250,17 +53802,19 @@ static int btreeMoveto(
 */
 static int btreeRestoreCursorPosition(BtCursor *pCur){
   int rc;
+  int skipNext;
   assert( cursorHoldsMutex(pCur) );
   assert( pCur->eState>=CURSOR_REQUIRESEEK );
   if( pCur->eState==CURSOR_FAULT ){
     return pCur->skipNext;
   }
   pCur->eState = CURSOR_INVALID;
-  rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skipNext);
+  rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &skipNext);
   if( rc==SQLITE_OK ){
     sqlite3_free(pCur->pKey);
     pCur->pKey = 0;
     assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
+    pCur->skipNext |= skipNext;
     if( pCur->skipNext && pCur->eState==CURSOR_VALID ){
       pCur->eState = CURSOR_SKIPNEXT;
     }
@@ -52274,37 +53828,49 @@ static int btreeRestoreCursorPosition(BtCursor *pCur){
          SQLITE_OK)
 
 /*
-** Determine whether or not a cursor has moved from the position it
-** was last placed at.  Cursors can move when the row they are pointing
-** at is deleted out from under them.
+** Determine whether or not a cursor has moved from the position where
+** it was last placed, or has been invalidated for any other reason.
+** Cursors can move when the row they are pointing at is deleted out
+** from under them, for example.  Cursor might also move if a btree
+** is rebalanced.
+**
+** Calling this routine with a NULL cursor pointer returns false.
+**
+** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor
+** back to where it ought to be if this routine returns true.
+*/
+SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){
+  return pCur->eState!=CURSOR_VALID;
+}
+
+/*
+** This routine restores a cursor back to its original position after it
+** has been moved by some outside activity (such as a btree rebalance or
+** a row having been deleted out from under the cursor).  
 **
-** This routine returns an error code if something goes wrong.  The
-** integer *pHasMoved is set as follows:
+** On success, the *pDifferentRow parameter is false if the cursor is left
+** pointing at exactly the same row.  *pDifferntRow is the row the cursor
+** was pointing to has been deleted, forcing the cursor to point to some
+** nearby row.
 **
-**    0:   The cursor is unchanged
-**    1:   The cursor is still pointing at the same row, but the pointers
-**         returned by sqlite3BtreeKeyFetch() or sqlite3BtreeDataFetch()
-**         might now be invalid because of a balance() or other change to the
-**         b-tree.
-**    2:   The cursor is no longer pointing to the row.  The row might have
-**         been deleted out from under the cursor.
+** This routine should only be called for a cursor that just returned
+** TRUE from sqlite3BtreeCursorHasMoved().
 */
-SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur, int *pHasMoved){
+SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow){
   int rc;
 
-  if( pCur->eState==CURSOR_VALID ){
-    *pHasMoved = 0;
-    return SQLITE_OK;
-  }
+  assert( pCur!=0 );
+  assert( pCur->eState!=CURSOR_VALID );
   rc = restoreCursorPosition(pCur);
   if( rc ){
-    *pHasMoved = 2;
+    *pDifferentRow = 1;
     return rc;
   }
-  if( pCur->eState!=CURSOR_VALID || NEVER(pCur->skipNext!=0) ){
-    *pHasMoved = 2;
+  if( pCur->eState!=CURSOR_VALID ){
+    *pDifferentRow = 1;
   }else{
-    *pHasMoved = 1;
+    assert( pCur->skipNext==0 );
+    *pDifferentRow = 0;
   }
   return SQLITE_OK;
 }
@@ -52469,47 +54035,44 @@ static u8 *findOverflowCell(MemPage *pPage, int iCell){
 ** are two versions of this function.  btreeParseCell() takes a 
 ** cell index as the second argument and btreeParseCellPtr() 
 ** takes a pointer to the body of the cell as its second argument.
-**
-** Within this file, the parseCell() macro can be called instead of
-** btreeParseCellPtr(). Using some compilers, this will be faster.
 */
 static void btreeParseCellPtr(
   MemPage *pPage,         /* Page containing the cell */
   u8 *pCell,              /* Pointer to the cell text. */
   CellInfo *pInfo         /* Fill in this structure */
 ){
-  u16 n;                  /* Number bytes in cell content header */
+  u8 *pIter;              /* For scanning through pCell */
   u32 nPayload;           /* Number of bytes of cell payload */
 
   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
-
-  pInfo->pCell = pCell;
   assert( pPage->leaf==0 || pPage->leaf==1 );
-  n = pPage->childPtrSize;
-  assert( n==4-4*pPage->leaf );
-  if( pPage->intKey ){
-    if( pPage->hasData ){
-      assert( n==0 );
-      n = getVarint32(pCell, nPayload);
-    }else{
-      nPayload = 0;
-    }
-    n += getVarint(&pCell[n], (u64*)&pInfo->nKey);
-    pInfo->nData = nPayload;
+  if( pPage->intKeyLeaf ){
+    assert( pPage->childPtrSize==0 );
+    pIter = pCell + getVarint32(pCell, nPayload);
+    pIter += getVarint(pIter, (u64*)&pInfo->nKey);
+  }else if( pPage->noPayload ){
+    assert( pPage->childPtrSize==4 );
+    pInfo->nSize = 4 + getVarint(&pCell[4], (u64*)&pInfo->nKey);
+    pInfo->nPayload = 0;
+    pInfo->nLocal = 0;
+    pInfo->iOverflow = 0;
+    pInfo->pPayload = 0;
+    return;
   }else{
-    pInfo->nData = 0;
-    n += getVarint32(&pCell[n], nPayload);
+    pIter = pCell + pPage->childPtrSize;
+    pIter += getVarint32(pIter, nPayload);
     pInfo->nKey = nPayload;
   }
   pInfo->nPayload = nPayload;
-  pInfo->nHeader = n;
+  pInfo->pPayload = pIter;
   testcase( nPayload==pPage->maxLocal );
   testcase( nPayload==pPage->maxLocal+1 );
-  if( likely(nPayload<=pPage->maxLocal) ){
+  if( nPayload<=pPage->maxLocal ){
     /* This is the (easy) common case where the entire payload fits
     ** on the local page.  No overflow is required.
     */
-    if( (pInfo->nSize = (u16)(n+nPayload))<4 ) pInfo->nSize = 4;
+    pInfo->nSize = nPayload + (u16)(pIter - pCell);
+    if( pInfo->nSize<4 ) pInfo->nSize = 4;
     pInfo->nLocal = (u16)nPayload;
     pInfo->iOverflow = 0;
   }else{
@@ -52536,18 +54099,16 @@ static void btreeParseCellPtr(
     }else{
       pInfo->nLocal = (u16)minLocal;
     }
-    pInfo->iOverflow = (u16)(pInfo->nLocal + n);
+    pInfo->iOverflow = (u16)(&pInfo->pPayload[pInfo->nLocal] - pCell);
     pInfo->nSize = pInfo->iOverflow + 4;
   }
 }
-#define parseCell(pPage, iCell, pInfo) \
-  btreeParseCellPtr((pPage), findCell((pPage), (iCell)), (pInfo))
 static void btreeParseCell(
   MemPage *pPage,         /* Page containing the cell */
   int iCell,              /* The cell index.  First cell is 0 */
   CellInfo *pInfo         /* Fill in this structure */
 ){
-  parseCell(pPage, iCell, pInfo);
+  btreeParseCellPtr(pPage, findCell(pPage, iCell), pInfo);
 }
 
 /*
@@ -52557,8 +54118,9 @@ static void btreeParseCell(
 ** the space used by the cell pointer.
 */
 static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
-  u8 *pIter = &pCell[pPage->childPtrSize];
-  u32 nSize;
+  u8 *pIter = pCell + pPage->childPtrSize; /* For looping over bytes of pCell */
+  u8 *pEnd;                                /* End mark for a varint */
+  u32 nSize;                               /* Size value to return */
 
 #ifdef SQLITE_DEBUG
   /* The value returned by this function should always be the same as
@@ -52569,26 +54131,34 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
   btreeParseCellPtr(pPage, pCell, &debuginfo);
 #endif
 
+  if( pPage->noPayload ){
+    pEnd = &pIter[9];
+    while( (*pIter++)&0x80 && pIter<pEnd );
+    assert( pPage->childPtrSize==4 );
+    return (u16)(pIter - pCell);
+  }
+  nSize = *pIter;
+  if( nSize>=0x80 ){
+    pEnd = &pIter[9];
+    nSize &= 0x7f;
+    do{
+      nSize = (nSize<<7) | (*++pIter & 0x7f);
+    }while( *(pIter)>=0x80 && pIter<pEnd );
+  }
+  pIter++;
   if( pPage->intKey ){
-    u8 *pEnd;
-    if( pPage->hasData ){
-      pIter += getVarint32(pIter, nSize);
-    }else{
-      nSize = 0;
-    }
-
     /* pIter now points at the 64-bit integer key value, a variable length 
     ** integer. The following block moves pIter to point at the first byte
     ** past the end of the key value. */
     pEnd = &pIter[9];
     while( (*pIter++)&0x80 && pIter<pEnd );
-  }else{
-    pIter += getVarint32(pIter, nSize);
   }
-
   testcase( nSize==pPage->maxLocal );
   testcase( nSize==pPage->maxLocal+1 );
-  if( nSize>pPage->maxLocal ){
+  if( nSize<=pPage->maxLocal ){
+    nSize += (u32)(pIter - pCell);
+    if( nSize<4 ) nSize = 4;
+  }else{
     int minLocal = pPage->minLocal;
     nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4);
     testcase( nSize==pPage->maxLocal );
@@ -52596,16 +54166,9 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){
     if( nSize>pPage->maxLocal ){
       nSize = minLocal;
     }
-    nSize += 4;
-  }
-  nSize += (u32)(pIter - pCell);
-
-  /* The minimum size of any cell is 4 bytes. */
-  if( nSize<4 ){
-    nSize = 4;
+    nSize += 4 + (u16)(pIter - pCell);
   }
-
-  assert( nSize==debuginfo.nSize );
+  assert( nSize==debuginfo.nSize || CORRUPT_DB );
   return (u16)nSize;
 }
 
@@ -52628,7 +54191,6 @@ static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
   if( *pRC ) return;
   assert( pCell!=0 );
   btreeParseCellPtr(pPage, pCell, &info);
-  assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload );
   if( info.iOverflow ){
     Pgno ovfl = get4byte(&pCell[info.iOverflow]);
     ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC);
@@ -52642,10 +54204,15 @@ static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
 ** end of the page and all free space is collected into one
 ** big FreeBlk that occurs in between the header and cell
 ** pointer array and the cell content area.
+**
+** EVIDENCE-OF: R-44582-60138 SQLite may from time to time reorganize a
+** b-tree page so that there are no freeblocks or fragment bytes, all
+** unused bytes are contained in the unallocated space region, and all
+** cells are packed tightly at the end of the page.
 */
 static int defragmentPage(MemPage *pPage){
   int i;                     /* Loop counter */
-  int pc;                    /* Address of a i-th cell */
+  int pc;                    /* Address of the i-th cell */
   int hdr;                   /* Offset to the page header */
   int size;                  /* Size of a cell */
   int usableSize;            /* Number of usable bytes on a page */
@@ -52654,6 +54221,7 @@ static int defragmentPage(MemPage *pPage){
   int nCell;                 /* Number of cells on the page */
   unsigned char *data;       /* The page data */
   unsigned char *temp;       /* Temp area for cell content */
+  unsigned char *src;        /* Source of content */
   int iCellFirst;            /* First allowable cell index */
   int iCellLast;             /* Last possible cell index */
 
@@ -52663,15 +54231,13 @@ static int defragmentPage(MemPage *pPage){
   assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE );
   assert( pPage->nOverflow==0 );
   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
-  temp = sqlite3PagerTempSpace(pPage->pBt->pPager);
-  data = pPage->aData;
+  temp = 0;
+  src = data = pPage->aData;
   hdr = pPage->hdrOffset;
   cellOffset = pPage->cellOffset;
   nCell = pPage->nCell;
   assert( nCell==get2byte(&data[hdr+3]) );
   usableSize = pPage->pBt->usableSize;
-  cbrk = get2byte(&data[hdr+5]);
-  memcpy(&temp[cbrk], &data[cbrk], usableSize - cbrk);
   cbrk = usableSize;
   iCellFirst = cellOffset + 2*nCell;
   iCellLast = usableSize - 4;
@@ -52690,7 +54256,7 @@ static int defragmentPage(MemPage *pPage){
     }
 #endif
     assert( pc>=iCellFirst && pc<=iCellLast );
-    size = cellSizePtr(pPage, &temp[pc]);
+    size = cellSizePtr(pPage, &src[pc]);
     cbrk -= size;
 #if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
     if( cbrk<iCellFirst ){
@@ -52704,8 +54270,16 @@ static int defragmentPage(MemPage *pPage){
     assert( cbrk+size<=usableSize && cbrk>=iCellFirst );
     testcase( cbrk+size==usableSize );
     testcase( pc+size==usableSize );
-    memcpy(&data[cbrk], &temp[pc], size);
     put2byte(pAddr, cbrk);
+    if( temp==0 ){
+      int x;
+      if( cbrk==pc ) continue;
+      temp = sqlite3PagerTempSpace(pPage->pBt->pPager);
+      x = get2byte(&data[hdr+5]);
+      memcpy(&temp[x], &data[x], (cbrk+size) - x);
+      src = temp;
+    }
+    memcpy(&data[cbrk], &src[pc], size);
   }
   assert( cbrk>=iCellFirst );
   put2byte(&data[hdr+5], cbrk);
@@ -52721,6 +54295,69 @@ static int defragmentPage(MemPage *pPage){
 }
 
 /*
+** Search the free-list on page pPg for space to store a cell nByte bytes in
+** size. If one can be found, return a pointer to the space and remove it
+** from the free-list.
+**
+** If no suitable space can be found on the free-list, return NULL.
+**
+** This function may detect corruption within pPg.  If corruption is
+** detected then *pRc is set to SQLITE_CORRUPT and NULL is returned.
+**
+** If a slot of at least nByte bytes is found but cannot be used because 
+** there are already at least 60 fragmented bytes on the page, return NULL.
+** In this case, if pbDefrag parameter is not NULL, set *pbDefrag to true.
+*/
+static u8 *pageFindSlot(MemPage *pPg, int nByte, int *pRc, int *pbDefrag){
+  const int hdr = pPg->hdrOffset;
+  u8 * const aData = pPg->aData;
+  int iAddr;
+  int pc;
+  int usableSize = pPg->pBt->usableSize;
+
+  for(iAddr=hdr+1; (pc = get2byte(&aData[iAddr]))>0; iAddr=pc){
+    int size;            /* Size of the free slot */
+    /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of
+    ** increasing offset. */
+    if( pc>usableSize-4 || pc<iAddr+4 ){
+      *pRc = SQLITE_CORRUPT_BKPT;
+      return 0;
+    }
+    /* EVIDENCE-OF: R-22710-53328 The third and fourth bytes of each
+    ** freeblock form a big-endian integer which is the size of the freeblock
+    ** in bytes, including the 4-byte header. */
+    size = get2byte(&aData[pc+2]);
+    if( size>=nByte ){
+      int x = size - nByte;
+      testcase( x==4 );
+      testcase( x==3 );
+      if( x<4 ){
+        /* EVIDENCE-OF: R-11498-58022 In a well-formed b-tree page, the total
+        ** number of bytes in fragments may not exceed 60. */
+        if( aData[hdr+7]>=60 ){
+          if( pbDefrag ) *pbDefrag = 1;
+          return 0;
+        }
+        /* Remove the slot from the free-list. Update the number of
+        ** fragmented bytes within the page. */
+        memcpy(&aData[iAddr], &aData[pc], 2);
+        aData[hdr+7] += (u8)x;
+      }else if( size+pc > usableSize ){
+        *pRc = SQLITE_CORRUPT_BKPT;
+        return 0;
+      }else{
+        /* The slot remains on the free-list. Reduce its size to account
+         ** for the portion used by the new allocation. */
+        put2byte(&aData[pc+2], x);
+      }
+      return &aData[pc + x];
+    }
+  }
+
+  return 0;
+}
+
+/*
 ** Allocate nByte bytes of space from within the B-Tree page passed
 ** as the first argument. Write into *pIdx the index into pPage->aData[]
 ** of the first byte of allocated space. Return either SQLITE_OK or
@@ -52736,11 +54373,9 @@ static int defragmentPage(MemPage *pPage){
 static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
   const int hdr = pPage->hdrOffset;    /* Local cache of pPage->hdrOffset */
   u8 * const data = pPage->aData;      /* Local cache of pPage->aData */
-  int nFrag;                           /* Number of fragmented bytes on pPage */
   int top;                             /* First byte of cell content area */
+  int rc = SQLITE_OK;                  /* Integer return code */
   int gap;        /* First byte of gap between cell pointers and cell content */
-  int rc;         /* Integer return code */
-  int usableSize; /* Usable size of the page */
   
   assert( sqlite3PagerIswriteable(pPage->pDbPage) );
   assert( pPage->pBt );
@@ -52748,62 +54383,45 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
   assert( nByte>=0 );  /* Minimum cell size is 4 */
   assert( pPage->nFree>=nByte );
   assert( pPage->nOverflow==0 );
-  usableSize = pPage->pBt->usableSize;
-  assert( nByte < usableSize-8 );
+  assert( nByte < (int)(pPage->pBt->usableSize-8) );
 
-  nFrag = data[hdr+7];
   assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf );
   gap = pPage->cellOffset + 2*pPage->nCell;
+  assert( gap<=65536 );
+  /* EVIDENCE-OF: R-29356-02391 If the database uses a 65536-byte page size
+  ** and the reserved space is zero (the usual value for reserved space)
+  ** then the cell content offset of an empty page wants to be 65536.
+  ** However, that integer is too large to be stored in a 2-byte unsigned
+  ** integer, so a value of 0 is used in its place. */
   top = get2byteNotZero(&data[hdr+5]);
   if( gap>top ) return SQLITE_CORRUPT_BKPT;
+
+  /* If there is enough space between gap and top for one more cell pointer
+  ** array entry offset, and if the freelist is not empty, then search the
+  ** freelist looking for a free slot big enough to satisfy the request.
+  */
   testcase( gap+2==top );
   testcase( gap+1==top );
   testcase( gap==top );
-
-  if( nFrag>=60 ){
-    /* Always defragment highly fragmented pages */
-    rc = defragmentPage(pPage);
+  if( gap+2<=top && (data[hdr+1] || data[hdr+2]) ){
+    int bDefrag = 0;
+    u8 *pSpace = pageFindSlot(pPage, nByte, &rc, &bDefrag);
     if( rc ) return rc;
-    top = get2byteNotZero(&data[hdr+5]);
-  }else if( gap+2<=top ){
-    /* Search the freelist looking for a free slot big enough to satisfy 
-    ** the request. The allocation is made from the first free slot in 
-    ** the list that is large enough to accommodate it.
-    */
-    int pc, addr;
-    for(addr=hdr+1; (pc = get2byte(&data[addr]))>0; addr=pc){
-      int size;            /* Size of the free slot */
-      if( pc>usableSize-4 || pc<addr+4 ){
-        return SQLITE_CORRUPT_BKPT;
-      }
-      size = get2byte(&data[pc+2]);
-      if( size>=nByte ){
-        int x = size - nByte;
-        testcase( x==4 );
-        testcase( x==3 );
-        if( x<4 ){
-          /* Remove the slot from the free-list. Update the number of
-          ** fragmented bytes within the page. */
-          memcpy(&data[addr], &data[pc], 2);
-          data[hdr+7] = (u8)(nFrag + x);
-        }else if( size+pc > usableSize ){
-          return SQLITE_CORRUPT_BKPT;
-        }else{
-          /* The slot remains on the free-list. Reduce its size to account
-          ** for the portion used by the new allocation. */
-          put2byte(&data[pc+2], x);
-        }
-        *pIdx = pc + x;
-        return SQLITE_OK;
-      }
+    if( bDefrag ) goto defragment_page;
+    if( pSpace ){
+      assert( pSpace>=data && (pSpace - data)<65536 );
+      *pIdx = (int)(pSpace - data);
+      return SQLITE_OK;
     }
   }
 
-  /* Check to make sure there is enough space in the gap to satisfy
-  ** the allocation.  If not, defragment.
+  /* The request could not be fulfilled using a freelist slot.  Check
+  ** to see if defragmentation is necessary.
   */
   testcase( gap+2+nByte==top );
   if( gap+2+nByte>top ){
+ defragment_page:
+    assert( pPage->nCell>0 || CORRUPT_DB );
     rc = defragmentPage(pPage);
     if( rc ) return rc;
     top = get2byteNotZero(&data[hdr+5]);
@@ -52826,90 +54444,100 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){
 
 /*
 ** Return a section of the pPage->aData to the freelist.
-** The first byte of the new free block is pPage->aDisk[start]
-** and the size of the block is "size" bytes.
-**
-** Most of the effort here is involved in coalesing adjacent
-** free blocks into a single big free block.
-*/
-static int freeSpace(MemPage *pPage, int start, int size){
-  int addr, pbegin, hdr;
-  int iLast;                        /* Largest possible freeblock offset */
-  unsigned char *data = pPage->aData;
+** The first byte of the new free block is pPage->aData[iStart]
+** and the size of the block is iSize bytes.
+**
+** Adjacent freeblocks are coalesced.
+**
+** Note that even though the freeblock list was checked by btreeInitPage(),
+** that routine will not detect overlap between cells or freeblocks.  Nor
+** does it detect cells or freeblocks that encrouch into the reserved bytes
+** at the end of the page.  So do additional corruption checks inside this
+** routine and return SQLITE_CORRUPT if any problems are found.
+*/
+static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
+  u16 iPtr;                             /* Address of ptr to next freeblock */
+  u16 iFreeBlk;                         /* Address of the next freeblock */
+  u8 hdr;                               /* Page header size.  0 or 100 */
+  u8 nFrag = 0;                         /* Reduction in fragmentation */
+  u16 iOrigSize = iSize;                /* Original value of iSize */
+  u32 iLast = pPage->pBt->usableSize-4; /* Largest possible freeblock offset */
+  u32 iEnd = iStart + iSize;            /* First byte past the iStart buffer */
+  unsigned char *data = pPage->aData;   /* Page content */
 
   assert( pPage->pBt!=0 );
   assert( sqlite3PagerIswriteable(pPage->pDbPage) );
-  assert( start>=pPage->hdrOffset+6+pPage->childPtrSize );
-  assert( (start + size) <= (int)pPage->pBt->usableSize );
+  assert( iStart>=pPage->hdrOffset+6+pPage->childPtrSize );
+  assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize );
   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
-  assert( size>=0 );   /* Minimum cell size is 4 */
+  assert( iSize>=4 );   /* Minimum cell size is 4 */
+  assert( iStart<=iLast );
 
+  /* Overwrite deleted information with zeros when the secure_delete
+  ** option is enabled */
   if( pPage->pBt->btsFlags & BTS_SECURE_DELETE ){
-    /* Overwrite deleted information with zeros when the secure_delete
-    ** option is enabled */
-    memset(&data[start], 0, size);
+    memset(&data[iStart], 0, iSize);
   }
 
-  /* Add the space back into the linked list of freeblocks.  Note that
-  ** even though the freeblock list was checked by btreeInitPage(),
-  ** btreeInitPage() did not detect overlapping cells or
-  ** freeblocks that overlapped cells.   Nor does it detect when the
-  ** cell content area exceeds the value in the page header.  If these
-  ** situations arise, then subsequent insert operations might corrupt
-  ** the freelist.  So we do need to check for corruption while scanning
-  ** the freelist.
+  /* The list of freeblocks must be in ascending order.  Find the 
+  ** spot on the list where iStart should be inserted.
   */
   hdr = pPage->hdrOffset;
-  addr = hdr + 1;
-  iLast = pPage->pBt->usableSize - 4;
-  assert( start<=iLast );
-  while( (pbegin = get2byte(&data[addr]))<start && pbegin>0 ){
-    if( pbegin<addr+4 ){
-      return SQLITE_CORRUPT_BKPT;
+  iPtr = hdr + 1;
+  if( data[iPtr+1]==0 && data[iPtr]==0 ){
+    iFreeBlk = 0;  /* Shortcut for the case when the freelist is empty */
+  }else{
+    while( (iFreeBlk = get2byte(&data[iPtr]))>0 && iFreeBlk<iStart ){
+      if( iFreeBlk<iPtr+4 ) return SQLITE_CORRUPT_BKPT;
+      iPtr = iFreeBlk;
     }
-    addr = pbegin;
-  }
-  if( pbegin>iLast ){
-    return SQLITE_CORRUPT_BKPT;
-  }
-  assert( pbegin>addr || pbegin==0 );
-  put2byte(&data[addr], start);
-  put2byte(&data[start], pbegin);
-  put2byte(&data[start+2], size);
-  pPage->nFree = pPage->nFree + (u16)size;
-
-  /* Coalesce adjacent free blocks */
-  addr = hdr + 1;
-  while( (pbegin = get2byte(&data[addr]))>0 ){
-    int pnext, psize, x;
-    assert( pbegin>addr );
-    assert( pbegin <= (int)pPage->pBt->usableSize-4 );
-    pnext = get2byte(&data[pbegin]);
-    psize = get2byte(&data[pbegin+2]);
-    if( pbegin + psize + 3 >= pnext && pnext>0 ){
-      int frag = pnext - (pbegin+psize);
-      if( (frag<0) || (frag>(int)data[hdr+7]) ){
-        return SQLITE_CORRUPT_BKPT;
-      }
-      data[hdr+7] -= (u8)frag;
-      x = get2byte(&data[pnext]);
-      put2byte(&data[pbegin], x);
-      x = pnext + get2byte(&data[pnext+2]) - pbegin;
-      put2byte(&data[pbegin+2], x);
-    }else{
-      addr = pbegin;
+    if( iFreeBlk>iLast ) return SQLITE_CORRUPT_BKPT;
+    assert( iFreeBlk>iPtr || iFreeBlk==0 );
+  
+    /* At this point:
+    **    iFreeBlk:   First freeblock after iStart, or zero if none
+    **    iPtr:       The address of a pointer iFreeBlk
+    **
+    ** Check to see if iFreeBlk should be coalesced onto the end of iStart.
+    */
+    if( iFreeBlk && iEnd+3>=iFreeBlk ){
+      nFrag = iFreeBlk - iEnd;
+      if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_BKPT;
+      iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]);
+      iSize = iEnd - iStart;
+      iFreeBlk = get2byte(&data[iFreeBlk]);
     }
-  }
-
-  /* If the cell content area begins with a freeblock, remove it. */
-  if( data[hdr+1]==data[hdr+5] && data[hdr+2]==data[hdr+6] ){
-    int top;
-    pbegin = get2byte(&data[hdr+1]);
-    memcpy(&data[hdr+1], &data[pbegin], 2);
-    top = get2byte(&data[hdr+5]) + get2byte(&data[pbegin+2]);
-    put2byte(&data[hdr+5], top);
-  }
-  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
+  
+    /* If iPtr is another freeblock (that is, if iPtr is not the freelist
+    ** pointer in the page header) then check to see if iStart should be
+    ** coalesced onto the end of iPtr.
+    */
+    if( iPtr>hdr+1 ){
+      int iPtrEnd = iPtr + get2byte(&data[iPtr+2]);
+      if( iPtrEnd+3>=iStart ){
+        if( iPtrEnd>iStart ) return SQLITE_CORRUPT_BKPT;
+        nFrag += iStart - iPtrEnd;
+        iSize = iEnd - iPtr;
+        iStart = iPtr;
+      }
+    }
+    if( nFrag>data[hdr+7] ) return SQLITE_CORRUPT_BKPT;
+    data[hdr+7] -= nFrag;
+  }
+  if( iStart==get2byte(&data[hdr+5]) ){
+    /* The new freeblock is at the beginning of the cell content area,
+    ** so just extend the cell content area rather than create another
+    ** freelist entry */
+    if( iPtr!=hdr+1 ) return SQLITE_CORRUPT_BKPT;
+    put2byte(&data[hdr+1], iFreeBlk);
+    put2byte(&data[hdr+5], iEnd);
+  }else{
+    /* Insert the new freeblock into the freelist */
+    put2byte(&data[iPtr], iStart);
+    put2byte(&data[iStart], iFreeBlk);
+    put2byte(&data[iStart+2], iSize);
+  }
+  pPage->nFree += iOrigSize;
   return SQLITE_OK;
 }
 
@@ -52935,16 +54563,32 @@ static int decodeFlags(MemPage *pPage, int flagByte){
   pPage->childPtrSize = 4-4*pPage->leaf;
   pBt = pPage->pBt;
   if( flagByte==(PTF_LEAFDATA | PTF_INTKEY) ){
+    /* EVIDENCE-OF: R-03640-13415 A value of 5 means the page is an interior
+    ** table b-tree page. */
+    assert( (PTF_LEAFDATA|PTF_INTKEY)==5 );
+    /* EVIDENCE-OF: R-20501-61796 A value of 13 means the page is a leaf
+    ** table b-tree page. */
+    assert( (PTF_LEAFDATA|PTF_INTKEY|PTF_LEAF)==13 );
     pPage->intKey = 1;
-    pPage->hasData = pPage->leaf;
+    pPage->intKeyLeaf = pPage->leaf;
+    pPage->noPayload = !pPage->leaf;
     pPage->maxLocal = pBt->maxLeaf;
     pPage->minLocal = pBt->minLeaf;
   }else if( flagByte==PTF_ZERODATA ){
+    /* EVIDENCE-OF: R-27225-53936 A value of 2 means the page is an interior
+    ** index b-tree page. */
+    assert( (PTF_ZERODATA)==2 );
+    /* EVIDENCE-OF: R-16571-11615 A value of 10 means the page is a leaf
+    ** index b-tree page. */
+    assert( (PTF_ZERODATA|PTF_LEAF)==10 );
     pPage->intKey = 0;
-    pPage->hasData = 0;
+    pPage->intKeyLeaf = 0;
+    pPage->noPayload = 0;
     pPage->maxLocal = pBt->maxLocal;
     pPage->minLocal = pBt->minLocal;
   }else{
+    /* EVIDENCE-OF: R-47608-56469 Any other value for the b-tree page type is
+    ** an error. */
     return SQLITE_CORRUPT_BKPT;
   }
   pPage->max1bytePayload = pBt->max1bytePayload;
@@ -52984,21 +54628,33 @@ static int btreeInitPage(MemPage *pPage){
 
     hdr = pPage->hdrOffset;
     data = pPage->aData;
+    /* EVIDENCE-OF: R-28594-02890 The one-byte flag at offset 0 indicating
+    ** the b-tree page type. */
     if( decodeFlags(pPage, data[hdr]) ) return SQLITE_CORRUPT_BKPT;
     assert( pBt->pageSize>=512 && pBt->pageSize<=65536 );
     pPage->maskPage = (u16)(pBt->pageSize - 1);
     pPage->nOverflow = 0;
     usableSize = pBt->usableSize;
-    pPage->cellOffset = cellOffset = hdr + 12 - 4*pPage->leaf;
+    pPage->cellOffset = cellOffset = hdr + 8 + pPage->childPtrSize;
     pPage->aDataEnd = &data[usableSize];
     pPage->aCellIdx = &data[cellOffset];
+    /* EVIDENCE-OF: R-58015-48175 The two-byte integer at offset 5 designates
+    ** the start of the cell content area. A zero value for this integer is
+    ** interpreted as 65536. */
     top = get2byteNotZero(&data[hdr+5]);
+    /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
+    ** number of cells on the page. */
     pPage->nCell = get2byte(&data[hdr+3]);
     if( pPage->nCell>MX_CELL(pBt) ){
       /* To many cells for a single page.  The page must be corrupt */
       return SQLITE_CORRUPT_BKPT;
     }
     testcase( pPage->nCell==MX_CELL(pBt) );
+    /* EVIDENCE-OF: R-24089-57979 If a page contains no cells (which is only
+    ** possible for a root page of a table that contains no rows) then the
+    ** offset to the cell content area will equal the page size minus the
+    ** bytes of reserved space. */
+    assert( pPage->nCell>0 || top==usableSize || CORRUPT_DB );
 
     /* A malformed database page might cause us to read past the end
     ** of page when parsing a cell.  
@@ -53032,13 +54688,20 @@ static int btreeInitPage(MemPage *pPage){
     }  
 #endif
 
-    /* Compute the total free space on the page */
+    /* Compute the total free space on the page
+    ** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the
+    ** start of the first freeblock on the page, or is zero if there are no
+    ** freeblocks. */
     pc = get2byte(&data[hdr+1]);
-    nFree = data[hdr+7] + top;
+    nFree = data[hdr+7] + top;  /* Init nFree to non-freeblock free space */
     while( pc>0 ){
       u16 next, size;
       if( pc<iCellFirst || pc>iCellLast ){
-        /* Start of free block is off the page */
+        /* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will
+        ** always be at least one cell before the first freeblock.
+        **
+        ** Or, the freeblock is off the end of the page
+        */
         return SQLITE_CORRUPT_BKPT; 
       }
       next = get2byte(&data[pc]);
@@ -53347,16 +55010,18 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
   */
   if( isTempDb==0 && (isMemdb==0 || (vfsFlags&SQLITE_OPEN_URI)!=0) ){
     if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
+      int nFilename = sqlite3Strlen30(zFilename)+1;
       int nFullPathname = pVfs->mxPathname+1;
-      char *zFullPathname = sqlite3Malloc(nFullPathname);
+      char *zFullPathname = sqlite3Malloc(MAX(nFullPathname,nFilename));
       MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
+
       p->sharable = 1;
       if( !zFullPathname ){
         sqlite3_free(p);
         return SQLITE_NOMEM;
       }
       if( isMemdb ){
-        memcpy(zFullPathname, zFilename, sqlite3Strlen30(zFilename)+1);
+        memcpy(zFullPathname, zFilename, nFilename);
       }else{
         rc = sqlite3OsFullPathname(pVfs, zFilename,
                                    nFullPathname, zFullPathname);
@@ -53413,8 +55078,8 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
     ** the right size.  This is to guard against size changes that result
     ** when compiling on a different architecture.
     */
-    assert( sizeof(i64)==8 || sizeof(i64)==4 );
-    assert( sizeof(u64)==8 || sizeof(u64)==4 );
+    assert( sizeof(i64)==8 );
+    assert( sizeof(u64)==8 );
     assert( sizeof(u32)==4 );
     assert( sizeof(u16)==2 );
     assert( sizeof(Pgno)==4 );
@@ -53444,6 +55109,9 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
 #ifdef SQLITE_SECURE_DELETE
     pBt->btsFlags |= BTS_SECURE_DELETE;
 #endif
+    /* EVIDENCE-OF: R-51873-39618 The page size for a database file is
+    ** determined by the 2-byte integer located at an offset of 16 bytes from
+    ** the beginning of the database file. */
     pBt->pageSize = (zDbHeader[16]<<8) | (zDbHeader[17]<<16);
     if( pBt->pageSize<512 || pBt->pageSize>SQLITE_MAX_PAGE_SIZE
          || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){
@@ -53462,6 +55130,9 @@ SQLITE_PRIVATE int sqlite3BtreeOpen(
 #endif
       nReserve = 0;
     }else{
+      /* EVIDENCE-OF: R-37497-42412 The size of the reserved region is
+      ** determined by the one-byte unsigned integer found at an offset of 20
+      ** into the database file header. */
       nReserve = zDbHeader[20];
       pBt->btsFlags |= BTS_PAGESIZE_FIXED;
 #ifndef SQLITE_OMIT_AUTOVACUUM
@@ -53596,7 +55267,8 @@ static int removeFromSharingList(BtShared *pBt){
 
 /*
 ** Make sure pBt->pTmpSpace points to an allocation of 
-** MX_CELL_SIZE(pBt) bytes.
+** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child
+** pointer.
 */
 static void allocateTempSpace(BtShared *pBt){
   if( !pBt->pTmpSpace ){
@@ -53611,8 +55283,16 @@ static void allocateTempSpace(BtShared *pBt){
     ** it into a database page. This is not actually a problem, but it
     ** does cause a valgrind error when the 1 or 2 bytes of unitialized 
     ** data is passed to system call write(). So to avoid this error,
-    ** zero the first 4 bytes of temp space here.  */
-    if( pBt->pTmpSpace ) memset(pBt->pTmpSpace, 0, 4);
+    ** zero the first 4 bytes of temp space here.
+    **
+    ** Also:  Provide four bytes of initialized space before the
+    ** beginning of pTmpSpace as an area available to prepend the
+    ** left-child pointer to the beginning of a cell.
+    */
+    if( pBt->pTmpSpace ){
+      memset(pBt->pTmpSpace, 0, 8);
+      pBt->pTmpSpace += 4;
+    }
   }
 }
 
@@ -53620,8 +55300,11 @@ static void allocateTempSpace(BtShared *pBt){
 ** Free the pBt->pTmpSpace allocation
 */
 static void freeTempSpace(BtShared *pBt){
-  sqlite3PageFree( pBt->pTmpSpace);
-  pBt->pTmpSpace = 0;
+  if( pBt->pTmpSpace ){
+    pBt->pTmpSpace -= 4;
+    sqlite3PageFree(pBt->pTmpSpace);
+    pBt->pTmpSpace = 0;
+  }
 }
 
 /*
@@ -53647,7 +55330,7 @@ SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){
   ** The call to sqlite3BtreeRollback() drops any table-locks held by
   ** this handle.
   */
-  sqlite3BtreeRollback(p, SQLITE_OK);
+  sqlite3BtreeRollback(p, SQLITE_OK, 0);
   sqlite3BtreeLeave(p);
 
   /* If there are still other outstanding references to the shared-btree
@@ -53783,6 +55466,9 @@ SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve,
   BtShared *pBt = p->pBt;
   assert( nReserve>=-1 && nReserve<=255 );
   sqlite3BtreeEnter(p);
+#if SQLITE_HAS_CODEC
+  if( nReserve>pBt->optimalReserve ) pBt->optimalReserve = (u8)nReserve;
+#endif
   if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){
     sqlite3BtreeLeave(p);
     return SQLITE_READONLY;
@@ -53794,7 +55480,7 @@ SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve,
   if( pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE &&
         ((pageSize-1)&pageSize)==0 ){
     assert( (pageSize & 7)==0 );
-    assert( !pBt->pPage1 && !pBt->pCursor );
+    assert( !pBt->pCursor );
     pBt->pageSize = (u32)pageSize;
     freeTempSpace(pBt);
   }
@@ -53812,7 +55498,6 @@ SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree *p){
   return p->pBt->pageSize;
 }
 
-#if defined(SQLITE_HAS_CODEC) || defined(SQLITE_DEBUG)
 /*
 ** This function is similar to sqlite3BtreeGetReserve(), except that it
 ** may only be called if it is guaranteed that the b-tree mutex is already
@@ -53825,25 +55510,33 @@ SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree *p){
 ** database handle that owns *p, causing undefined behavior.
 */
 SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p){
+  int n;
   assert( sqlite3_mutex_held(p->pBt->mutex) );
-  return p->pBt->pageSize - p->pBt->usableSize;
+  n = p->pBt->pageSize - p->pBt->usableSize;
+  return n;
 }
-#endif /* SQLITE_HAS_CODEC || SQLITE_DEBUG */
 
-#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM)
 /*
 ** Return the number of bytes of space at the end of every page that
 ** are intentually left unused.  This is the "reserved" space that is
 ** sometimes used by extensions.
+**
+** If SQLITE_HAS_MUTEX is defined then the number returned is the
+** greater of the current reserved space and the maximum requested
+** reserve space.
 */
-SQLITE_PRIVATE int sqlite3BtreeGetReserve(Btree *p){
+SQLITE_PRIVATE int sqlite3BtreeGetOptimalReserve(Btree *p){
   int n;
   sqlite3BtreeEnter(p);
-  n = p->pBt->pageSize - p->pBt->usableSize;
+  n = sqlite3BtreeGetReserveNoMutex(p);
+#ifdef SQLITE_HAS_CODEC
+  if( n<p->pBt->optimalReserve ) n = p->pBt->optimalReserve;
+#endif
   sqlite3BtreeLeave(p);
   return n;
 }
 
+
 /*
 ** Set the maximum page count for a database if mxPage is positive.
 ** No changes are made if mxPage is 0 or negative.
@@ -53874,7 +55567,6 @@ SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree *p, int newFlag){
   sqlite3BtreeLeave(p);
   return b;
 }
-#endif /* !defined(SQLITE_OMIT_PAGER_PRAGMAS) || !defined(SQLITE_OMIT_VACUUM) */
 
 /*
 ** Change the 'auto-vacuum' property of the database. If the 'autoVacuum'
@@ -53959,6 +55651,9 @@ static int lockBtree(BtShared *pBt){
     u32 usableSize;
     u8 *page1 = pPage1->aData;
     rc = SQLITE_NOTADB;
+    /* EVIDENCE-OF: R-43737-39999 Every valid SQLite database file begins
+    ** with the following 16 bytes (in hex): 53 51 4c 69 74 65 20 66 6f 72 6d
+    ** 61 74 20 33 00. */
     if( memcmp(page1, zMagicHeader, 16)!=0 ){
       goto page1_init_failed;
     }
@@ -53999,15 +55694,21 @@ static int lockBtree(BtShared *pBt){
     }
 #endif
 
-    /* The maximum embedded fraction must be exactly 25%.  And the minimum
-    ** embedded fraction must be 12.5% for both leaf-data and non-leaf-data.
+    /* EVIDENCE-OF: R-15465-20813 The maximum and minimum embedded payload
+    ** fractions and the leaf payload fraction values must be 64, 32, and 32.
+    **
     ** The original design allowed these amounts to vary, but as of
     ** version 3.6.0, we require them to be fixed.
     */
     if( memcmp(&page1[21], "\100\040\040",3)!=0 ){
       goto page1_init_failed;
     }
+    /* EVIDENCE-OF: R-51873-39618 The page size for a database file is
+    ** determined by the 2-byte integer located at an offset of 16 bytes from
+    ** the beginning of the database file. */
     pageSize = (page1[16]<<8) | (page1[17]<<16);
+    /* EVIDENCE-OF: R-25008-21688 The size of a page is a power of two
+    ** between 512 and 65536 inclusive. */
     if( ((pageSize-1)&pageSize)!=0
      || pageSize>SQLITE_MAX_PAGE_SIZE 
      || pageSize<=256 
@@ -54015,6 +55716,13 @@ static int lockBtree(BtShared *pBt){
       goto page1_init_failed;
     }
     assert( (pageSize & 7)==0 );
+    /* EVIDENCE-OF: R-59310-51205 The "reserved space" size in the 1-byte
+    ** integer at offset 20 is the number of bytes of space at the end of
+    ** each page to reserve for extensions. 
+    **
+    ** EVIDENCE-OF: R-37497-42412 The size of the reserved region is
+    ** determined by the one-byte unsigned integer found at an offset of 20
+    ** into the database file header. */
     usableSize = pageSize - page1[20];
     if( (u32)pageSize!=pBt->pageSize ){
       /* After reading the first page of the database assuming a page size
@@ -54035,6 +55743,9 @@ static int lockBtree(BtShared *pBt){
       rc = SQLITE_CORRUPT_BKPT;
       goto page1_init_failed;
     }
+    /* EVIDENCE-OF: R-28312-64704 However, the usable size is not allowed to
+    ** be less than 480. In other words, if the page size is 512, then the
+    ** reserved space size cannot exceed 32. */
     if( usableSize<480 ){
       goto page1_init_failed;
     }
@@ -54089,7 +55800,7 @@ page1_init_failed:
 ** false then all cursors are counted.
 **
 ** For the purposes of this routine, a cursor is any cursor that
-** is capable of reading or writing to the databse.  Cursors that
+** is capable of reading or writing to the database.  Cursors that
 ** have been tripped into the CURSOR_FAULT state are not counted.
 */
 static int countValidCursors(BtShared *pBt, int wrOnly){
@@ -54115,11 +55826,11 @@ static void unlockBtreeIfUnused(BtShared *pBt){
   assert( sqlite3_mutex_held(pBt->mutex) );
   assert( countValidCursors(pBt,0)==0 || pBt->inTransaction>TRANS_NONE );
   if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){
-    assert( pBt->pPage1->aData );
+    MemPage *pPage1 = pBt->pPage1;
+    assert( pPage1->aData );
     assert( sqlite3PagerRefcount(pBt->pPager)==1 );
-    assert( pBt->pPage1->aData );
-    releasePage(pBt->pPage1);
     pBt->pPage1 = 0;
+    releasePage(pPage1);
   }
 }
 
@@ -54553,7 +56264,7 @@ static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8);
 ** calling this function again), return SQLITE_DONE. Or, if an error 
 ** occurs, return some other error code.
 **
-** More specificly, this function attempts to re-organize the database so 
+** More specifically, this function attempts to re-organize the database so 
 ** that the last page of the file currently in use is no longer in use.
 **
 ** Parameter nFin is the number of pages that this database would contain
@@ -54561,7 +56272,7 @@ static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8);
 **
 ** If the bCommit parameter is non-zero, this function assumes that the 
 ** caller will keep calling incrVacuumStep() until it returns SQLITE_DONE 
-** or an error. bCommit is passed true for an auto-vacuum-on-commmit 
+** or an error. bCommit is passed true for an auto-vacuum-on-commit 
 ** operation, or false for an incremental vacuum.
 */
 static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg, int bCommit){
@@ -54915,6 +56626,7 @@ SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree *p, int bCleanup){
       sqlite3BtreeLeave(p);
       return rc;
     }
+    p->iDataVersion--;  /* Compensate for pPager->iDataVersion++; */
     pBt->inTransaction = TRANS_READ;
     btreeClearHasContent(pBt);
   }
@@ -54940,60 +56652,91 @@ SQLITE_PRIVATE int sqlite3BtreeCommit(Btree *p){
 
 /*
 ** This routine sets the state to CURSOR_FAULT and the error
-** code to errCode for every cursor on BtShared that pBtree
-** references.
-**
-** Every cursor is tripped, including cursors that belong
-** to other database connections that happen to be sharing
-** the cache with pBtree.
-**
-** This routine gets called when a rollback occurs.
-** All cursors using the same cache must be tripped
-** to prevent them from trying to use the btree after
-** the rollback.  The rollback may have deleted tables
-** or moved root pages, so it is not sufficient to
-** save the state of the cursor.  The cursor must be
-** invalidated.
-*/
-SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode){
+** code to errCode for every cursor on any BtShared that pBtree
+** references.  Or if the writeOnly flag is set to 1, then only
+** trip write cursors and leave read cursors unchanged.
+**
+** Every cursor is a candidate to be tripped, including cursors
+** that belong to other database connections that happen to be
+** sharing the cache with pBtree.
+**
+** This routine gets called when a rollback occurs. If the writeOnly
+** flag is true, then only write-cursors need be tripped - read-only
+** cursors save their current positions so that they may continue 
+** following the rollback. Or, if writeOnly is false, all cursors are 
+** tripped. In general, writeOnly is false if the transaction being
+** rolled back modified the database schema. In this case b-tree root
+** pages may be moved or deleted from the database altogether, making
+** it unsafe for read cursors to continue.
+**
+** If the writeOnly flag is true and an error is encountered while 
+** saving the current position of a read-only cursor, all cursors, 
+** including all read-cursors are tripped.
+**
+** SQLITE_OK is returned if successful, or if an error occurs while
+** saving a cursor position, an SQLite error code.
+*/
+SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int writeOnly){
   BtCursor *p;
-  if( pBtree==0 ) return;
-  sqlite3BtreeEnter(pBtree);
-  for(p=pBtree->pBt->pCursor; p; p=p->pNext){
-    int i;
-    sqlite3BtreeClearCursor(p);
-    p->eState = CURSOR_FAULT;
-    p->skipNext = errCode;
-    for(i=0; i<=p->iPage; i++){
-      releasePage(p->apPage[i]);
-      p->apPage[i] = 0;
+  int rc = SQLITE_OK;
+
+  assert( (writeOnly==0 || writeOnly==1) && BTCF_WriteFlag==1 );
+  if( pBtree ){
+    sqlite3BtreeEnter(pBtree);
+    for(p=pBtree->pBt->pCursor; p; p=p->pNext){
+      int i;
+      if( writeOnly && (p->curFlags & BTCF_WriteFlag)==0 ){
+        if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){
+          rc = saveCursorPosition(p);
+          if( rc!=SQLITE_OK ){
+            (void)sqlite3BtreeTripAllCursors(pBtree, rc, 0);
+            break;
+          }
+        }
+      }else{
+        sqlite3BtreeClearCursor(p);
+        p->eState = CURSOR_FAULT;
+        p->skipNext = errCode;
+      }
+      for(i=0; i<=p->iPage; i++){
+        releasePage(p->apPage[i]);
+        p->apPage[i] = 0;
+      }
     }
+    sqlite3BtreeLeave(pBtree);
   }
-  sqlite3BtreeLeave(pBtree);
+  return rc;
 }
 
 /*
-** Rollback the transaction in progress.  All cursors will be
-** invalided by this operation.  Any attempt to use a cursor
-** that was open at the beginning of this operation will result
-** in an error.
+** Rollback the transaction in progress.
+**
+** If tripCode is not SQLITE_OK then cursors will be invalidated (tripped).
+** Only write cursors are tripped if writeOnly is true but all cursors are
+** tripped if writeOnly is false.  Any attempt to use
+** a tripped cursor will result in an error.
 **
 ** This will release the write lock on the database file.  If there
 ** are no active cursors, it also releases the read lock.
 */
-SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode){
+SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly){
   int rc;
   BtShared *pBt = p->pBt;
   MemPage *pPage1;
 
+  assert( writeOnly==1 || writeOnly==0 );
+  assert( tripCode==SQLITE_ABORT_ROLLBACK || tripCode==SQLITE_OK );
   sqlite3BtreeEnter(p);
   if( tripCode==SQLITE_OK ){
     rc = tripCode = saveAllCursors(pBt, 0, 0);
+    if( rc ) writeOnly = 0;
   }else{
     rc = SQLITE_OK;
   }
   if( tripCode ){
-    sqlite3BtreeTripAllCursors(p, tripCode);
+    int rc2 = sqlite3BtreeTripAllCursors(p, tripCode, writeOnly);
+    assert( rc==SQLITE_OK || (writeOnly==0 && rc2==SQLITE_OK) );
+    if( rc2!=SQLITE_OK ) rc = rc2;
   }
   btreeIntegrity(p);
 
@@ -55028,7 +56771,7 @@ SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode){
 }
 
 /*
-** Start a statement subtransaction. The subtransaction can can be rolled
+** Start a statement subtransaction. The subtransaction can be rolled
 ** back independently of the main transaction. You must start a transaction 
 ** before starting a subtransaction. The subtransaction is ended automatically 
 ** if the main transaction commits or rolls back.
@@ -55160,6 +56903,10 @@ static int btreeCursor(
   if( NEVER(wrFlag && (pBt->btsFlags & BTS_READ_ONLY)!=0) ){
     return SQLITE_READONLY;
   }
+  if( wrFlag ){
+    allocateTempSpace(pBt);
+    if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM;
+  }
   if( iTable==1 && btreePagecount(pBt)==0 ){
     assert( wrFlag==0 );
     iTable = 0;
@@ -55243,7 +56990,7 @@ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){
       releasePage(pCur->apPage[i]);
     }
     unlockBtreeIfUnused(pBt);
-    sqlite3DbFree(pBtree->db, pCur->aOverflow);
+    sqlite3_free(pCur->aOverflow);
     /* sqlite3_free(pCur); */
     sqlite3BtreeLeave(pBtree);
   }
@@ -55262,7 +57009,7 @@ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){
 ** compiler to crash when getCellInfo() is implemented as a macro.
 ** But there is a measureable speed advantage to using the macro on gcc
 ** (when less compiler optimizations like -Os or -O0 are used and the
-** compiler is not doing agressive inlining.)  So we use a real function
+** compiler is not doing aggressive inlining.)  So we use a real function
 ** for MSVC and a macro for everything else.  Ticket #2457.
 */
 #ifndef NDEBUG
@@ -55324,13 +57071,9 @@ SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor *pCur){
 */
 SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
   assert( cursorHoldsMutex(pCur) );
-  assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
-  if( pCur->eState!=CURSOR_VALID ){
-    *pSize = 0;
-  }else{
-    getCellInfo(pCur);
-    *pSize = pCur->info.nKey;
-  }
+  assert( pCur->eState==CURSOR_VALID );
+  getCellInfo(pCur);
+  *pSize = pCur->info.nKey;
   return SQLITE_OK;
 }
 
@@ -55349,8 +57092,11 @@ SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){
 SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
   assert( cursorHoldsMutex(pCur) );
   assert( pCur->eState==CURSOR_VALID );
+  assert( pCur->iPage>=0 );
+  assert( pCur->iPage<BTCURSOR_MAX_DEPTH );
+  assert( pCur->apPage[pCur->iPage]->intKeyLeaf==1 );
   getCellInfo(pCur);
-  *pSize = pCur->info.nData;
+  *pSize = pCur->info.nPayload;
   return SQLITE_OK;
 }
 
@@ -55479,7 +57225,7 @@ static int copyPayload(
 **
 ** If the current cursor entry uses one or more overflow pages and the
 ** eOp argument is not 2, this function may allocate space for and lazily 
-** popluates the overflow page-list cache array (BtCursor.aOverflow). 
+** populates the overflow page-list cache array (BtCursor.aOverflow). 
 ** Subsequent calls use this cache to make seeking to the supplied offset 
 ** more efficient.
 **
@@ -55501,30 +57247,28 @@ static int accessPayload(
 ){
   unsigned char *aPayload;
   int rc = SQLITE_OK;
-  u32 nKey;
   int iIdx = 0;
   MemPage *pPage = pCur->apPage[pCur->iPage]; /* Btree page of current entry */
   BtShared *pBt = pCur->pBt;                  /* Btree this cursor belongs to */
 #ifdef SQLITE_DIRECT_OVERFLOW_READ
-  int bEnd;                                   /* True if reading to end of data */
+  unsigned char * const pBufStart = pBuf;
+  int bEnd;                                 /* True if reading to end of data */
 #endif
 
   assert( pPage );
   assert( pCur->eState==CURSOR_VALID );
   assert( pCur->aiIdx[pCur->iPage]<pPage->nCell );
   assert( cursorHoldsMutex(pCur) );
-  assert( eOp!=2 || offset==0 );      /* Always start from beginning for eOp==2 */
+  assert( eOp!=2 || offset==0 );    /* Always start from beginning for eOp==2 */
 
   getCellInfo(pCur);
-  aPayload = pCur->info.pCell + pCur->info.nHeader;
-  nKey = (pPage->intKey ? 0 : (int)pCur->info.nKey);
+  aPayload = pCur->info.pPayload;
 #ifdef SQLITE_DIRECT_OVERFLOW_READ
-  bEnd = (offset+amt==nKey+pCur->info.nData);
+  bEnd = offset+amt==pCur->info.nPayload;
 #endif
+  assert( offset+amt <= pCur->info.nPayload );
 
-  if( NEVER(offset+amt > nKey+pCur->info.nData) 
-   || &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize]
-  ){
+  if( &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] ){
     /* Trying to read or write past the end of the data is an error */
     return SQLITE_CORRUPT_BKPT;
   }
@@ -55543,6 +57287,7 @@ static int accessPayload(
     offset -= pCur->info.nLocal;
   }
 
+
   if( rc==SQLITE_OK && amt>0 ){
     const u32 ovflSize = pBt->usableSize - 4;  /* Bytes content per ovfl page */
     Pgno nextPage;
@@ -55560,8 +57305,8 @@ static int accessPayload(
     if( eOp!=2 && (pCur->curFlags & BTCF_ValidOvfl)==0 ){
       int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize;
       if( nOvfl>pCur->nOvflAlloc ){
-        Pgno *aNew = (Pgno*)sqlite3DbRealloc(
-            pCur->pBtree->db, pCur->aOverflow, nOvfl*2*sizeof(Pgno)
+        Pgno *aNew = (Pgno*)sqlite3Realloc(
+            pCur->aOverflow, nOvfl*2*sizeof(Pgno)
         );
         if( aNew==0 ){
           rc = SQLITE_NOMEM;
@@ -55580,7 +57325,9 @@ static int accessPayload(
     ** entry for the first required overflow page is valid, skip
     ** directly to it.
     */
-    if( (pCur->curFlags & BTCF_ValidOvfl)!=0 && pCur->aOverflow[offset/ovflSize] ){
+    if( (pCur->curFlags & BTCF_ValidOvfl)!=0
+     && pCur->aOverflow[offset/ovflSize]
+    ){
       iIdx = (offset/ovflSize);
       nextPage = pCur->aOverflow[iIdx];
       offset = (offset%ovflSize);
@@ -55606,6 +57353,7 @@ static int accessPayload(
         */
         assert( eOp!=2 );
         assert( pCur->curFlags & BTCF_ValidOvfl );
+        assert( pCur->pBtree->db==pBt->db );
         if( pCur->aOverflow[iIdx+1] ){
           nextPage = pCur->aOverflow[iIdx+1];
         }else{
@@ -55633,6 +57381,7 @@ static int accessPayload(
         **   4) there is no open write-transaction, and
         **   5) the database is not a WAL database,
         **   6) all data from the page is being read.
+        **   7) at least 4 bytes have already been read into the output buffer 
         **
         ** then data can be read directly from the database file into the
         ** output buffer, bypassing the page-cache altogether. This speeds
@@ -55644,9 +57393,11 @@ static int accessPayload(
          && pBt->inTransaction==TRANS_READ                     /* (4) */
          && (fd = sqlite3PagerFile(pBt->pPager))->pMethods     /* (3) */
          && pBt->pPage1->aData[19]==0x01                       /* (5) */
+         && &pBuf[-4]>=pBufStart                               /* (7) */
         ){
           u8 aSave[4];
           u8 *aWrite = &pBuf[-4];
+          assert( aWrite>=pBufStart );                         /* hence (7) */
           memcpy(aSave, aWrite, 4);
           rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));
           nextPage = get4byte(aWrite);
@@ -55681,7 +57432,7 @@ static int accessPayload(
 
 /*
 ** Read part of the key associated with cursor pCur.  Exactly
-** "amt" bytes will be transfered into pBuf[].  The transfer
+** "amt" bytes will be transferred into pBuf[].  The transfer
 ** begins at "offset".
 **
 ** The caller must ensure that pCur is pointing to a valid row
@@ -55751,14 +57502,19 @@ static const void *fetchPayload(
   BtCursor *pCur,      /* Cursor pointing to entry to read from */
   u32 *pAmt            /* Write the number of available bytes here */
 ){
+  u32 amt;
   assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
   assert( pCur->eState==CURSOR_VALID );
   assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
   assert( cursorHoldsMutex(pCur) );
   assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
   assert( pCur->info.nSize>0 );
-  *pAmt = pCur->info.nLocal;
-  return (void*)(pCur->info.pCell + pCur->info.nHeader);
+  assert( pCur->info.pPayload>pCur->apPage[pCur->iPage]->aData || CORRUPT_DB );
+  assert( pCur->info.pPayload<pCur->apPage[pCur->iPage]->aDataEnd ||CORRUPT_DB);
+  amt = (int)(pCur->apPage[pCur->iPage]->aDataEnd - pCur->info.pPayload);
+  if( pCur->info.nLocal<amt ) amt = pCur->info.nLocal;
+  *pAmt = amt;
+  return (void*)pCur->info.pPayload;
 }
 
 
@@ -55821,7 +57577,7 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
   return SQLITE_OK;
 }
 
-#if 0
+#if SQLITE_DEBUG
 /*
 ** Page pParent is an internal (non-leaf) tree page. This function 
 ** asserts that page number iChild is the left-child if the iIdx'th
@@ -55830,6 +57586,8 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
 ** the page.
 */
 static void assertParentIndex(MemPage *pParent, int iIdx, Pgno iChild){
+  if( CORRUPT_DB ) return;  /* The conditions tested below might not be true
+                            ** in a corrupt database */
   assert( iIdx<=pParent->nCell );
   if( iIdx==pParent->nCell ){
     assert( get4byte(&pParent->aData[pParent->hdrOffset+8])==iChild );
@@ -55854,19 +57612,11 @@ static void moveToParent(BtCursor *pCur){
   assert( pCur->eState==CURSOR_VALID );
   assert( pCur->iPage>0 );
   assert( pCur->apPage[pCur->iPage] );
-
-  /* UPDATE: It is actually possible for the condition tested by the assert
-  ** below to be untrue if the database file is corrupt. This can occur if
-  ** one cursor has modified page pParent while a reference to it is held 
-  ** by a second cursor. Which can only happen if a single page is linked
-  ** into more than one b-tree structure in a corrupt database.  */
-#if 0
   assertParentIndex(
     pCur->apPage[pCur->iPage-1], 
     pCur->aiIdx[pCur->iPage-1], 
     pCur->apPage[pCur->iPage]->pgno
   );
-#endif
   testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell );
 
   releasePage(pCur->apPage[pCur->iPage]);
@@ -56001,17 +57751,16 @@ static int moveToRightmost(BtCursor *pCur){
 
   assert( cursorHoldsMutex(pCur) );
   assert( pCur->eState==CURSOR_VALID );
-  while( rc==SQLITE_OK && !(pPage = pCur->apPage[pCur->iPage])->leaf ){
+  while( !(pPage = pCur->apPage[pCur->iPage])->leaf ){
     pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
     pCur->aiIdx[pCur->iPage] = pPage->nCell;
     rc = moveToChild(pCur, pgno);
+    if( rc ) return rc;
   }
-  if( rc==SQLITE_OK ){
-    pCur->aiIdx[pCur->iPage] = pPage->nCell-1;
-    pCur->info.nSize = 0;
-    pCur->curFlags &= ~BTCF_ValidNKey;
-  }
-  return rc;
+  pCur->aiIdx[pCur->iPage] = pPage->nCell-1;
+  assert( pCur->info.nSize==0 );
+  assert( (pCur->curFlags & BTCF_ValidNKey)==0 );
+  return SQLITE_OK;
 }
 
 /* Move the cursor to the first entry in the table.  Return SQLITE_OK
@@ -56142,7 +57891,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
 
   if( pIdxKey ){
     xRecordCompare = sqlite3VdbeFindCompare(pIdxKey);
-    pIdxKey->isCorrupt = 0;
+    pIdxKey->errCode = 0;
     assert( pIdxKey->default_rc==1 
          || pIdxKey->default_rc==0 
          || pIdxKey->default_rc==-1
@@ -56187,7 +57936,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
       for(;;){
         i64 nCellKey;
         pCell = findCell(pPage, idx) + pPage->childPtrSize;
-        if( pPage->hasData ){
+        if( pPage->intKeyLeaf ){
           while( 0x80 <= *(pCell++) ){
             if( pCell>=pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT;
           }
@@ -56235,14 +57984,14 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
           ** single byte varint and the record fits entirely on the main
           ** b-tree page.  */
           testcase( pCell+nCell+1==pPage->aDataEnd );
-          c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey, 0);
+          c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey);
         }else if( !(pCell[1] & 0x80) 
           && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal
         ){
           /* The record-size field is a 2 byte varint and the record 
           ** fits entirely on the main b-tree page.  */
           testcase( pCell+nCell+2==pPage->aDataEnd );
-          c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey, 0);
+          c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey);
         }else{
           /* The record flows over onto one or more overflow pages. In
           ** this case the whole cell needs to be parsed, a buffer allocated
@@ -56263,10 +58012,13 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
             sqlite3_free(pCellKey);
             goto moveto_finish;
           }
-          c = xRecordCompare(nCell, pCellKey, pIdxKey, 0);
+          c = xRecordCompare(nCell, pCellKey, pIdxKey);
           sqlite3_free(pCellKey);
         }
-        assert( pIdxKey->isCorrupt==0 || c==0 );
+        assert( 
+            (pIdxKey->errCode!=SQLITE_CORRUPT || c==0)
+         && (pIdxKey->errCode!=SQLITE_NOMEM || pCur->pBtree->db->mallocFailed)
+        );
         if( c<0 ){
           lwr = idx+1;
         }else if( c>0 ){
@@ -56276,7 +58028,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked(
           *pRes = 0;
           rc = SQLITE_OK;
           pCur->aiIdx[pCur->iPage] = (u16)idx;
-          if( pIdxKey->isCorrupt ) rc = SQLITE_CORRUPT;
+          if( pIdxKey->errCode ) rc = SQLITE_CORRUPT;
           goto moveto_finish;
         }
         if( lwr>upr ) break;
@@ -56331,6 +58083,12 @@ SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor *pCur){
 ** was already pointing to the last entry in the database before
 ** this routine was called, then set *pRes=1.
 **
+** The main entry point is sqlite3BtreeNext().  That routine is optimized
+** for the common case of merely incrementing the cell counter BtCursor.aiIdx
+** to the next cell on the current page.  The (slower) btreeNext() helper
+** routine is called when it is necessary to move to a different page or
+** to restore the cursor.
+**
 ** The calling function will set *pRes to 0 or 1.  The initial *pRes value
 ** will be 1 if the cursor being stepped corresponds to an SQL index and
 ** if this routine could have been skipped if that SQL index had been
@@ -56340,20 +58098,18 @@ SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor *pCur){
 ** SQLite btree implementation does not. (Note that the comdb2 btree
 ** implementation does use this hint, however.)
 */
-SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
+static SQLITE_NOINLINE int btreeNext(BtCursor *pCur, int *pRes){
   int rc;
   int idx;
   MemPage *pPage;
 
   assert( cursorHoldsMutex(pCur) );
-  assert( pRes!=0 );
-  assert( *pRes==0 || *pRes==1 );
   assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
+  assert( *pRes==0 );
   if( pCur->eState!=CURSOR_VALID ){
-    invalidateOverflowCache(pCur);
+    assert( (pCur->curFlags & BTCF_ValidOvfl)==0 );
     rc = restoreCursorPosition(pCur);
     if( rc!=SQLITE_OK ){
-      *pRes = 0;
       return rc;
     }
     if( CURSOR_INVALID==pCur->eState ){
@@ -56365,7 +58121,6 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
       pCur->eState = CURSOR_VALID;
       if( pCur->skipNext>0 ){
         pCur->skipNext = 0;
-        *pRes = 0;
         return SQLITE_OK;
       }
       pCur->skipNext = 0;
@@ -56383,18 +58138,11 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
   ** page into more than one b-tree structure. */
   testcase( idx>pPage->nCell );
 
-  pCur->info.nSize = 0;
-  pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
   if( idx>=pPage->nCell ){
     if( !pPage->leaf ){
       rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
-      if( rc ){
-        *pRes = 0;
-        return rc;
-      }
-      rc = moveToLeftmost(pCur);
-      *pRes = 0;
-      return rc;
+      if( rc ) return rc;
+      return moveToLeftmost(pCur);
     }
     do{
       if( pCur->iPage==0 ){
@@ -56405,29 +58153,52 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
       moveToParent(pCur);
       pPage = pCur->apPage[pCur->iPage];
     }while( pCur->aiIdx[pCur->iPage]>=pPage->nCell );
-    *pRes = 0;
     if( pPage->intKey ){
-      rc = sqlite3BtreeNext(pCur, pRes);
+      return sqlite3BtreeNext(pCur, pRes);
     }else{
-      rc = SQLITE_OK;
+      return SQLITE_OK;
     }
-    return rc;
   }
+  if( pPage->leaf ){
+    return SQLITE_OK;
+  }else{
+    return moveToLeftmost(pCur);
+  }
+}
+SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
+  MemPage *pPage;
+  assert( cursorHoldsMutex(pCur) );
+  assert( pRes!=0 );
+  assert( *pRes==0 || *pRes==1 );
+  assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
+  pCur->info.nSize = 0;
+  pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
   *pRes = 0;
+  if( pCur->eState!=CURSOR_VALID ) return btreeNext(pCur, pRes);
+  pPage = pCur->apPage[pCur->iPage];
+  if( (++pCur->aiIdx[pCur->iPage])>=pPage->nCell ){
+    pCur->aiIdx[pCur->iPage]--;
+    return btreeNext(pCur, pRes);
+  }
   if( pPage->leaf ){
     return SQLITE_OK;
+  }else{
+    return moveToLeftmost(pCur);
   }
-  rc = moveToLeftmost(pCur);
-  return rc;
 }
 
-
 /*
 ** Step the cursor to the back to the previous entry in the database.  If
 ** successful then set *pRes=0.  If the cursor
 ** was already pointing to the first entry in the database before
 ** this routine was called, then set *pRes=1.
 **
+** The main entry point is sqlite3BtreePrevious().  That routine is optimized
+** for the common case of merely decrementing the cell counter BtCursor.aiIdx
+** to the previous cell on the current page.  The (slower) btreePrevious()
+** helper routine is called when it is necessary to move to a different page
+** or to restore the cursor.
+**
 ** The calling function will set *pRes to 0 or 1.  The initial *pRes value
 ** will be 1 if the cursor being stepped corresponds to an SQL index and
 ** if this routine could have been skipped if that SQL index had been
@@ -56437,22 +58208,20 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
 ** SQLite btree implementation does not. (Note that the comdb2 btree
 ** implementation does use this hint, however.)
 */
-SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
+static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur, int *pRes){
   int rc;
   MemPage *pPage;
 
   assert( cursorHoldsMutex(pCur) );
   assert( pRes!=0 );
-  assert( *pRes==0 || *pRes==1 );
+  assert( *pRes==0 );
   assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
-  pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl);
+  assert( (pCur->curFlags & (BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey))==0 );
+  assert( pCur->info.nSize==0 );
   if( pCur->eState!=CURSOR_VALID ){
-    if( ALWAYS(pCur->eState>=CURSOR_REQUIRESEEK) ){
-      rc = btreeRestoreCursorPosition(pCur);
-      if( rc!=SQLITE_OK ){
-        *pRes = 0;
-        return rc;
-      }
+    rc = restoreCursorPosition(pCur);
+    if( rc!=SQLITE_OK ){
+      return rc;
     }
     if( CURSOR_INVALID==pCur->eState ){
       *pRes = 1;
@@ -56463,7 +58232,6 @@ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
       pCur->eState = CURSOR_VALID;
       if( pCur->skipNext<0 ){
         pCur->skipNext = 0;
-        *pRes = 0;
         return SQLITE_OK;
       }
       pCur->skipNext = 0;
@@ -56475,10 +58243,7 @@ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
   if( !pPage->leaf ){
     int idx = pCur->aiIdx[pCur->iPage];
     rc = moveToChild(pCur, get4byte(findCell(pPage, idx)));
-    if( rc ){
-      *pRes = 0;
-      return rc;
-    }
+    if( rc ) return rc;
     rc = moveToRightmost(pCur);
   }else{
     while( pCur->aiIdx[pCur->iPage]==0 ){
@@ -56489,8 +58254,8 @@ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
       }
       moveToParent(pCur);
     }
-    pCur->info.nSize = 0;
-    pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl);
+    assert( pCur->info.nSize==0 );
+    assert( (pCur->curFlags & (BTCF_ValidNKey|BTCF_ValidOvfl))==0 );
 
     pCur->aiIdx[pCur->iPage]--;
     pPage = pCur->apPage[pCur->iPage];
@@ -56500,9 +58265,25 @@ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
       rc = SQLITE_OK;
     }
   }
-  *pRes = 0;
   return rc;
 }
+SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
+  assert( cursorHoldsMutex(pCur) );
+  assert( pRes!=0 );
+  assert( *pRes==0 || *pRes==1 );
+  assert( pCur->skipNext==0 || pCur->eState!=CURSOR_VALID );
+  *pRes = 0;
+  pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidOvfl|BTCF_ValidNKey);
+  pCur->info.nSize = 0;
+  if( pCur->eState!=CURSOR_VALID
+   || pCur->aiIdx[pCur->iPage]==0
+   || pCur->apPage[pCur->iPage]->leaf==0
+  ){
+    return btreePrevious(pCur, pRes);
+  }
+  pCur->aiIdx[pCur->iPage]--;
+  return SQLITE_OK;
+}
 
 /*
 ** Allocate a new page from the database file.
@@ -56546,6 +58327,8 @@ static int allocateBtreePage(
   assert( eMode==BTALLOC_ANY || (nearby>0 && IfNotOmitAV(pBt->autoVacuum)) );
   pPage1 = pBt->pPage1;
   mxPage = btreePagecount(pBt);
+  /* EVIDENCE-OF: R-05119-02637 The 4-byte big-endian integer at offset 36
+  ** stores stores the total number of pages on the freelist. */
   n = get4byte(&pPage1->aData[36]);
   testcase( n==mxPage-1 );
   if( n>=mxPage ){
@@ -56592,8 +58375,14 @@ static int allocateBtreePage(
     do {
       pPrevTrunk = pTrunk;
       if( pPrevTrunk ){
+        /* EVIDENCE-OF: R-01506-11053 The first integer on a freelist trunk page
+        ** is the page number of the next freelist trunk page in the list or
+        ** zero if this is the last freelist trunk page. */
         iTrunk = get4byte(&pPrevTrunk->aData[0]);
       }else{
+        /* EVIDENCE-OF: R-59841-13798 The 4-byte big-endian integer at offset 32
+        ** stores the page number of the first page of the freelist, or zero if
+        ** the freelist is empty. */
         iTrunk = get4byte(&pPage1->aData[32]);
       }
       testcase( iTrunk==mxPage );
@@ -56608,8 +58397,9 @@ static int allocateBtreePage(
       }
       assert( pTrunk!=0 );
       assert( pTrunk->aData!=0 );
-
-      k = get4byte(&pTrunk->aData[4]); /* # of leaves on this trunk page */
+      /* EVIDENCE-OF: R-13523-04394 The second integer on a freelist trunk page
+      ** is the number of leaf page pointers to follow. */
+      k = get4byte(&pTrunk->aData[4]);
       if( k==0 && !searchList ){
         /* The trunk has no leaves and the list is not being searched. 
         ** So extract the trunk page itself and use it as the newly 
@@ -56743,7 +58533,7 @@ static int allocateBtreePage(
             memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
           }
           put4byte(&aData[4], k-1);
-          noContent = !btreeGetHasContent(pBt, *pPgno) ? PAGER_GET_NOCONTENT : 0;
+          noContent = !btreeGetHasContent(pBt, *pPgno)? PAGER_GET_NOCONTENT : 0;
           rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
           if( rc==SQLITE_OK ){
             rc = sqlite3PagerWrite((*ppPage)->pDbPage);
@@ -56776,7 +58566,7 @@ static int allocateBtreePage(
     ** here are confined to those pages that lie between the end of the
     ** database image and the end of the database file.
     */
-    int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate)) ? PAGER_GET_NOCONTENT : 0;
+    int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate))? PAGER_GET_NOCONTENT:0;
 
     rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
     if( rc ) return rc;
@@ -56927,6 +58717,11 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
       ** for now.  At some point in the future (once everyone has upgraded
       ** to 3.6.0 or later) we should consider fixing the conditional above
       ** to read "usableSize/4-2" instead of "usableSize/4-8".
+      **
+      ** EVIDENCE-OF: R-19920-11576 However, newer versions of SQLite still
+      ** avoid using the last six entries in the freelist trunk page array in
+      ** order that database files created by newer versions of SQLite can be
+      ** read by older versions of SQLite.
       */
       rc = sqlite3PagerWrite(pTrunk->pDbPage);
       if( rc==SQLITE_OK ){
@@ -56975,9 +58770,15 @@ static void freePage(MemPage *pPage, int *pRC){
 }
 
 /*
-** Free any overflow pages associated with the given Cell.
+** Free any overflow pages associated with the given Cell.  Write the
+** local Cell size (the number of bytes on the original page, omitting
+** overflow) into *pnSize.
 */
-static int clearCell(MemPage *pPage, unsigned char *pCell){
+static int clearCell(
+  MemPage *pPage,          /* The page that contains the Cell */
+  unsigned char *pCell,    /* First byte of the Cell */
+  u16 *pnSize              /* Write the size of the Cell here */
+){
   BtShared *pBt = pPage->pBt;
   CellInfo info;
   Pgno ovflPgno;
@@ -56987,6 +58788,7 @@ static int clearCell(MemPage *pPage, unsigned char *pCell){
 
   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
   btreeParseCellPtr(pPage, pCell, &info);
+  *pnSize = info.nSize;
   if( info.iOverflow==0 ){
     return SQLITE_OK;  /* No overflow pages. Return without doing anything */
   }
@@ -57070,7 +58872,6 @@ static int fillInCell(
   BtShared *pBt = pPage->pBt;
   Pgno pgnoOvfl = 0;
   int nHeader;
-  CellInfo info;
 
   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
 
@@ -57080,23 +58881,17 @@ static int fillInCell(
             || sqlite3PagerIswriteable(pPage->pDbPage) );
 
   /* Fill in the header. */
-  nHeader = 0;
-  if( !pPage->leaf ){
-    nHeader += 4;
-  }
-  if( pPage->hasData ){
-    nHeader += putVarint32(&pCell[nHeader], nData+nZero);
+  nHeader = pPage->childPtrSize;
+  nPayload = nData + nZero;
+  if( pPage->intKeyLeaf ){
+    nHeader += putVarint32(&pCell[nHeader], nPayload);
   }else{
-    nData = nZero = 0;
+    assert( nData==0 );
+    assert( nZero==0 );
   }
   nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey);
-  btreeParseCellPtr(pPage, pCell, &info);
-  assert( info.nHeader==nHeader );
-  assert( info.nKey==nKey );
-  assert( info.nData==(u32)(nData+nZero) );
   
-  /* Fill in the payload */
-  nPayload = nData + nZero;
+  /* Fill in the payload size */
   if( pPage->intKey ){
     pSrc = pData;
     nSrc = nData;
@@ -57105,15 +58900,55 @@ static int fillInCell(
     if( NEVER(nKey>0x7fffffff || pKey==0) ){
       return SQLITE_CORRUPT_BKPT;
     }
-    nPayload += (int)nKey;
+    nPayload = (int)nKey;
     pSrc = pKey;
     nSrc = (int)nKey;
   }
-  *pnSize = info.nSize;
-  spaceLeft = info.nLocal;
+  if( nPayload<=pPage->maxLocal ){
+    n = nHeader + nPayload;
+    testcase( n==3 );
+    testcase( n==4 );
+    if( n<4 ) n = 4;
+    *pnSize = n;
+    spaceLeft = nPayload;
+    pPrior = pCell;
+  }else{
+    int mn = pPage->minLocal;
+    n = mn + (nPayload - mn) % (pPage->pBt->usableSize - 4);
+    testcase( n==pPage->maxLocal );
+    testcase( n==pPage->maxLocal+1 );
+    if( n > pPage->maxLocal ) n = mn;
+    spaceLeft = n;
+    *pnSize = n + nHeader + 4;
+    pPrior = &pCell[nHeader+n];
+  }
   pPayload = &pCell[nHeader];
-  pPrior = &pCell[info.iOverflow];
 
+  /* At this point variables should be set as follows:
+  **
+  **   nPayload           Total payload size in bytes
+  **   pPayload           Begin writing payload here
+  **   spaceLeft          Space available at pPayload.  If nPayload>spaceLeft,
+  **                      that means content must spill into overflow pages.
+  **   *pnSize            Size of the local cell (not counting overflow pages)
+  **   pPrior             Where to write the pgno of the first overflow page
+  **
+  ** Use a call to btreeParseCellPtr() to verify that the values above
+  ** were computed correctly.
+  */
+#if SQLITE_DEBUG
+  {
+    CellInfo info;
+    btreeParseCellPtr(pPage, pCell, &info);
+    assert( nHeader=(int)(info.pPayload - pCell) );
+    assert( info.nKey==nKey );
+    assert( *pnSize == info.nSize );
+    assert( spaceLeft == info.nLocal );
+    assert( pPrior == &pCell[info.iOverflow] );
+  }
+#endif
+
+  /* Write the payload into the local Cell and any extra into overflow pages */
   while( nPayload>0 ){
     if( spaceLeft==0 ){
 #ifndef SQLITE_OMIT_AUTOVACUUM
@@ -57238,9 +59073,17 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
     return;
   }
   pPage->nCell--;
-  memmove(ptr, ptr+2, 2*(pPage->nCell - idx));
-  put2byte(&data[hdr+3], pPage->nCell);
-  pPage->nFree += 2;
+  if( pPage->nCell==0 ){
+    memset(&data[hdr+1], 0, 4);
+    data[hdr+7] = 0;
+    put2byte(&data[hdr+5], pPage->pBt->usableSize);
+    pPage->nFree = pPage->pBt->usableSize - pPage->hdrOffset
+                       - pPage->childPtrSize - 8;
+  }else{
+    memmove(ptr, ptr+2, 2*(pPage->nCell - idx));
+    put2byte(&data[hdr+3], pPage->nCell);
+    pPage->nFree += 2;
+  }
 }
 
 /*
@@ -57254,11 +59097,6 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){
 ** in pTemp or the original pCell) and also record its index. 
 ** Allocating a new entry in pPage->aCell[] implies that 
 ** pPage->nOverflow is incremented.
-**
-** If nSkip is non-zero, then do not copy the first nSkip bytes of the
-** cell. The caller will overwrite them after this function returns. If
-** nSkip is non-zero, then pCell may not point to an invalid memory location 
-** (but pCell+nSkip is always valid).
 */
 static void insertCell(
   MemPage *pPage,   /* Page into which we are copying */
@@ -57275,7 +59113,6 @@ static void insertCell(
   int ins;          /* Index in data[] where new cell pointer is inserted */
   int cellOffset;   /* Address of first cell pointer in data[] */
   u8 *data;         /* The content of the whole page */
-  int nSkip = (iChild ? 4 : 0);
 
   if( *pRC ) return;
 
@@ -57293,7 +59130,7 @@ static void insertCell(
   assert( sz==cellSizePtr(pPage, pCell) || (sz==8 && iChild>0) );
   if( pPage->nOverflow || sz+2>pPage->nFree ){
     if( pTemp ){
-      memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip);
+      memcpy(pTemp, pCell, sz);
       pCell = pTemp;
     }
     if( iChild ){
@@ -57322,7 +59159,7 @@ static void insertCell(
     assert( idx+sz <= (int)pPage->pBt->usableSize );
     pPage->nCell++;
     pPage->nFree -= (u16)(2 + sz);
-    memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip);
+    memcpy(&data[idx], pCell, sz);
     if( iChild ){
       put4byte(&data[idx], iChild);
     }
@@ -57341,45 +59178,271 @@ static void insertCell(
 }
 
 /*
-** Add a list of cells to a page.  The page should be initially empty.
-** The cells are guaranteed to fit on the page.
+** Array apCell[] contains pointers to nCell b-tree page cells. The 
+** szCell[] array contains the size in bytes of each cell. This function
+** replaces the current contents of page pPg with the contents of the cell
+** array.
+**
+** Some of the cells in apCell[] may currently be stored in pPg. This
+** function works around problems caused by this by making a copy of any 
+** such cells before overwriting the page data.
+**
+** The MemPage.nFree field is invalidated by this function. It is the 
+** responsibility of the caller to set it correctly.
 */
-static void assemblePage(
-  MemPage *pPage,   /* The page to be assemblied */
-  int nCell,        /* The number of cells to add to this page */
-  u8 **apCell,      /* Pointers to cell bodies */
-  u16 *aSize        /* Sizes of the cells */
+static void rebuildPage(
+  MemPage *pPg,                   /* Edit this page */
+  int nCell,                      /* Final number of cells on page */
+  u8 **apCell,                    /* Array of cells */
+  u16 *szCell                     /* Array of cell sizes */
 ){
-  int i;            /* Loop counter */
-  u8 *pCellptr;     /* Address of next cell pointer */
-  int cellbody;     /* Address of next cell body */
-  u8 * const data = pPage->aData;             /* Pointer to data for pPage */
-  const int hdr = pPage->hdrOffset;           /* Offset of header on pPage */
-  const int nUsable = pPage->pBt->usableSize; /* Usable size of page */
+  const int hdr = pPg->hdrOffset;          /* Offset of header on pPg */
+  u8 * const aData = pPg->aData;           /* Pointer to data for pPg */
+  const int usableSize = pPg->pBt->usableSize;
+  u8 * const pEnd = &aData[usableSize];
+  int i;
+  u8 *pCellptr = pPg->aCellIdx;
+  u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager);
+  u8 *pData;
 
-  assert( pPage->nOverflow==0 );
-  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
-  assert( nCell>=0 && nCell<=(int)MX_CELL(pPage->pBt)
-            && (int)MX_CELL(pPage->pBt)<=10921);
-  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
+  i = get2byte(&aData[hdr+5]);
+  memcpy(&pTmp[i], &aData[i], usableSize - i);
+
+  pData = pEnd;
+  for(i=0; i<nCell; i++){
+    u8 *pCell = apCell[i];
+    if( pCell>aData && pCell<pEnd ){
+      pCell = &pTmp[pCell - aData];
+    }
+    pData -= szCell[i];
+    memcpy(pData, pCell, szCell[i]);
+    put2byte(pCellptr, (pData - aData));
+    pCellptr += 2;
+    assert( szCell[i]==cellSizePtr(pPg, pCell) );
+  }
+
+  /* The pPg->nFree field is now set incorrectly. The caller will fix it. */
+  pPg->nCell = nCell;
+  pPg->nOverflow = 0;
 
-  /* Check that the page has just been zeroed by zeroPage() */
-  assert( pPage->nCell==0 );
-  assert( get2byteNotZero(&data[hdr+5])==nUsable );
+  put2byte(&aData[hdr+1], 0);
+  put2byte(&aData[hdr+3], pPg->nCell);
+  put2byte(&aData[hdr+5], pData - aData);
+  aData[hdr+7] = 0x00;
+}
 
-  pCellptr = &pPage->aCellIdx[nCell*2];
-  cellbody = nUsable;
-  for(i=nCell-1; i>=0; i--){
-    u16 sz = aSize[i];
-    pCellptr -= 2;
-    cellbody -= sz;
-    put2byte(pCellptr, cellbody);
-    memcpy(&data[cellbody], apCell[i], sz);
+/*
+** Array apCell[] contains nCell pointers to b-tree cells. Array szCell
+** contains the size in bytes of each such cell. This function attempts to 
+** add the cells stored in the array to page pPg. If it cannot (because 
+** the page needs to be defragmented before the cells will fit), non-zero
+** is returned. Otherwise, if the cells are added successfully, zero is
+** returned.
+**
+** Argument pCellptr points to the first entry in the cell-pointer array
+** (part of page pPg) to populate. After cell apCell[0] is written to the
+** page body, a 16-bit offset is written to pCellptr. And so on, for each
+** cell in the array. It is the responsibility of the caller to ensure
+** that it is safe to overwrite this part of the cell-pointer array.
+**
+** When this function is called, *ppData points to the start of the 
+** content area on page pPg. If the size of the content area is extended,
+** *ppData is updated to point to the new start of the content area
+** before returning.
+**
+** Finally, argument pBegin points to the byte immediately following the
+** end of the space required by this page for the cell-pointer area (for
+** all cells - not just those inserted by the current call). If the content
+** area must be extended to before this point in order to accomodate all
+** cells in apCell[], then the cells do not fit and non-zero is returned.
+*/
+static int pageInsertArray(
+  MemPage *pPg,                   /* Page to add cells to */
+  u8 *pBegin,                     /* End of cell-pointer array */
+  u8 **ppData,                    /* IN/OUT: Page content -area pointer */
+  u8 *pCellptr,                   /* Pointer to cell-pointer area */
+  int nCell,                      /* Number of cells to add to pPg */
+  u8 **apCell,                    /* Array of cells */
+  u16 *szCell                     /* Array of cell sizes */
+){
+  int i;
+  u8 *aData = pPg->aData;
+  u8 *pData = *ppData;
+  const int bFreelist = aData[1] || aData[2];
+  assert( CORRUPT_DB || pPg->hdrOffset==0 );    /* Never called on page 1 */
+  for(i=0; i<nCell; i++){
+    int sz = szCell[i];
+    int rc;
+    u8 *pSlot;
+    if( bFreelist==0 || (pSlot = pageFindSlot(pPg, sz, &rc, 0))==0 ){
+      pData -= sz;
+      if( pData<pBegin ) return 1;
+      pSlot = pData;
+    }
+    memcpy(pSlot, apCell[i], sz);
+    put2byte(pCellptr, (pSlot - aData));
+    pCellptr += 2;
   }
-  put2byte(&data[hdr+3], nCell);
-  put2byte(&data[hdr+5], cellbody);
-  pPage->nFree -= (nCell*2 + nUsable - cellbody);
-  pPage->nCell = (u16)nCell;
+  *ppData = pData;
+  return 0;
+}
+
+/*
+** Array apCell[] contains nCell pointers to b-tree cells. Array szCell 
+** contains the size in bytes of each such cell. This function adds the
+** space associated with each cell in the array that is currently stored 
+** within the body of pPg to the pPg free-list. The cell-pointers and other
+** fields of the page are not updated.
+**
+** This function returns the total number of cells added to the free-list.
+*/
+static int pageFreeArray(
+  MemPage *pPg,                   /* Page to edit */
+  int nCell,                      /* Cells to delete */
+  u8 **apCell,                    /* Array of cells */
+  u16 *szCell                     /* Array of cell sizes */
+){
+  u8 * const aData = pPg->aData;
+  u8 * const pEnd = &aData[pPg->pBt->usableSize];
+  u8 * const pStart = &aData[pPg->hdrOffset + 8 + pPg->childPtrSize];
+  int nRet = 0;
+  int i;
+  u8 *pFree = 0;
+  int szFree = 0;
+
+  for(i=0; i<nCell; i++){
+    u8 *pCell = apCell[i];
+    if( pCell>=pStart && pCell<pEnd ){
+      int sz = szCell[i];
+      if( pFree!=(pCell + sz) ){
+        if( pFree ){
+          assert( pFree>aData && (pFree - aData)<65536 );
+          freeSpace(pPg, (u16)(pFree - aData), szFree);
+        }
+        pFree = pCell;
+        szFree = sz;
+        if( pFree+sz>pEnd ) return 0;
+      }else{
+        pFree = pCell;
+        szFree += sz;
+      }
+      nRet++;
+    }
+  }
+  if( pFree ){
+    assert( pFree>aData && (pFree - aData)<65536 );
+    freeSpace(pPg, (u16)(pFree - aData), szFree);
+  }
+  return nRet;
+}
+
+/*
+** apCell[] and szCell[] contains pointers to and sizes of all cells in the
+** pages being balanced.  The current page, pPg, has pPg->nCell cells starting
+** with apCell[iOld].  After balancing, this page should hold nNew cells
+** starting at apCell[iNew].
+**
+** This routine makes the necessary adjustments to pPg so that it contains
+** the correct cells after being balanced.
+**
+** The pPg->nFree field is invalid when this function returns. It is the
+** responsibility of the caller to set it correctly.
+*/
+static void editPage(
+  MemPage *pPg,                   /* Edit this page */
+  int iOld,                       /* Index of first cell currently on page */
+  int iNew,                       /* Index of new first cell on page */
+  int nNew,                       /* Final number of cells on page */
+  u8 **apCell,                    /* Array of cells */
+  u16 *szCell                     /* Array of cell sizes */
+){
+  u8 * const aData = pPg->aData;
+  const int hdr = pPg->hdrOffset;
+  u8 *pBegin = &pPg->aCellIdx[nNew * 2];
+  int nCell = pPg->nCell;       /* Cells stored on pPg */
+  u8 *pData;
+  u8 *pCellptr;
+  int i;
+  int iOldEnd = iOld + pPg->nCell + pPg->nOverflow;
+  int iNewEnd = iNew + nNew;
+
+#ifdef SQLITE_DEBUG
+  u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager);
+  memcpy(pTmp, aData, pPg->pBt->usableSize);
+#endif
+
+  /* Remove cells from the start and end of the page */
+  if( iOld<iNew ){
+    int nShift = pageFreeArray(
+        pPg, iNew-iOld, &apCell[iOld], &szCell[iOld]
+    );
+    memmove(pPg->aCellIdx, &pPg->aCellIdx[nShift*2], nCell*2);
+    nCell -= nShift;
+  }
+  if( iNewEnd < iOldEnd ){
+    nCell -= pageFreeArray(
+        pPg, iOldEnd-iNewEnd, &apCell[iNewEnd], &szCell[iNewEnd]
+    );
+  }
+
+  pData = &aData[get2byteNotZero(&aData[hdr+5])];
+  if( pData<pBegin ) goto editpage_fail;
+
+  /* Add cells to the start of the page */
+  if( iNew<iOld ){
+    int nAdd = MIN(nNew,iOld-iNew);
+    assert( (iOld-iNew)<nNew || nCell==0 || CORRUPT_DB );
+    pCellptr = pPg->aCellIdx;
+    memmove(&pCellptr[nAdd*2], pCellptr, nCell*2);
+    if( pageInsertArray(
+          pPg, pBegin, &pData, pCellptr,
+          nAdd, &apCell[iNew], &szCell[iNew]
+    ) ) goto editpage_fail;
+    nCell += nAdd;
+  }
+
+  /* Add any overflow cells */
+  for(i=0; i<pPg->nOverflow; i++){
+    int iCell = (iOld + pPg->aiOvfl[i]) - iNew;
+    if( iCell>=0 && iCell<nNew ){
+      pCellptr = &pPg->aCellIdx[iCell * 2];
+      memmove(&pCellptr[2], pCellptr, (nCell - iCell) * 2);
+      nCell++;
+      if( pageInsertArray(
+            pPg, pBegin, &pData, pCellptr,
+            1, &apCell[iCell + iNew], &szCell[iCell + iNew]
+      ) ) goto editpage_fail;
+    }
+  }
+
+  /* Append cells to the end of the page */
+  pCellptr = &pPg->aCellIdx[nCell*2];
+  if( pageInsertArray(
+        pPg, pBegin, &pData, pCellptr,
+        nNew-nCell, &apCell[iNew+nCell], &szCell[iNew+nCell]
+  ) ) goto editpage_fail;
+
+  pPg->nCell = nNew;
+  pPg->nOverflow = 0;
+
+  put2byte(&aData[hdr+3], pPg->nCell);
+  put2byte(&aData[hdr+5], pData - aData);
+
+#ifdef SQLITE_DEBUG
+  for(i=0; i<nNew && !CORRUPT_DB; i++){
+    u8 *pCell = apCell[i+iNew];
+    int iOff = get2byte(&pPg->aCellIdx[i*2]);
+    if( pCell>=aData && pCell<&aData[pPg->pBt->usableSize] ){
+      pCell = &pTmp[pCell - aData];
+    }
+    assert( 0==memcmp(pCell, &aData[iOff], szCell[i+iNew]) );
+  }
+#endif
+
+  return;
+ editpage_fail:
+  /* Unable to edit this page. Rebuild it from scratch instead. */
+  rebuildPage(pPg, nNew, &apCell[iNew], &szCell[iNew]);
 }
 
 /*
@@ -57433,7 +59496,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
   assert( pPage->nOverflow==1 );
 
   /* This error condition is now caught prior to reaching this function */
-  if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT;
+  if( NEVER(pPage->nCell==0) ) return SQLITE_CORRUPT_BKPT;
 
   /* Allocate a new page. This page will become the right-sibling of 
   ** pPage. Make the parent page writable, so that the new divider cell
@@ -57451,7 +59514,8 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){
     assert( sqlite3PagerIswriteable(pNew->pDbPage) );
     assert( pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) );
     zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF);
-    assemblePage(pNew, 1, &pCell, &szCell);
+    rebuildPage(pNew, 1, &pCell, &szCell);
+    pNew->nFree = pBt->usableSize - pNew->cellOffset - 2 - szCell;
 
     /* If this is an auto-vacuum database, update the pointer map
     ** with entries for the new page, and any pointer from the 
@@ -57670,17 +59734,22 @@ static int balance_nonroot(
   int iOvflSpace = 0;          /* First unused byte of aOvflSpace[] */
   int szScratch;               /* Size of scratch memory requested */
   MemPage *apOld[NB];          /* pPage and up to two siblings */
-  MemPage *apCopy[NB];         /* Private copies of apOld[] pages */
   MemPage *apNew[NB+2];        /* pPage and up to NB siblings after balancing */
   u8 *pRight;                  /* Location in parent of right-sibling pointer */
   u8 *apDiv[NB-1];             /* Divider cells in pParent */
   int cntNew[NB+2];            /* Index in aCell[] of cell after i-th page */
-  int szNew[NB+2];             /* Combined size of cells place on i-th page */
+  int cntOld[NB+2];            /* Old index in aCell[] after i-th page */
+  int szNew[NB+2];             /* Combined size of cells placed on i-th page */
   u8 **apCell = 0;             /* All cells begin balanced */
   u16 *szCell;                 /* Local size of all cells in apCell[] */
   u8 *aSpace1;                 /* Space for copies of dividers cells */
   Pgno pgno;                   /* Temp var to store a page number in */
+  u8 abDone[NB+2];             /* True after i'th new page is populated */
+  Pgno aPgno[NB+2];            /* Page numbers of new pages before shuffling */
+  Pgno aPgOrder[NB+2];         /* Copy of aPgno[] used for sorting pages */
+  u16 aPgFlags[NB+2];          /* flags field of new pages before shuffling */
 
+  memset(abDone, 0, sizeof(abDone));
   pBt = pParent->pBt;
   assert( sqlite3_mutex_held(pBt->mutex) );
   assert( sqlite3PagerIswriteable(pParent->pDbPage) );
@@ -57722,7 +59791,6 @@ static int balance_nonroot(
     }else if( iParentIdx==i ){
       nxDiv = i-2+bBulk;
     }else{
-      assert( bBulk==0 );
       nxDiv = iParentIdx-1;
     }
     i = 2-bBulk;
@@ -57789,12 +59857,14 @@ static int balance_nonroot(
   /*
   ** Allocate space for memory structures
   */
-  k = pBt->pageSize + ROUND8(sizeof(MemPage));
   szScratch =
        nMaxCells*sizeof(u8*)                       /* apCell */
      + nMaxCells*sizeof(u16)                       /* szCell */
-     + pBt->pageSize                               /* aSpace1 */
-     + k*nOld;                                     /* Page copies (apCopy) */
+     + pBt->pageSize;                              /* aSpace1 */
+
+  /* EVIDENCE-OF: R-28375-38319 SQLite will never request a scratch buffer
+  ** that is more than 6 times the database page size. */
+  assert( szScratch<=6*(int)pBt->pageSize );
   apCell = sqlite3ScratchMalloc( szScratch ); 
   if( apCell==0 ){
     rc = SQLITE_NOMEM;
@@ -57807,8 +59877,8 @@ static int balance_nonroot(
   /*
   ** Load pointers to all cells on sibling pages and the divider cells
   ** into the local apCell[] array.  Make copies of the divider cells
-  ** into space obtained from aSpace1[] and remove the divider cells
-  ** from pParent.
+  ** into space obtained from aSpace1[]. The divider cells have already
+  ** been removed from pParent.
   **
   ** If the siblings are on leaf pages, then the child pointers of the
   ** divider cells are stripped from the cells before they are copied
@@ -57821,18 +59891,10 @@ static int balance_nonroot(
   **       leafData:  1 if pPage holds key+data and pParent holds only keys.
   */
   leafCorrection = apOld[0]->leaf*4;
-  leafData = apOld[0]->hasData;
+  leafData = apOld[0]->intKeyLeaf;
   for(i=0; i<nOld; i++){
     int limit;
-    
-    /* Before doing anything else, take a copy of the i'th original sibling
-    ** The rest of this function will use data from the copies rather
-    ** that the original pages since the original pages will be in the
-    ** process of being overwritten.  */
-    MemPage *pOld = apCopy[i] = (MemPage*)&aSpace1[pBt->pageSize + k*i];
-    memcpy(pOld, apOld[i], sizeof(MemPage));
-    pOld->aData = (void*)&pOld[1];
-    memcpy(pOld->aData, apOld[i]->aData, pBt->pageSize);
+    MemPage *pOld = apOld[i];
 
     limit = pOld->nCell+pOld->nOverflow;
     if( pOld->nOverflow>0 ){
@@ -57853,6 +59915,7 @@ static int balance_nonroot(
         nCell++;
       }
     }       
+    cntOld[i] = nCell;
     if( i<nOld-1 && !leafData){
       u16 sz = (u16)szNew[i];
       u8 *pTemp;
@@ -57875,7 +59938,11 @@ static int balance_nonroot(
       }else{
         assert( leafCorrection==4 );
         if( szCell[nCell]<4 ){
-          /* Do not allow any cells smaller than 4 bytes. */
+          /* Do not allow any cells smaller than 4 bytes. If a smaller cell
+          ** does exist, pad it with 0x00 bytes. */
+          assert( szCell[nCell]==3 );
+          assert( apCell[nCell]==&aSpace1[iSpace1-3] );
+          aSpace1[iSpace1++] = 0x00;
           szCell[nCell] = 4;
         }
       }
@@ -57904,7 +59971,7 @@ static int balance_nonroot(
     assert( i<nMaxCells );
     subtotal += szCell[i] + 2;
     if( subtotal > usableSpace ){
-      szNew[k] = subtotal - szCell[i];
+      szNew[k] = subtotal - szCell[i] - 2;
       cntNew[k] = i;
       if( leafData ){ i--; }
       subtotal = 0;
@@ -57918,9 +59985,10 @@ static int balance_nonroot(
 
   /*
   ** The packing computed by the previous block is biased toward the siblings
-  ** on the left side.  The left siblings are always nearly full, while the
-  ** right-most sibling might be nearly empty.  This block of code attempts
-  ** to adjust the packing of siblings to get a better balance.
+  ** on the left side (siblings with smaller keys). The left siblings are
+  ** always nearly full, while the right-most sibling might be nearly empty.
+  ** The next block of code attempts to adjust the packing of siblings to
+  ** get a better balance.
   **
   ** This adjustment is more than an optimization.  The packing above might
   ** be so out of balance as to be illegal.  For example, the right-most
@@ -57949,22 +60017,18 @@ static int balance_nonroot(
     szNew[i-1] = szLeft;
   }
 
-  /* Either we found one or more cells (cntnew[0])>0) or pPage is
-  ** a virtual root page.  A virtual root page is when the real root
-  ** page is page 1 and we are the only child of that page.
-  **
-  ** UPDATE:  The assert() below is not necessarily true if the database
-  ** file is corrupt.  The corruption will be detected and reported later
-  ** in this procedure so there is no need to act upon it now.
+  /* Sanity check:  For a non-corrupt database file one of the follwing
+  ** must be true:
+  **    (1) We found one or more cells (cntNew[0])>0), or
+  **    (2) pPage is a virtual root page.  A virtual root page is when
+  **        the real root page is page 1 and we are the only child of
+  **        that page.
   */
-#if 0
-  assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) );
-#endif
-
-  TRACE(("BALANCE: old: %d %d %d  ",
-    apOld[0]->pgno, 
-    nOld>=2 ? apOld[1]->pgno : 0,
-    nOld>=3 ? apOld[2]->pgno : 0
+  assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) || CORRUPT_DB);
+  TRACE(("BALANCE: old: %d(nc=%d) %d(nc=%d) %d(nc=%d)\n",
+    apOld[0]->pgno, apOld[0]->nCell,
+    nOld>=2 ? apOld[1]->pgno : 0, nOld>=2 ? apOld[1]->nCell : 0,
+    nOld>=3 ? apOld[2]->pgno : 0, nOld>=3 ? apOld[2]->nCell : 0
   ));
 
   /*
@@ -57987,8 +60051,10 @@ static int balance_nonroot(
       assert( i>0 );
       rc = allocateBtreePage(pBt, &pNew, &pgno, (bBulk ? 1 : pgno), 0);
       if( rc ) goto balance_cleanup;
+      zeroPage(pNew, pageFlags);
       apNew[i] = pNew;
       nNew++;
+      cntOld[i] = nCell;
 
       /* Set the pointer-map entry for the new sibling page. */
       if( ISAUTOVACUUM ){
@@ -58000,135 +60066,247 @@ static int balance_nonroot(
     }
   }
 
-  /* Free any old pages that were not reused as new pages.
-  */
-  while( i<nOld ){
-    freePage(apOld[i], &rc);
-    if( rc ) goto balance_cleanup;
-    releasePage(apOld[i]);
-    apOld[i] = 0;
-    i++;
-  }
-
   /*
-  ** Put the new pages in accending order.  This helps to
-  ** keep entries in the disk file in order so that a scan
-  ** of the table is a linear scan through the file.  That
-  ** in turn helps the operating system to deliver pages
-  ** from the disk more rapidly.
+  ** Reassign page numbers so that the new pages are in ascending order. 
+  ** This helps to keep entries in the disk file in order so that a scan
+  ** of the table is closer to a linear scan through the file. That in turn 
+  ** helps the operating system to deliver pages from the disk more rapidly.
   **
-  ** An O(n^2) insertion sort algorithm is used, but since
-  ** n is never more than NB (a small constant), that should
-  ** not be a problem.
+  ** An O(n^2) insertion sort algorithm is used, but since n is never more 
+  ** than (NB+2) (a small constant), that should not be a problem.
   **
-  ** When NB==3, this one optimization makes the database
-  ** about 25% faster for large insertions and deletions.
+  ** When NB==3, this one optimization makes the database about 25% faster 
+  ** for large insertions and deletions.
   */
-  for(i=0; i<k-1; i++){
-    int minV = apNew[i]->pgno;
-    int minI = i;
-    for(j=i+1; j<k; j++){
-      if( apNew[j]->pgno<(unsigned)minV ){
-        minI = j;
-        minV = apNew[j]->pgno;
+  for(i=0; i<nNew; i++){
+    aPgOrder[i] = aPgno[i] = apNew[i]->pgno;
+    aPgFlags[i] = apNew[i]->pDbPage->flags;
+    for(j=0; j<i; j++){
+      if( aPgno[j]==aPgno[i] ){
+        /* This branch is taken if the set of sibling pages somehow contains
+        ** duplicate entries. This can happen if the database is corrupt. 
+        ** It would be simpler to detect this as part of the loop below, but
+        ** we do the detection here in order to avoid populating the pager
+        ** cache with two separate objects associated with the same
+        ** page number.  */
+        assert( CORRUPT_DB );
+        rc = SQLITE_CORRUPT_BKPT;
+        goto balance_cleanup;
       }
     }
-    if( minI>i ){
-      MemPage *pT;
-      pT = apNew[i];
-      apNew[i] = apNew[minI];
-      apNew[minI] = pT;
+  }
+  for(i=0; i<nNew; i++){
+    int iBest = 0;                /* aPgno[] index of page number to use */
+    for(j=1; j<nNew; j++){
+      if( aPgOrder[j]<aPgOrder[iBest] ) iBest = j;
+    }
+    pgno = aPgOrder[iBest];
+    aPgOrder[iBest] = 0xffffffff;
+    if( iBest!=i ){
+      if( iBest>i ){
+        sqlite3PagerRekey(apNew[iBest]->pDbPage, pBt->nPage+iBest+1, 0);
+      }
+      sqlite3PagerRekey(apNew[i]->pDbPage, pgno, aPgFlags[iBest]);
+      apNew[i]->pgno = pgno;
     }
   }
-  TRACE(("new: %d(%d) %d(%d) %d(%d) %d(%d) %d(%d)\n",
-    apNew[0]->pgno, szNew[0],
+
+  TRACE(("BALANCE: new: %d(%d nc=%d) %d(%d nc=%d) %d(%d nc=%d) "
+         "%d(%d nc=%d) %d(%d nc=%d)\n",
+    apNew[0]->pgno, szNew[0], cntNew[0],
     nNew>=2 ? apNew[1]->pgno : 0, nNew>=2 ? szNew[1] : 0,
+    nNew>=2 ? cntNew[1] - cntNew[0] - !leafData : 0,
     nNew>=3 ? apNew[2]->pgno : 0, nNew>=3 ? szNew[2] : 0,
+    nNew>=3 ? cntNew[2] - cntNew[1] - !leafData : 0,
     nNew>=4 ? apNew[3]->pgno : 0, nNew>=4 ? szNew[3] : 0,
-    nNew>=5 ? apNew[4]->pgno : 0, nNew>=5 ? szNew[4] : 0));
+    nNew>=4 ? cntNew[3] - cntNew[2] - !leafData : 0,
+    nNew>=5 ? apNew[4]->pgno : 0, nNew>=5 ? szNew[4] : 0,
+    nNew>=5 ? cntNew[4] - cntNew[3] - !leafData : 0
+  ));
 
   assert( sqlite3PagerIswriteable(pParent->pDbPage) );
   put4byte(pRight, apNew[nNew-1]->pgno);
 
-  /*
-  ** Evenly distribute the data in apCell[] across the new pages.
-  ** Insert divider cells into pParent as necessary.
+  /* If the sibling pages are not leaves, ensure that the right-child pointer
+  ** of the right-most new sibling page is set to the value that was 
+  ** originally in the same field of the right-most old sibling page. */
+  if( (pageFlags & PTF_LEAF)==0 && nOld!=nNew ){
+    MemPage *pOld = (nNew>nOld ? apNew : apOld)[nOld-1];
+    memcpy(&apNew[nNew-1]->aData[8], &pOld->aData[8], 4);
+  }
+
+  /* Make any required updates to pointer map entries associated with 
+  ** cells stored on sibling pages following the balance operation. Pointer
+  ** map entries associated with divider cells are set by the insertCell()
+  ** routine. The associated pointer map entries are:
+  **
+  **   a) if the cell contains a reference to an overflow chain, the
+  **      entry associated with the first page in the overflow chain, and
+  **
+  **   b) if the sibling pages are not leaves, the child page associated
+  **      with the cell.
+  **
+  ** If the sibling pages are not leaves, then the pointer map entry 
+  ** associated with the right-child of each sibling may also need to be 
+  ** updated. This happens below, after the sibling pages have been 
+  ** populated, not here.
   */
-  j = 0;
-  for(i=0; i<nNew; i++){
-    /* Assemble the new sibling page. */
+  if( ISAUTOVACUUM ){
+    MemPage *pNew = apNew[0];
+    u8 *aOld = pNew->aData;
+    int cntOldNext = pNew->nCell + pNew->nOverflow;
+    int usableSize = pBt->usableSize;
+    int iNew = 0;
+    int iOld = 0;
+
+    for(i=0; i<nCell; i++){
+      u8 *pCell = apCell[i];
+      if( i==cntOldNext ){
+        MemPage *pOld = (++iOld)<nNew ? apNew[iOld] : apOld[iOld];
+        cntOldNext += pOld->nCell + pOld->nOverflow + !leafData;
+        aOld = pOld->aData;
+      }
+      if( i==cntNew[iNew] ){
+        pNew = apNew[++iNew];
+        if( !leafData ) continue;
+      }
+
+      /* Cell pCell is destined for new sibling page pNew. Originally, it
+      ** was either part of sibling page iOld (possibly an overflow cell), 
+      ** or else the divider cell to the left of sibling page iOld. So,
+      ** if sibling page iOld had the same page number as pNew, and if
+      ** pCell really was a part of sibling page iOld (not a divider or
+      ** overflow cell), we can skip updating the pointer map entries.  */
+      if( iOld>=nNew
+       || pNew->pgno!=aPgno[iOld]
+       || pCell<aOld
+       || pCell>=&aOld[usableSize]
+      ){
+        if( !leafCorrection ){
+          ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc);
+        }
+        if( szCell[i]>pNew->minLocal ){
+          ptrmapPutOvflPtr(pNew, pCell, &rc);
+        }
+      }
+    }
+  }
+
+  /* Insert new divider cells into pParent. */
+  for(i=0; i<nNew-1; i++){
+    u8 *pCell;
+    u8 *pTemp;
+    int sz;
     MemPage *pNew = apNew[i];
+    j = cntNew[i];
+
     assert( j<nMaxCells );
-    zeroPage(pNew, pageFlags);
-    assemblePage(pNew, cntNew[i]-j, &apCell[j], &szCell[j]);
-    assert( pNew->nCell>0 || (nNew==1 && cntNew[0]==0) );
-    assert( pNew->nOverflow==0 );
+    pCell = apCell[j];
+    sz = szCell[j] + leafCorrection;
+    pTemp = &aOvflSpace[iOvflSpace];
+    if( !pNew->leaf ){
+      memcpy(&pNew->aData[8], pCell, 4);
+    }else if( leafData ){
+      /* If the tree is a leaf-data tree, and the siblings are leaves, 
+      ** then there is no divider cell in apCell[]. Instead, the divider 
+      ** cell consists of the integer key for the right-most cell of 
+      ** the sibling-page assembled above only.
+      */
+      CellInfo info;
+      j--;
+      btreeParseCellPtr(pNew, apCell[j], &info);
+      pCell = pTemp;
+      sz = 4 + putVarint(&pCell[4], info.nKey);
+      pTemp = 0;
+    }else{
+      pCell -= 4;
+      /* Obscure case for non-leaf-data trees: If the cell at pCell was
+      ** previously stored on a leaf node, and its reported size was 4
+      ** bytes, then it may actually be smaller than this 
+      ** (see btreeParseCellPtr(), 4 bytes is the minimum size of
+      ** any cell). But it is important to pass the correct size to 
+      ** insertCell(), so reparse the cell now.
+      **
+      ** Note that this can never happen in an SQLite data file, as all
+      ** cells are at least 4 bytes. It only happens in b-trees used
+      ** to evaluate "IN (SELECT ...)" and similar clauses.
+      */
+      if( szCell[j]==4 ){
+        assert(leafCorrection==4);
+        sz = cellSizePtr(pParent, pCell);
+      }
+    }
+    iOvflSpace += sz;
+    assert( sz<=pBt->maxLocal+23 );
+    assert( iOvflSpace <= (int)pBt->pageSize );
+    insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno, &rc);
+    if( rc!=SQLITE_OK ) goto balance_cleanup;
+    assert( sqlite3PagerIswriteable(pParent->pDbPage) );
+  }
 
-    j = cntNew[i];
+  /* Now update the actual sibling pages. The order in which they are updated
+  ** is important, as this code needs to avoid disrupting any page from which
+  ** cells may still to be read. In practice, this means:
+  **
+  **  (1) If cells are moving left (from apNew[iPg] to apNew[iPg-1])
+  **      then it is not safe to update page apNew[iPg] until after
+  **      the left-hand sibling apNew[iPg-1] has been updated.
+  **
+  **  (2) If cells are moving right (from apNew[iPg] to apNew[iPg+1])
+  **      then it is not safe to update page apNew[iPg] until after
+  **      the right-hand sibling apNew[iPg+1] has been updated.
+  **
+  ** If neither of the above apply, the page is safe to update.
+  **
+  ** The iPg value in the following loop starts at nNew-1 goes down
+  ** to 0, then back up to nNew-1 again, thus making two passes over
+  ** the pages.  On the initial downward pass, only condition (1) above
+  ** needs to be tested because (2) will always be true from the previous
+  ** step.  On the upward pass, both conditions are always true, so the
+  ** upwards pass simply processes pages that were missed on the downward
+  ** pass.
+  */
+  for(i=1-nNew; i<nNew; i++){
+    int iPg = i<0 ? -i : i;
+    assert( iPg>=0 && iPg<nNew );
+    if( abDone[iPg] ) continue;         /* Skip pages already processed */
+    if( i>=0                            /* On the upwards pass, or... */
+     || cntOld[iPg-1]>=cntNew[iPg-1]    /* Condition (1) is true */
+    ){
+      int iNew;
+      int iOld;
+      int nNewCell;
 
-    /* If the sibling page assembled above was not the right-most sibling,
-    ** insert a divider cell into the parent page.
-    */
-    assert( i<nNew-1 || j==nCell );
-    if( j<nCell ){
-      u8 *pCell;
-      u8 *pTemp;
-      int sz;
+      /* Verify condition (1):  If cells are moving left, update iPg
+      ** only after iPg-1 has already been updated. */
+      assert( iPg==0 || cntOld[iPg-1]>=cntNew[iPg-1] || abDone[iPg-1] );
 
-      assert( j<nMaxCells );
-      pCell = apCell[j];
-      sz = szCell[j] + leafCorrection;
-      pTemp = &aOvflSpace[iOvflSpace];
-      if( !pNew->leaf ){
-        memcpy(&pNew->aData[8], pCell, 4);
-      }else if( leafData ){
-        /* If the tree is a leaf-data tree, and the siblings are leaves, 
-        ** then there is no divider cell in apCell[]. Instead, the divider 
-        ** cell consists of the integer key for the right-most cell of 
-        ** the sibling-page assembled above only.
-        */
-        CellInfo info;
-        j--;
-        btreeParseCellPtr(pNew, apCell[j], &info);
-        pCell = pTemp;
-        sz = 4 + putVarint(&pCell[4], info.nKey);
-        pTemp = 0;
+      /* Verify condition (2):  If cells are moving right, update iPg
+      ** only after iPg+1 has already been updated. */
+      assert( cntNew[iPg]>=cntOld[iPg] || abDone[iPg+1] );
+
+      if( iPg==0 ){
+        iNew = iOld = 0;
+        nNewCell = cntNew[0];
       }else{
-        pCell -= 4;
-        /* Obscure case for non-leaf-data trees: If the cell at pCell was
-        ** previously stored on a leaf node, and its reported size was 4
-        ** bytes, then it may actually be smaller than this 
-        ** (see btreeParseCellPtr(), 4 bytes is the minimum size of
-        ** any cell). But it is important to pass the correct size to 
-        ** insertCell(), so reparse the cell now.
-        **
-        ** Note that this can never happen in an SQLite data file, as all
-        ** cells are at least 4 bytes. It only happens in b-trees used
-        ** to evaluate "IN (SELECT ...)" and similar clauses.
-        */
-        if( szCell[j]==4 ){
-          assert(leafCorrection==4);
-          sz = cellSizePtr(pParent, pCell);
-        }
+        iOld = iPg<nOld ? (cntOld[iPg-1] + !leafData) : nCell;
+        iNew = cntNew[iPg-1] + !leafData;
+        nNewCell = cntNew[iPg] - iNew;
       }
-      iOvflSpace += sz;
-      assert( sz<=pBt->maxLocal+23 );
-      assert( iOvflSpace <= (int)pBt->pageSize );
-      insertCell(pParent, nxDiv, pCell, sz, pTemp, pNew->pgno, &rc);
-      if( rc!=SQLITE_OK ) goto balance_cleanup;
-      assert( sqlite3PagerIswriteable(pParent->pDbPage) );
 
-      j++;
-      nxDiv++;
+      editPage(apNew[iPg], iOld, iNew, nNewCell, apCell, szCell);
+      abDone[iPg]++;
+      apNew[iPg]->nFree = usableSpace-szNew[iPg];
+      assert( apNew[iPg]->nOverflow==0 );
+      assert( apNew[iPg]->nCell==nNewCell );
     }
   }
-  assert( j==nCell );
+
+  /* All pages have been processed exactly once */
+  assert( memcmp(abDone, "\01\01\01\01\01", nNew)==0 );
+
   assert( nOld>0 );
   assert( nNew>0 );
-  if( (pageFlags & PTF_LEAF)==0 ){
-    u8 *zChild = &apCopy[nOld-1]->aData[8];
-    memcpy(&apNew[nNew-1]->aData[8], zChild, 4);
-  }
 
   if( isRoot && pParent->nCell==0 && pParent->hdrOffset<=apNew[0]->nFree ){
     /* The root page of the b-tree now contains no cells. The only sibling
@@ -58141,126 +60319,50 @@ static int balance_nonroot(
     ** sets all pointer-map entries corresponding to database image pages 
     ** for which the pointer is stored within the content being copied.
     **
-    ** The second assert below verifies that the child page is defragmented
-    ** (it must be, as it was just reconstructed using assemblePage()). This
-    ** is important if the parent page happens to be page 1 of the database
-    ** image.  */
+    ** It is critical that the child page be defragmented before being
+    ** copied into the parent, because if the parent is page 1 then it will
+    ** by smaller than the child due to the database header, and so all the
+    ** free space needs to be up front.
+    */
     assert( nNew==1 );
+    rc = defragmentPage(apNew[0]);
+    testcase( rc!=SQLITE_OK );
     assert( apNew[0]->nFree == 
-        (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2) 
+        (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2)
+      || rc!=SQLITE_OK
     );
     copyNodeContent(apNew[0], pParent, &rc);
     freePage(apNew[0], &rc);
-  }else if( ISAUTOVACUUM ){
-    /* Fix the pointer-map entries for all the cells that were shifted around. 
-    ** There are several different types of pointer-map entries that need to
-    ** be dealt with by this routine. Some of these have been set already, but
-    ** many have not. The following is a summary:
-    **
-    **   1) The entries associated with new sibling pages that were not
-    **      siblings when this function was called. These have already
-    **      been set. We don't need to worry about old siblings that were
-    **      moved to the free-list - the freePage() code has taken care
-    **      of those.
-    **
-    **   2) The pointer-map entries associated with the first overflow
-    **      page in any overflow chains used by new divider cells. These 
-    **      have also already been taken care of by the insertCell() code.
-    **
-    **   3) If the sibling pages are not leaves, then the child pages of
-    **      cells stored on the sibling pages may need to be updated.
-    **
-    **   4) If the sibling pages are not internal intkey nodes, then any
-    **      overflow pages used by these cells may need to be updated
-    **      (internal intkey nodes never contain pointers to overflow pages).
-    **
-    **   5) If the sibling pages are not leaves, then the pointer-map
-    **      entries for the right-child pages of each sibling may need
-    **      to be updated.
-    **
-    ** Cases 1 and 2 are dealt with above by other code. The next
-    ** block deals with cases 3 and 4 and the one after that, case 5. Since
-    ** setting a pointer map entry is a relatively expensive operation, this
-    ** code only sets pointer map entries for child or overflow pages that have
-    ** actually moved between pages.  */
-    MemPage *pNew = apNew[0];
-    MemPage *pOld = apCopy[0];
-    int nOverflow = pOld->nOverflow;
-    int iNextOld = pOld->nCell + nOverflow;
-    int iOverflow = (nOverflow ? pOld->aiOvfl[0] : -1);
-    j = 0;                             /* Current 'old' sibling page */
-    k = 0;                             /* Current 'new' sibling page */
-    for(i=0; i<nCell; i++){
-      int isDivider = 0;
-      while( i==iNextOld ){
-        /* Cell i is the cell immediately following the last cell on old
-        ** sibling page j. If the siblings are not leaf pages of an
-        ** intkey b-tree, then cell i was a divider cell. */
-        assert( j+1 < ArraySize(apCopy) );
-        assert( j+1 < nOld );
-        pOld = apCopy[++j];
-        iNextOld = i + !leafData + pOld->nCell + pOld->nOverflow;
-        if( pOld->nOverflow ){
-          nOverflow = pOld->nOverflow;
-          iOverflow = i + !leafData + pOld->aiOvfl[0];
-        }
-        isDivider = !leafData;  
-      }
-
-      assert(nOverflow>0 || iOverflow<i );
-      assert(nOverflow<2 || pOld->aiOvfl[0]==pOld->aiOvfl[1]-1);
-      assert(nOverflow<3 || pOld->aiOvfl[1]==pOld->aiOvfl[2]-1);
-      if( i==iOverflow ){
-        isDivider = 1;
-        if( (--nOverflow)>0 ){
-          iOverflow++;
-        }
-      }
-
-      if( i==cntNew[k] ){
-        /* Cell i is the cell immediately following the last cell on new
-        ** sibling page k. If the siblings are not leaf pages of an
-        ** intkey b-tree, then cell i is a divider cell.  */
-        pNew = apNew[++k];
-        if( !leafData ) continue;
-      }
-      assert( j<nOld );
-      assert( k<nNew );
-
-      /* If the cell was originally divider cell (and is not now) or
-      ** an overflow cell, or if the cell was located on a different sibling
-      ** page before the balancing, then the pointer map entries associated
-      ** with any child or overflow pages need to be updated.  */
-      if( isDivider || pOld->pgno!=pNew->pgno ){
-        if( !leafCorrection ){
-          ptrmapPut(pBt, get4byte(apCell[i]), PTRMAP_BTREE, pNew->pgno, &rc);
-        }
-        if( szCell[i]>pNew->minLocal ){
-          ptrmapPutOvflPtr(pNew, apCell[i], &rc);
-        }
-      }
+  }else if( ISAUTOVACUUM && !leafCorrection ){
+    /* Fix the pointer map entries associated with the right-child of each
+    ** sibling page. All other pointer map entries have already been taken
+    ** care of.  */
+    for(i=0; i<nNew; i++){
+      u32 key = get4byte(&apNew[i]->aData[8]);
+      ptrmapPut(pBt, key, PTRMAP_BTREE, apNew[i]->pgno, &rc);
     }
+  }
 
-    if( !leafCorrection ){
-      for(i=0; i<nNew; i++){
-        u32 key = get4byte(&apNew[i]->aData[8]);
-        ptrmapPut(pBt, key, PTRMAP_BTREE, apNew[i]->pgno, &rc);
-      }
-    }
+  assert( pParent->isInit );
+  TRACE(("BALANCE: finished: old=%d new=%d cells=%d\n",
+          nOld, nNew, nCell));
+
+  /* Free any old pages that were not reused as new pages.
+  */
+  for(i=nNew; i<nOld; i++){
+    freePage(apOld[i], &rc);
+  }
 
 #if 0
+  if( ISAUTOVACUUM && rc==SQLITE_OK && apNew[0]->isInit ){
     /* The ptrmapCheckPages() contains assert() statements that verify that
     ** all pointer map pages are set correctly. This is helpful while 
     ** debugging. This is usually disabled because a corrupt database may
     ** cause an assert() statement to fail.  */
     ptrmapCheckPages(apNew, nNew);
     ptrmapCheckPages(&pParent, 1);
-#endif
   }
-
-  assert( pParent->isInit );
-  TRACE(("BALANCE: finished: old=%d new=%d cells=%d\n",
-          nOld, nNew, nCell));
+#endif
 
   /*
   ** Cleanup before returning.
@@ -58397,7 +60499,7 @@ static int balance(BtCursor *pCur){
       rc = sqlite3PagerWrite(pParent->pDbPage);
       if( rc==SQLITE_OK ){
 #ifndef SQLITE_OMIT_QUICKBALANCE
-        if( pPage->hasData
+        if( pPage->intKeyLeaf
          && pPage->nOverflow==1
          && pPage->aiOvfl[0]==pPage->nCell
          && pParent->pgno!=1
@@ -58406,7 +60508,7 @@ static int balance(BtCursor *pCur){
           /* Call balance_quick() to create a new sibling of pPage on which
           ** to store the overflow cell. balance_quick() inserts a new cell
           ** into pParent, which may cause pParent overflow. If this
-          ** happens, the next interation of the do-loop will balance pParent 
+          ** happens, the next iteration of the do-loop will balance pParent 
           ** use either balance_nonroot() or balance_deeper(). Until this
           ** happens, the overflow cell is stored in the aBalanceQuickSpace[]
           ** buffer. 
@@ -58439,7 +60541,8 @@ static int balance(BtCursor *pCur){
           ** pSpace buffer passed to the latter call to balance_nonroot().
           */
           u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize);
-          rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1, pCur->hints);
+          rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1,
+                               pCur->hints&BTREE_BULKLOAD);
           if( pFree ){
             /* If pFree is not NULL, it points to the pSpace buffer used 
             ** by a previous call to balance_nonroot(). Its contents are
@@ -58460,6 +60563,7 @@ static int balance(BtCursor *pCur){
       /* The next iteration of the do-loop balances the parent page. */
       releasePage(pPage);
       pCur->iPage--;
+      assert( pCur->iPage>=0 );
     }
   }while( rc==SQLITE_OK );
 
@@ -58483,7 +60587,7 @@ static int balance(BtCursor *pCur){
 ** MovetoUnpacked() to seek cursor pCur to (pKey, nKey) has already
 ** been performed. seekResult is the search result returned (a negative
 ** number if pCur points at an entry that is smaller than (pKey, nKey), or
-** a positive value if pCur points at an etry that is larger than 
+** a positive value if pCur points at an entry that is larger than 
 ** (pKey, nKey)). 
 **
 ** If the seekResult parameter is non-zero, then the caller guarantees that
@@ -58516,7 +60620,8 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
   }
 
   assert( cursorHoldsMutex(pCur) );
-  assert( (pCur->curFlags & BTCF_WriteFlag)!=0 && pBt->inTransaction==TRANS_WRITE
+  assert( (pCur->curFlags & BTCF_WriteFlag)!=0
+              && pBt->inTransaction==TRANS_WRITE
               && (pBt->btsFlags & BTS_READ_ONLY)==0 );
   assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
 
@@ -58549,7 +60654,8 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
     /* If the cursor is currently on the last row and we are appending a
     ** new row onto the end, set the "loc" to avoid an unnecessary btreeMoveto()
     ** call */
-    if( (pCur->curFlags&BTCF_ValidNKey)!=0 && nKey>0 && pCur->info.nKey==nKey-1 ){
+    if( (pCur->curFlags&BTCF_ValidNKey)!=0 && nKey>0
+      && pCur->info.nKey==nKey-1 ){
       loc = -1;
     }
   }
@@ -58568,9 +60674,8 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
           pCur->pgnoRoot, nKey, nData, pPage->pgno,
           loc==0 ? "overwrite" : "new entry"));
   assert( pPage->isInit );
-  allocateTempSpace(pBt);
   newCell = pBt->pTmpSpace;
-  if( newCell==0 ) return SQLITE_NOMEM;
+  assert( newCell!=0 );
   rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, nZero, &szNew);
   if( rc ) goto end_insert;
   assert( szNew==cellSizePtr(pPage, newCell) );
@@ -58587,8 +60692,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert(
     if( !pPage->leaf ){
       memcpy(newCell, oldCell, 4);
     }
-    szOld = cellSizePtr(pPage, oldCell);
-    rc = clearCell(pPage, oldCell);
+    rc = clearCell(pPage, oldCell, &szOld);
     dropCell(pPage, idx, szOld, &rc);
     if( rc ) goto end_insert;
   }else if( loc<0 && pPage->nCell>0 ){
@@ -58640,7 +60744,7 @@ end_insert:
 
 /*
 ** Delete the entry that the cursor is pointing to.  The cursor
-** is left pointing at a arbitrary location.
+** is left pointing at an arbitrary location.
 */
 SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){
   Btree *p = pCur->pBtree;
@@ -58650,6 +60754,7 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){
   unsigned char *pCell;                /* Pointer to cell to delete */
   int iCellIdx;                        /* Index of cell to delete */
   int iCellDepth;                      /* Depth of node containing pCell */ 
+  u16 szCell;                          /* Size of the cell being deleted */
 
   assert( cursorHoldsMutex(pCur) );
   assert( pBt->inTransaction==TRANS_WRITE );
@@ -58698,8 +60803,8 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){
 
   rc = sqlite3PagerWrite(pPage->pDbPage);
   if( rc ) return rc;
-  rc = clearCell(pPage, pCell);
-  dropCell(pPage, iCellIdx, cellSizePtr(pPage, pCell), &rc);
+  rc = clearCell(pPage, pCell, &szCell);
+  dropCell(pPage, iCellIdx, szCell, &rc);
   if( rc ) return rc;
 
   /* If the cell deleted was not located on a leaf page, then the cursor
@@ -58716,10 +60821,8 @@ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){
     pCell = findCell(pLeaf, pLeaf->nCell-1);
     nCell = cellSizePtr(pLeaf, pCell);
     assert( MX_CELL_SIZE(pBt) >= nCell );
-
-    allocateTempSpace(pBt);
     pTmp = pBt->pTmpSpace;
-
+    assert( pTmp!=0 );
     rc = sqlite3PagerWrite(pLeaf->pDbPage);
     insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc);
     dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc);
@@ -58931,14 +61034,19 @@ static int clearDatabasePage(
   unsigned char *pCell;
   int i;
   int hdr;
+  u16 szCell;
 
   assert( sqlite3_mutex_held(pBt->mutex) );
   if( pgno>btreePagecount(pBt) ){
     return SQLITE_CORRUPT_BKPT;
   }
-
   rc = getAndInitPage(pBt, pgno, &pPage, 0);
   if( rc ) return rc;
+  if( pPage->bBusy ){
+    rc = SQLITE_CORRUPT_BKPT;
+    goto cleardatabasepage_out;
+  }
+  pPage->bBusy = 1;
   hdr = pPage->hdrOffset;
   for(i=0; i<pPage->nCell; i++){
     pCell = findCell(pPage, i);
@@ -58946,7 +61054,7 @@ static int clearDatabasePage(
       rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange);
       if( rc ) goto cleardatabasepage_out;
     }
-    rc = clearCell(pPage, pCell);
+    rc = clearCell(pPage, pCell, &szCell);
     if( rc ) goto cleardatabasepage_out;
   }
   if( !pPage->leaf ){
@@ -58963,6 +61071,7 @@ static int clearDatabasePage(
   }
 
 cleardatabasepage_out:
+  pPage->bBusy = 0;
   releasePage(pPage);
   return rc;
 }
@@ -59152,6 +61261,13 @@ SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){
 ** The schema layer numbers meta values differently.  At the schema
 ** layer (and the SetCookie and ReadCookie opcodes) the number of
 ** free pages is not visible.  So Cookie[0] is the same as Meta[1].
+**
+** This routine treats Meta[BTREE_DATA_VERSION] as a special case.  Instead
+** of reading the value out of the header, it instead loads the "DataVersion"
+** from the pager.  The BTREE_DATA_VERSION value is not actually stored in the
+** database file.  It is a number computed by the pager.  But its access
+** pattern is the same as header meta values, and so it is convenient to
+** read it from this routine.
 */
 SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
   BtShared *pBt = p->pBt;
@@ -59162,7 +61278,11 @@ SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){
   assert( pBt->pPage1 );
   assert( idx>=0 && idx<=15 );
 
-  *pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]);
+  if( idx==BTREE_DATA_VERSION ){
+    *pMeta = sqlite3PagerDataVersion(pBt->pPager) + p->iDataVersion;
+  }else{
+    *pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]);
+  }
 
   /* If auto-vacuum is disabled in this build and this is an auto-vacuum
   ** database, mark the database as read-only.  */
@@ -59253,7 +61373,7 @@ SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){
         if( pCur->iPage==0 ){
           /* All pages of the b-tree have been visited. Return successfully. */
           *pnEntry = nEntry;
-          return SQLITE_OK;
+          return moveToRoot(pCur);
         }
         moveToParent(pCur);
       }while ( pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell );
@@ -59292,11 +61412,11 @@ SQLITE_PRIVATE Pager *sqlite3BtreePager(Btree *p){
 */
 static void checkAppendMsg(
   IntegrityCk *pCheck,
-  char *zMsg1,
   const char *zFormat,
   ...
 ){
   va_list ap;
+  char zBuf[200];
   if( !pCheck->mxErr ) return;
   pCheck->mxErr--;
   pCheck->nErr++;
@@ -59304,8 +61424,9 @@ static void checkAppendMsg(
   if( pCheck->errMsg.nChar ){
     sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
   }
-  if( zMsg1 ){
-    sqlite3StrAccumAppendAll(&pCheck->errMsg, zMsg1);
+  if( pCheck->zPfx ){
+    sqlite3_snprintf(sizeof(zBuf), zBuf, pCheck->zPfx, pCheck->v1, pCheck->v2);
+    sqlite3StrAccumAppendAll(&pCheck->errMsg, zBuf);
   }
   sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
   va_end(ap);
@@ -59338,19 +61459,19 @@ static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){
 /*
 ** Add 1 to the reference count for page iPage.  If this is the second
 ** reference to the page, add an error message to pCheck->zErrMsg.
-** Return 1 if there are 2 ore more references to the page and 0 if
+** Return 1 if there are 2 or more references to the page and 0 if
 ** if this is the first reference to the page.
 **
 ** Also check that the page number is in bounds.
 */
-static int checkRef(IntegrityCk *pCheck, Pgno iPage, char *zContext){
+static int checkRef(IntegrityCk *pCheck, Pgno iPage){
   if( iPage==0 ) return 1;
   if( iPage>pCheck->nPage ){
-    checkAppendMsg(pCheck, zContext, "invalid page number %d", iPage);
+    checkAppendMsg(pCheck, "invalid page number %d", iPage);
     return 1;
   }
   if( getPageReferenced(pCheck, iPage) ){
-    checkAppendMsg(pCheck, zContext, "2nd reference to page %d", iPage);
+    checkAppendMsg(pCheck, "2nd reference to page %d", iPage);
     return 1;
   }
   setPageReferenced(pCheck, iPage);
@@ -59367,8 +61488,7 @@ static void checkPtrmap(
   IntegrityCk *pCheck,   /* Integrity check context */
   Pgno iChild,           /* Child page number */
   u8 eType,              /* Expected pointer map type */
-  Pgno iParent,          /* Expected pointer map parent page number */
-  char *zContext         /* Context description (used for error msg) */
+  Pgno iParent           /* Expected pointer map parent page number */
 ){
   int rc;
   u8 ePtrmapType;
@@ -59377,12 +61497,12 @@ static void checkPtrmap(
   rc = ptrmapGet(pCheck->pBt, iChild, &ePtrmapType, &iPtrmapParent);
   if( rc!=SQLITE_OK ){
     if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) pCheck->mallocFailed = 1;
-    checkAppendMsg(pCheck, zContext, "Failed to read ptrmap key=%d", iChild);
+    checkAppendMsg(pCheck, "Failed to read ptrmap key=%d", iChild);
     return;
   }
 
   if( ePtrmapType!=eType || iPtrmapParent!=iParent ){
-    checkAppendMsg(pCheck, zContext, 
+    checkAppendMsg(pCheck,
       "Bad ptr map entry key=%d expected=(%d,%d) got=(%d,%d)", 
       iChild, eType, iParent, ePtrmapType, iPtrmapParent);
   }
@@ -59397,8 +61517,7 @@ static void checkList(
   IntegrityCk *pCheck,  /* Integrity checking context */
   int isFreeList,       /* True for a freelist.  False for overflow page list */
   int iPage,            /* Page number for first page in the list */
-  int N,                /* Expected number of pages in the list */
-  char *zContext        /* Context for error messages */
+  int N                 /* Expected number of pages in the list */
 ){
   int i;
   int expected = N;
@@ -59407,14 +61526,14 @@ static void checkList(
     DbPage *pOvflPage;
     unsigned char *pOvflData;
     if( iPage<1 ){
-      checkAppendMsg(pCheck, zContext,
+      checkAppendMsg(pCheck,
          "%d of %d pages missing from overflow list starting at %d",
           N+1, expected, iFirst);
       break;
     }
-    if( checkRef(pCheck, iPage, zContext) ) break;
+    if( checkRef(pCheck, iPage) ) break;
     if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage) ){
-      checkAppendMsg(pCheck, zContext, "failed to get page %d", iPage);
+      checkAppendMsg(pCheck, "failed to get page %d", iPage);
       break;
     }
     pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage);
@@ -59422,11 +61541,11 @@ static void checkList(
       int n = get4byte(&pOvflData[4]);
 #ifndef SQLITE_OMIT_AUTOVACUUM
       if( pCheck->pBt->autoVacuum ){
-        checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0, zContext);
+        checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0);
       }
 #endif
       if( n>(int)pCheck->pBt->usableSize/4-2 ){
-        checkAppendMsg(pCheck, zContext,
+        checkAppendMsg(pCheck,
            "freelist leaf count too big on page %d", iPage);
         N--;
       }else{
@@ -59434,10 +61553,10 @@ static void checkList(
           Pgno iFreePage = get4byte(&pOvflData[8+i*4]);
 #ifndef SQLITE_OMIT_AUTOVACUUM
           if( pCheck->pBt->autoVacuum ){
-            checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0, zContext);
+            checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0);
           }
 #endif
-          checkRef(pCheck, iFreePage, zContext);
+          checkRef(pCheck, iFreePage);
         }
         N -= n;
       }
@@ -59450,7 +61569,7 @@ static void checkList(
       */
       if( pCheck->pBt->autoVacuum && N>0 ){
         i = get4byte(pOvflData);
-        checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage, zContext);
+        checkPtrmap(pCheck, i, PTRMAP_OVERFLOW2, iPage);
       }
     }
 #endif
@@ -59460,6 +61579,57 @@ static void checkList(
 }
 #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
 
+/*
+** An implementation of a min-heap.
+**
+** aHeap[0] is the number of elements on the heap.  aHeap[1] is the
+** root element.  The daughter nodes of aHeap[N] are aHeap[N*2]
+** and aHeap[N*2+1].
+**
+** The heap property is this:  Every node is less than or equal to both
+** of its daughter nodes.  A consequence of the heap property is that the
+** root node aHeap[1] is always the minimum value currently in the heap.
+**
+** The btreeHeapInsert() routine inserts an unsigned 32-bit number onto
+** the heap, preserving the heap property.  The btreeHeapPull() routine
+** removes the root element from the heap (the minimum value in the heap)
+** and then moves other nodes around as necessary to preserve the heap
+** property.
+**
+** This heap is used for cell overlap and coverage testing.  Each u32
+** entry represents the span of a cell or freeblock on a btree page.  
+** The upper 16 bits are the index of the first byte of a range and the
+** lower 16 bits are the index of the last byte of that range.
+*/
+static void btreeHeapInsert(u32 *aHeap, u32 x){
+  u32 j, i = ++aHeap[0];
+  aHeap[i] = x;
+  while( (j = i/2)>0 && aHeap[j]>aHeap[i] ){
+    x = aHeap[j];
+    aHeap[j] = aHeap[i];
+    aHeap[i] = x;
+    i = j;
+  }
+}
+static int btreeHeapPull(u32 *aHeap, u32 *pOut){
+  u32 j, i, x;
+  if( (x = aHeap[0])==0 ) return 0;
+  *pOut = aHeap[1];
+  aHeap[1] = aHeap[x];
+  aHeap[x] = 0xffffffff;
+  aHeap[0]--;
+  i = 1;
+  while( (j = i*2)<=aHeap[0] ){
+    if( aHeap[j]>aHeap[j+1] ) j++;
+    if( aHeap[i]<aHeap[j] ) break;
+    x = aHeap[i];
+    aHeap[i] = aHeap[j];
+    aHeap[j] = x;
+    i = j;
+  }
+  return 1;  
+}
+
 #ifndef SQLITE_OMIT_INTEGRITY_CHECK
 /*
 ** Do various sanity checks on a single page of a tree.  Return
@@ -59482,7 +61652,6 @@ static void checkList(
 static int checkTreePage(
   IntegrityCk *pCheck,  /* Context for the sanity check */
   int iPage,            /* Page number of the page to check */
-  char *zParentContext, /* Parent context */
   i64 *pnParentMinKey, 
   i64 *pnParentMaxKey
 ){
@@ -59493,23 +61662,27 @@ static int checkTreePage(
   u8 *data;
   BtShared *pBt;
   int usableSize;
-  char zContext[100];
-  char *hit = 0;
+  u32 *heap = 0;
+  u32 x, prev = 0;
   i64 nMinKey = 0;
   i64 nMaxKey = 0;
-
-  sqlite3_snprintf(sizeof(zContext), zContext, "Page %d: ", iPage);
+  const char *saved_zPfx = pCheck->zPfx;
+  int saved_v1 = pCheck->v1;
+  int saved_v2 = pCheck->v2;
 
   /* Check that the page exists
   */
   pBt = pCheck->pBt;
   usableSize = pBt->usableSize;
   if( iPage==0 ) return 0;
-  if( checkRef(pCheck, iPage, zParentContext) ) return 0;
+  if( checkRef(pCheck, iPage) ) return 0;
+  pCheck->zPfx = "Page %d: ";
+  pCheck->v1 = iPage;
   if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){
-    checkAppendMsg(pCheck, zContext,
+    checkAppendMsg(pCheck,
        "unable to get the page. error code=%d", rc);
-    return 0;
+    depth = -1;
+    goto end_of_check;
   }
 
   /* Clear MemPage.isInit to make sure the corruption detection code in
@@ -59517,10 +61690,11 @@ static int checkTreePage(
   pPage->isInit = 0;
   if( (rc = btreeInitPage(pPage))!=0 ){
     assert( rc==SQLITE_CORRUPT );  /* The only possible error from InitPage */
-    checkAppendMsg(pCheck, zContext, 
+    checkAppendMsg(pCheck,
                    "btreeInitPage() returns error code %d", rc);
     releasePage(pPage);
-    return 0;
+    depth = -1;
+    goto end_of_check;
   }
 
   /* Check out all the cells.
@@ -59533,23 +61707,23 @@ static int checkTreePage(
 
     /* Check payload overflow pages
     */
-    sqlite3_snprintf(sizeof(zContext), zContext,
-             "On tree page %d cell %d: ", iPage, i);
+    pCheck->zPfx = "On tree page %d cell %d: ";
+    pCheck->v1 = iPage;
+    pCheck->v2 = i;
     pCell = findCell(pPage,i);
     btreeParseCellPtr(pPage, pCell, &info);
-    sz = info.nData;
-    if( !pPage->intKey ) sz += (int)info.nKey;
+    sz = info.nPayload;
     /* For intKey pages, check that the keys are in order.
     */
-    else if( i==0 ) nMinKey = nMaxKey = info.nKey;
-    else{
-      if( info.nKey <= nMaxKey ){
-        checkAppendMsg(pCheck, zContext, 
-            "Rowid %lld out of order (previous was %lld)", info.nKey, nMaxKey);
+    if( pPage->intKey ){
+      if( i==0 ){
+        nMinKey = nMaxKey = info.nKey;
+      }else if( info.nKey <= nMaxKey ){
+        checkAppendMsg(pCheck,
+           "Rowid %lld out of order (previous was %lld)", info.nKey, nMaxKey);
       }
       nMaxKey = info.nKey;
     }
-    assert( sz==info.nPayload );
     if( (sz>info.nLocal) 
      && (&pCell[info.iOverflow]<=&pPage->aData[pBt->usableSize])
     ){
@@ -59557,10 +61731,10 @@ static int checkTreePage(
       Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]);
 #ifndef SQLITE_OMIT_AUTOVACUUM
       if( pBt->autoVacuum ){
-        checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage, zContext);
+        checkPtrmap(pCheck, pgnoOvfl, PTRMAP_OVERFLOW1, iPage);
       }
 #endif
-      checkList(pCheck, 0, pgnoOvfl, nPage, zContext);
+      checkList(pCheck, 0, pgnoOvfl, nPage);
     }
 
     /* Check sanity of left child page.
@@ -59569,12 +61743,12 @@ static int checkTreePage(
       pgno = get4byte(pCell);
 #ifndef SQLITE_OMIT_AUTOVACUUM
       if( pBt->autoVacuum ){
-        checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext);
+        checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage);
       }
 #endif
-      d2 = checkTreePage(pCheck, pgno, zContext, &nMinKey, i==0 ? NULL : &nMaxKey);
+      d2 = checkTreePage(pCheck, pgno, &nMinKey, i==0?NULL:&nMaxKey);
       if( i>0 && d2!=depth ){
-        checkAppendMsg(pCheck, zContext, "Child page depth differs");
+        checkAppendMsg(pCheck, "Child page depth differs");
       }
       depth = d2;
     }
@@ -59582,37 +61756,39 @@ static int checkTreePage(
 
   if( !pPage->leaf ){
     pgno = get4byte(&pPage->aData[pPage->hdrOffset+8]);
-    sqlite3_snprintf(sizeof(zContext), zContext, 
-                     "On page %d at right child: ", iPage);
+    pCheck->zPfx = "On page %d at right child: ";
+    pCheck->v1 = iPage;
 #ifndef SQLITE_OMIT_AUTOVACUUM
     if( pBt->autoVacuum ){
-      checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage, zContext);
+      checkPtrmap(pCheck, pgno, PTRMAP_BTREE, iPage);
     }
 #endif
-    checkTreePage(pCheck, pgno, zContext, NULL, !pPage->nCell ? NULL : &nMaxKey);
+    checkTreePage(pCheck, pgno, NULL, !pPage->nCell?NULL:&nMaxKey);
   }
  
   /* For intKey leaf pages, check that the min/max keys are in order
   ** with any left/parent/right pages.
   */
+  pCheck->zPfx = "Page %d: ";
+  pCheck->v1 = iPage;
   if( pPage->leaf && pPage->intKey ){
     /* if we are a left child page */
     if( pnParentMinKey ){
       /* if we are the left most child page */
       if( !pnParentMaxKey ){
         if( nMaxKey > *pnParentMinKey ){
-          checkAppendMsg(pCheck, zContext, 
+          checkAppendMsg(pCheck,
               "Rowid %lld out of order (max larger than parent min of %lld)",
               nMaxKey, *pnParentMinKey);
         }
       }else{
         if( nMinKey <= *pnParentMinKey ){
-          checkAppendMsg(pCheck, zContext, 
+          checkAppendMsg(pCheck,
               "Rowid %lld out of order (min less than parent min of %lld)",
               nMinKey, *pnParentMinKey);
         }
         if( nMaxKey > *pnParentMaxKey ){
-          checkAppendMsg(pCheck, zContext, 
+          checkAppendMsg(pCheck,
               "Rowid %lld out of order (max larger than parent max of %lld)",
               nMaxKey, *pnParentMaxKey);
         }
@@ -59621,7 +61797,7 @@ static int checkTreePage(
     /* else if we're a right child page */
     } else if( pnParentMaxKey ){
       if( nMinKey <= *pnParentMaxKey ){
-        checkAppendMsg(pCheck, zContext, 
+        checkAppendMsg(pCheck,
             "Rowid %lld out of order (min less than parent max of %lld)",
             nMinKey, *pnParentMaxKey);
       }
@@ -59632,59 +61808,91 @@ static int checkTreePage(
   */
   data = pPage->aData;
   hdr = pPage->hdrOffset;
-  hit = sqlite3PageMalloc( pBt->pageSize );
-  if( hit==0 ){
+  heap = (u32*)sqlite3PageMalloc( pBt->pageSize );
+  pCheck->zPfx = 0;
+  if( heap==0 ){
     pCheck->mallocFailed = 1;
   }else{
     int contentOffset = get2byteNotZero(&data[hdr+5]);
     assert( contentOffset<=usableSize );  /* Enforced by btreeInitPage() */
-    memset(hit+contentOffset, 0, usableSize-contentOffset);
-    memset(hit, 1, contentOffset);
+    heap[0] = 0;
+    btreeHeapInsert(heap, contentOffset-1);
+    /* EVIDENCE-OF: R-37002-32774 The two-byte integer at offset 3 gives the
+    ** number of cells on the page. */
     nCell = get2byte(&data[hdr+3]);
+    /* EVIDENCE-OF: R-23882-45353 The cell pointer array of a b-tree page
+    ** immediately follows the b-tree page header. */
     cellStart = hdr + 12 - 4*pPage->leaf;
+    /* EVIDENCE-OF: R-02776-14802 The cell pointer array consists of K 2-byte
+    ** integer offsets to the cell contents. */
     for(i=0; i<nCell; i++){
       int pc = get2byte(&data[cellStart+i*2]);
       u32 size = 65536;
-      int j;
       if( pc<=usableSize-4 ){
         size = cellSizePtr(pPage, &data[pc]);
       }
       if( (int)(pc+size-1)>=usableSize ){
-        checkAppendMsg(pCheck, 0, 
+        pCheck->zPfx = 0;
+        checkAppendMsg(pCheck,
             "Corruption detected in cell %d on page %d",i,iPage);
       }else{
-        for(j=pc+size-1; j>=pc; j--) hit[j]++;
+        btreeHeapInsert(heap, (pc<<16)|(pc+size-1));
       }
     }
+    /* EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header
+    ** is the offset of the first freeblock, or zero if there are no
+    ** freeblocks on the page. */
     i = get2byte(&data[hdr+1]);
     while( i>0 ){
       int size, j;
       assert( i<=usableSize-4 );     /* Enforced by btreeInitPage() */
       size = get2byte(&data[i+2]);
       assert( i+size<=usableSize );  /* Enforced by btreeInitPage() */
-      for(j=i+size-1; j>=i; j--) hit[j]++;
+      btreeHeapInsert(heap, (i<<16)|(i+size-1));
+      /* EVIDENCE-OF: R-58208-19414 The first 2 bytes of a freeblock are a
+      ** big-endian integer which is the offset in the b-tree page of the next
+      ** freeblock in the chain, or zero if the freeblock is the last on the
+      ** chain. */
       j = get2byte(&data[i]);
+      /* EVIDENCE-OF: R-06866-39125 Freeblocks are always connected in order of
+      ** increasing offset. */
       assert( j==0 || j>i+size );  /* Enforced by btreeInitPage() */
       assert( j<=usableSize-4 );   /* Enforced by btreeInitPage() */
       i = j;
     }
-    for(i=cnt=0; i<usableSize; i++){
-      if( hit[i]==0 ){
-        cnt++;
-      }else if( hit[i]>1 ){
-        checkAppendMsg(pCheck, 0,
-          "Multiple uses for byte %d of page %d", i, iPage);
+    cnt = 0;
+    assert( heap[0]>0 );
+    assert( (heap[1]>>16)==0 );
+    btreeHeapPull(heap,&prev);
+    while( btreeHeapPull(heap,&x) ){
+      if( (prev&0xffff)+1>(x>>16) ){
+        checkAppendMsg(pCheck,
+          "Multiple uses for byte %u of page %d", x>>16, iPage);
         break;
+      }else{
+        cnt += (x>>16) - (prev&0xffff) - 1;
+        prev = x;
       }
     }
-    if( cnt!=data[hdr+7] ){
-      checkAppendMsg(pCheck, 0, 
+    cnt += usableSize - (prev&0xffff) - 1;
+    /* EVIDENCE-OF: R-43263-13491 The total number of bytes in all fragments
+    ** is stored in the fifth field of the b-tree page header.
+    ** EVIDENCE-OF: R-07161-27322 The one-byte integer at offset 7 gives the
+    ** number of fragmented free bytes within the cell content area.
+    */
+    if( heap[0]==0 && cnt!=data[hdr+7] ){
+      checkAppendMsg(pCheck,
           "Fragmentation of %d bytes reported as %d on page %d",
           cnt, data[hdr+7], iPage);
     }
   }
-  sqlite3PageFree(hit);
+  sqlite3PageFree(heap);
   releasePage(pPage);
+
+end_of_check:
+  pCheck->zPfx = saved_zPfx;
+  pCheck->v1 = saved_v1;
+  pCheck->v2 = saved_v2;
   return depth+1;
 }
 #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
@@ -59725,6 +61933,9 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
   sCheck.mxErr = mxErr;
   sCheck.nErr = 0;
   sCheck.mallocFailed = 0;
+  sCheck.zPfx = 0;
+  sCheck.v1 = 0;
+  sCheck.v2 = 0;
   *pnErr = 0;
   if( sCheck.nPage==0 ){
     sqlite3BtreeLeave(p);
@@ -59739,13 +61950,14 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
   }
   i = PENDING_BYTE_PAGE(pBt);
   if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i);
-  sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
-  sCheck.errMsg.useMalloc = 2;
+  sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
 
   /* Check the integrity of the freelist
   */
+  sCheck.zPfx = "Main freelist: ";
   checkList(&sCheck, 1, get4byte(&pBt->pPage1->aData[32]),
-            get4byte(&pBt->pPage1->aData[36]), "Main freelist: ");
+            get4byte(&pBt->pPage1->aData[36]));
+  sCheck.zPfx = 0;
 
   /* Check all the tables.
   */
@@ -59753,10 +61965,12 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
     if( aRoot[i]==0 ) continue;
 #ifndef SQLITE_OMIT_AUTOVACUUM
     if( pBt->autoVacuum && aRoot[i]>1 ){
-      checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0, 0);
+      checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0);
     }
 #endif
-    checkTreePage(&sCheck, aRoot[i], "List of tree roots: ", NULL, NULL);
+    sCheck.zPfx = "List of tree roots: ";
+    checkTreePage(&sCheck, aRoot[i], NULL, NULL);
+    sCheck.zPfx = 0;
   }
 
   /* Make sure every page in the file is referenced
@@ -59764,7 +61978,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
   for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){
 #ifdef SQLITE_OMIT_AUTOVACUUM
     if( getPageReferenced(&sCheck, i)==0 ){
-      checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
+      checkAppendMsg(&sCheck, "Page %d is never used", i);
     }
 #else
     /* If the database supports auto-vacuum, make sure no tables contain
@@ -59772,11 +61986,11 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
     */
     if( getPageReferenced(&sCheck, i)==0 && 
        (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){
-      checkAppendMsg(&sCheck, 0, "Page %d is never used", i);
+      checkAppendMsg(&sCheck, "Page %d is never used", i);
     }
     if( getPageReferenced(&sCheck, i)!=0 && 
        (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){
-      checkAppendMsg(&sCheck, 0, "Pointer map page %d is referenced", i);
+      checkAppendMsg(&sCheck, "Pointer map page %d is referenced", i);
     }
 #endif
   }
@@ -59786,7 +62000,7 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(
   ** of the integrity check.
   */
   if( NEVER(nRef != sqlite3PagerRefcount(pBt->pPager)) ){
-    checkAppendMsg(&sCheck, 0, 
+    checkAppendMsg(&sCheck,
       "Outstanding page count goes from %d to %d during this analysis",
       nRef, sqlite3PagerRefcount(pBt->pPager)
     );
@@ -59982,7 +62196,7 @@ SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void
   ** required in case any of them are holding references to an xFetch
   ** version of the b-tree page modified by the accessPayload call below.
   **
-  ** Note that pCsr must be open on a BTREE_INTKEY table and saveCursorPosition()
+  ** Note that pCsr must be open on a INTKEY table and saveCursorPosition()
   ** and hence saveAllCursors() cannot fail on a BTREE_INTKEY table, hence
   ** saveAllCursors can only return SQLITE_OK.
   */
@@ -60053,14 +62267,23 @@ SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){
 }
 
 /*
-** set the mask of hint flags for cursor pCsr. Currently the only valid
-** values are 0 and BTREE_BULKLOAD.
+** set the mask of hint flags for cursor pCsr.
 */
 SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){
-  assert( mask==BTREE_BULKLOAD || mask==0 );
+  assert( mask==BTREE_BULKLOAD || mask==BTREE_SEEK_EQ || mask==0 );
   pCsr->hints = mask;
 }
 
+#ifdef SQLITE_DEBUG
+/*
+** Return true if the cursor has a hint specified.  This routine is
+** only used from within assert() statements
+*/
+SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor *pCsr, unsigned int mask){
+  return (pCsr->hints & mask)!=0;
+}
+#endif
+
 /*
 ** Return true if the given Btree is read-only.
 */
@@ -60068,6 +62291,11 @@ SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *p){
   return (p->pBt->btsFlags & BTS_READ_ONLY)!=0;
 }
 
+/*
+** Return the size of the header added to each page by this module.
+*/
+SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); }
+
 /************** End of btree.c ***********************************************/
 /************** Begin file backup.c ******************************************/
 /*
@@ -60157,12 +62385,12 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
     int rc = 0;
     pParse = sqlite3StackAllocZero(pErrorDb, sizeof(*pParse));
     if( pParse==0 ){
-      sqlite3Error(pErrorDb, SQLITE_NOMEM, "out of memory");
+      sqlite3ErrorWithMsg(pErrorDb, SQLITE_NOMEM, "out of memory");
       rc = SQLITE_NOMEM;
     }else{
       pParse->db = pDb;
       if( sqlite3OpenTempDatabase(pParse) ){
-        sqlite3Error(pErrorDb, pParse->rc, "%s", pParse->zErrMsg);
+        sqlite3ErrorWithMsg(pErrorDb, pParse->rc, "%s", pParse->zErrMsg);
         rc = SQLITE_ERROR;
       }
       sqlite3DbFree(pErrorDb, pParse->zErrMsg);
@@ -60175,7 +62403,7 @@ static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){
   }
 
   if( i<0 ){
-    sqlite3Error(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb);
+    sqlite3ErrorWithMsg(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb);
     return 0;
   }
 
@@ -60193,6 +62421,20 @@ static int setDestPgsz(sqlite3_backup *p){
 }
 
 /*
+** Check that there is no open read-transaction on the b-tree passed as the
+** second argument. If there is not, return SQLITE_OK. Otherwise, if there
+** is an open read-transaction, return SQLITE_ERROR and leave an error 
+** message in database handle db.
+*/
+static int checkReadTransaction(sqlite3 *db, Btree *p){
+  if( sqlite3BtreeIsInReadTrans(p) ){
+    sqlite3ErrorWithMsg(db, SQLITE_ERROR, "destination database is in use");
+    return SQLITE_ERROR;
+  }
+  return SQLITE_OK;
+}
+
+/*
 ** Create an sqlite3_backup process to copy the contents of zSrcDb from
 ** connection handle pSrcDb to zDestDb in pDestDb. If successful, return
 ** a pointer to the new sqlite3_backup object.
@@ -60200,7 +62442,7 @@ static int setDestPgsz(sqlite3_backup *p){
 ** If an error occurs, NULL is returned and an error code and error message
 ** stored in database handle pDestDb.
 */
-SQLITE_API sqlite3_backup *sqlite3_backup_init(
+SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init(
   sqlite3* pDestDb,                     /* Database to write to */
   const char *zDestDb,                  /* Name of database within pDestDb */
   sqlite3* pSrcDb,                      /* Database connection to read from */
@@ -60208,6 +62450,13 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init(
 ){
   sqlite3_backup *p;                    /* Value to return */
 
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !sqlite3SafetyCheckOk(pSrcDb)||!sqlite3SafetyCheckOk(pDestDb) ){
+    (void)SQLITE_MISUSE_BKPT;
+    return 0;
+  }
+#endif
+
   /* Lock the source database handle. The destination database
   ** handle is not locked in this routine, but it is locked in
   ** sqlite3_backup_step(). The user is required to ensure that no
@@ -60220,7 +62469,7 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init(
   sqlite3_mutex_enter(pDestDb->mutex);
 
   if( pSrcDb==pDestDb ){
-    sqlite3Error(
+    sqlite3ErrorWithMsg(
         pDestDb, SQLITE_ERROR, "source and destination must be distinct"
     );
     p = 0;
@@ -60231,7 +62480,7 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init(
     ** sqlite3_backup_finish(). */
     p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup));
     if( !p ){
-      sqlite3Error(pDestDb, SQLITE_NOMEM, 0);
+      sqlite3Error(pDestDb, SQLITE_NOMEM);
     }
   }
 
@@ -60244,12 +62493,15 @@ SQLITE_API sqlite3_backup *sqlite3_backup_init(
     p->iNext = 1;
     p->isAttached = 0;
 
-    if( 0==p->pSrc || 0==p->pDest || setDestPgsz(p)==SQLITE_NOMEM ){
+    if( 0==p->pSrc || 0==p->pDest 
+     || setDestPgsz(p)==SQLITE_NOMEM 
+     || checkReadTransaction(pDestDb, p->pDest)!=SQLITE_OK 
+     ){
       /* One (or both) of the named databases did not exist or an OOM
-      ** error was hit.  The error has already been written into the
-      ** pDestDb handle.  All that is left to do here is free the
-      ** sqlite3_backup structure.
-      */
+      ** error was hit. Or there is a transaction open on the destination
+      ** database. The error has already been written into the pDestDb 
+      ** handle. All that is left to do here is free the sqlite3_backup 
+      ** structure.  */
       sqlite3_free(p);
       p = 0;
     }
@@ -60293,7 +62545,7 @@ static int backupOnePage(
   ** guaranteed that the shared-mutex is held by this thread, handle
   ** p->pSrc may not actually be the owner.  */
   int nSrcReserve = sqlite3BtreeGetReserveNoMutex(p->pSrc);
-  int nDestReserve = sqlite3BtreeGetReserve(p->pDest);
+  int nDestReserve = sqlite3BtreeGetOptimalReserve(p->pDest);
 #endif
   int rc = SQLITE_OK;
   i64 iOff;
@@ -60398,12 +62650,15 @@ static void attachBackupObject(sqlite3_backup *p){
 /*
 ** Copy nPage pages from the source b-tree to the destination.
 */
-SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
+SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage){
   int rc;
   int destMode;       /* Destination journal mode */
   int pgszSrc = 0;    /* Source page size */
   int pgszDest = 0;   /* Destination page size */
 
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( p==0 ) return SQLITE_MISUSE_BKPT;
+#endif
   sqlite3_mutex_enter(p->pSrcDb->mutex);
   sqlite3BtreeEnter(p->pSrc);
   if( p->pDestDb ){
@@ -60640,7 +62895,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){
 /*
 ** Release all resources associated with an sqlite3_backup* handle.
 */
-SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
+SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p){
   sqlite3_backup **pp;                 /* Ptr to head of pagers backup list */
   sqlite3 *pSrcDb;                     /* Source database connection */
   int rc;                              /* Value to return */
@@ -60667,12 +62922,12 @@ SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
   }
 
   /* If a transaction is still open on the Btree, roll it back. */
-  sqlite3BtreeRollback(p->pDest, SQLITE_OK);
+  sqlite3BtreeRollback(p->pDest, SQLITE_OK, 0);
 
   /* Set the error code of the destination database handle. */
   rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc;
   if( p->pDestDb ){
-    sqlite3Error(p->pDestDb, rc, 0);
+    sqlite3Error(p->pDestDb, rc);
 
     /* Exit the mutexes and free the backup context structure. */
     sqlite3LeaveMutexAndCloseZombie(p->pDestDb);
@@ -60692,7 +62947,13 @@ SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
 ** Return the number of pages still to be backed up as of the most recent
 ** call to sqlite3_backup_step().
 */
-SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p){
+SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p){
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( p==0 ){
+    (void)SQLITE_MISUSE_BKPT;
+    return 0;
+  }
+#endif
   return p->nRemaining;
 }
 
@@ -60700,7 +62961,13 @@ SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p){
 ** Return the total number of pages in the source database as of the most 
 ** recent call to sqlite3_backup_step().
 */
-SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p){
+SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p){
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( p==0 ){
+    (void)SQLITE_MISUSE_BKPT;
+    return 0;
+  }
+#endif
   return p->nPagecount;
 }
 
@@ -60845,29 +63112,40 @@ copy_finished:
 ** this:    assert( sqlite3VdbeCheckMemInvariants(pMem) );
 */
 SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){
-  /* The MEM_Dyn bit is set if and only if Mem.xDel is a non-NULL destructor
-  ** function for Mem.z 
+  /* If MEM_Dyn is set then Mem.xDel!=0.  
+  ** Mem.xDel is might not be initialized if MEM_Dyn is clear.
   */
   assert( (p->flags & MEM_Dyn)==0 || p->xDel!=0 );
-  assert( (p->flags & MEM_Dyn)!=0 || p->xDel==0 );
+
+  /* MEM_Dyn may only be set if Mem.szMalloc==0.  In this way we
+  ** ensure that if Mem.szMalloc>0 then it is safe to do
+  ** Mem.z = Mem.zMalloc without having to check Mem.flags&MEM_Dyn.
+  ** That saves a few cycles in inner loops. */
+  assert( (p->flags & MEM_Dyn)==0 || p->szMalloc==0 );
+
+  /* Cannot be both MEM_Int and MEM_Real at the same time */
+  assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
+
+  /* The szMalloc field holds the correct memory allocation size */
+  assert( p->szMalloc==0
+       || p->szMalloc==sqlite3DbMallocSize(p->db,p->zMalloc) );
 
   /* If p holds a string or blob, the Mem.z must point to exactly
   ** one of the following:
   **
   **   (1) Memory in Mem.zMalloc and managed by the Mem object
   **   (2) Memory to be freed using Mem.xDel
-  **   (3) An ephermal string or blob
+  **   (3) An ephemeral string or blob
   **   (4) A static string or blob
   */
-  if( (p->flags & (MEM_Str|MEM_Blob)) && p->z!=0 ){
+  if( (p->flags & (MEM_Str|MEM_Blob)) && p->n>0 ){
     assert( 
-      ((p->z==p->zMalloc)? 1 : 0) +
+      ((p->szMalloc>0 && p->z==p->zMalloc)? 1 : 0) +
       ((p->flags&MEM_Dyn)!=0 ? 1 : 0) +
       ((p->flags&MEM_Ephem)!=0 ? 1 : 0) +
       ((p->flags&MEM_Static)!=0 ? 1 : 0) == 1
     );
   }
-
   return 1;
 }
 #endif
@@ -60921,7 +63199,7 @@ SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
 ** blob if bPreserve is true.  If bPreserve is false, any prior content
 ** in pMem->z is discarded.
 */
-SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
+SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
   assert( sqlite3VdbeCheckMemInvariants(pMem) );
   assert( (pMem->flags&MEM_RowSet)==0 );
 
@@ -60930,24 +63208,28 @@ SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
   assert( bPreserve==0 || pMem->flags&(MEM_Blob|MEM_Str) );
   testcase( bPreserve && pMem->z==0 );
 
-  if( pMem->zMalloc==0 || sqlite3DbMallocSize(pMem->db, pMem->zMalloc)<n ){
+  assert( pMem->szMalloc==0
+       || pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) );
+  if( pMem->szMalloc<n ){
     if( n<32 ) n = 32;
-    if( bPreserve && pMem->z==pMem->zMalloc ){
+    if( bPreserve && pMem->szMalloc>0 && pMem->z==pMem->zMalloc ){
       pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
       bPreserve = 0;
     }else{
-      sqlite3DbFree(pMem->db, pMem->zMalloc);
+      if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc);
       pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n);
     }
     if( pMem->zMalloc==0 ){
-      VdbeMemRelease(pMem);
+      sqlite3VdbeMemSetNull(pMem);
       pMem->z = 0;
-      pMem->flags = MEM_Null;  
+      pMem->szMalloc = 0;
       return SQLITE_NOMEM;
+    }else{
+      pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
     }
   }
 
-  if( pMem->z && bPreserve && pMem->z!=pMem->zMalloc ){
+  if( bPreserve && pMem->z && pMem->z!=pMem->zMalloc ){
     memcpy(pMem->zMalloc, pMem->z, pMem->n);
   }
   if( (pMem->flags&MEM_Dyn)!=0 ){
@@ -60957,15 +63239,37 @@ SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){
 
   pMem->z = pMem->zMalloc;
   pMem->flags &= ~(MEM_Dyn|MEM_Ephem|MEM_Static);
-  pMem->xDel = 0;
   return SQLITE_OK;
 }
 
 /*
-** Make the given Mem object MEM_Dyn.  In other words, make it so
-** that any TEXT or BLOB content is stored in memory obtained from
-** malloc().  In this way, we know that the memory is safe to be
-** overwritten or altered.
+** Change the pMem->zMalloc allocation to be at least szNew bytes.
+** If pMem->zMalloc already meets or exceeds the requested size, this
+** routine is a no-op.
+**
+** Any prior string or blob content in the pMem object may be discarded.
+** The pMem->xDel destructor is called, if it exists.  Though MEM_Str
+** and MEM_Blob values may be discarded, MEM_Int, MEM_Real, and MEM_Null
+** values are preserved.
+**
+** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM)
+** if unable to complete the resizing.
+*/
+SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
+  assert( szNew>0 );
+  assert( (pMem->flags & MEM_Dyn)==0 || pMem->szMalloc==0 );
+  if( pMem->szMalloc<szNew ){
+    return sqlite3VdbeMemGrow(pMem, szNew, 0);
+  }
+  assert( (pMem->flags & MEM_Dyn)==0 );
+  pMem->z = pMem->zMalloc;
+  pMem->flags &= (MEM_Null|MEM_Int|MEM_Real);
+  return SQLITE_OK;
+}
+
+/*
+** Change pMem so that its MEM_Str or MEM_Blob value is stored in
+** MEM.zMalloc, where it can be safely written.
 **
 ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
 */
@@ -60975,17 +63279,18 @@ SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
   assert( (pMem->flags&MEM_RowSet)==0 );
   ExpandBlob(pMem);
   f = pMem->flags;
-  if( (f&(MEM_Str|MEM_Blob)) && pMem->z!=pMem->zMalloc ){
+  if( (f&(MEM_Str|MEM_Blob)) && (pMem->szMalloc==0 || pMem->z!=pMem->zMalloc) ){
     if( sqlite3VdbeMemGrow(pMem, pMem->n + 2, 1) ){
       return SQLITE_NOMEM;
     }
     pMem->z[pMem->n] = 0;
     pMem->z[pMem->n+1] = 0;
     pMem->flags |= MEM_Term;
+  }
+  pMem->flags &= ~MEM_Ephem;
 #ifdef SQLITE_DEBUG
-    pMem->pScopyFrom = 0;
+  pMem->pScopyFrom = 0;
 #endif
-  }
 
   return SQLITE_OK;
 }
@@ -61019,15 +63324,11 @@ SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){
 }
 #endif
 
-
 /*
-** Make sure the given Mem is \u0000 terminated.
+** It is already known that pMem contains an unterminated string.
+** Add the zero terminator.
 */
-SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){
-  assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
-  if( (pMem->flags & MEM_Term)!=0 || (pMem->flags & MEM_Str)==0 ){
-    return SQLITE_OK;   /* Nothing to do */
-  }
+static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){
   if( sqlite3VdbeMemGrow(pMem, pMem->n+2, 1) ){
     return SQLITE_NOMEM;
   }
@@ -61038,20 +63339,34 @@ SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){
 }
 
 /*
+** Make sure the given Mem is \u0000 terminated.
+*/
+SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){
+  assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
+  testcase( (pMem->flags & (MEM_Term|MEM_Str))==(MEM_Term|MEM_Str) );
+  testcase( (pMem->flags & (MEM_Term|MEM_Str))==0 );
+  if( (pMem->flags & (MEM_Term|MEM_Str))!=MEM_Str ){
+    return SQLITE_OK;   /* Nothing to do */
+  }else{
+    return vdbeMemAddTerminator(pMem);
+  }
+}
+
+/*
 ** Add MEM_Str to the set of representations for the given Mem.  Numbers
 ** are converted using sqlite3_snprintf().  Converting a BLOB to a string
 ** is a no-op.
 **
-** Existing representations MEM_Int and MEM_Real are *not* invalidated.
+** Existing representations MEM_Int and MEM_Real are invalidated if
+** bForce is true but are retained if bForce is false.
 **
 ** A MEM_Null value will never be passed to this function. This function is
 ** used for converting values to text for returning to the user (i.e. via
 ** sqlite3_value_text()), or for ensuring that values to be used as btree
 ** keys are strings. In the former case a NULL pointer is returned the
-** user and the later is an internal programming error.
+** user and the latter is an internal programming error.
 */
-SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, int enc){
-  int rc = SQLITE_OK;
+SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
   int fg = pMem->flags;
   const int nByte = 32;
 
@@ -61063,11 +63378,11 @@ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, int enc){
   assert( EIGHT_BYTE_ALIGNMENT(pMem) );
 
 
-  if( sqlite3VdbeMemGrow(pMem, nByte, 0) ){
+  if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){
     return SQLITE_NOMEM;
   }
 
-  /* For a Real or Integer, use sqlite3_mprintf() to produce the UTF-8
+  /* For a Real or Integer, use sqlite3_snprintf() to produce the UTF-8
   ** string representation of the value. Then, if the required encoding
   ** is UTF-16le or UTF-16be do a translation.
   ** 
@@ -61077,13 +63392,14 @@ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, int enc){
     sqlite3_snprintf(nByte, pMem->z, "%lld", pMem->u.i);
   }else{
     assert( fg & MEM_Real );
-    sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->r);
+    sqlite3_snprintf(nByte, pMem->z, "%!.15g", pMem->u.r);
   }
   pMem->n = sqlite3Strlen30(pMem->z);
   pMem->enc = SQLITE_UTF8;
   pMem->flags |= MEM_Str|MEM_Term;
+  if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real);
   sqlite3VdbeChangeEncoding(pMem, enc);
-  return rc;
+  return SQLITE_OK;
 }
 
 /*
@@ -61098,59 +63414,90 @@ SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
   int rc = SQLITE_OK;
   if( ALWAYS(pFunc && pFunc->xFinalize) ){
     sqlite3_context ctx;
+    Mem t;
     assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
     assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
     memset(&ctx, 0, sizeof(ctx));
-    ctx.s.flags = MEM_Null;
-    ctx.s.db = pMem->db;
+    memset(&t, 0, sizeof(t));
+    t.flags = MEM_Null;
+    t.db = pMem->db;
+    ctx.pOut = &t;
     ctx.pMem = pMem;
     ctx.pFunc = pFunc;
     pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */
-    assert( 0==(pMem->flags&MEM_Dyn) && !pMem->xDel );
-    sqlite3DbFree(pMem->db, pMem->zMalloc);
-    memcpy(pMem, &ctx.s, sizeof(ctx.s));
+    assert( (pMem->flags & MEM_Dyn)==0 );
+    if( pMem->szMalloc>0 ) sqlite3DbFree(pMem->db, pMem->zMalloc);
+    memcpy(pMem, &t, sizeof(t));
     rc = ctx.isError;
   }
   return rc;
 }
 
 /*
-** If the memory cell contains a string value that must be freed by
-** invoking an external callback, free it now. Calling this function
-** does not free any Mem.zMalloc buffer.
+** If the memory cell contains a value that must be freed by
+** invoking the external callback in Mem.xDel, then this routine
+** will free that value.  It also sets Mem.flags to MEM_Null.
+**
+** This is a helper routine for sqlite3VdbeMemSetNull() and
+** for sqlite3VdbeMemRelease().  Use those other routines as the
+** entry point for releasing Mem resources.
 */
-SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p){
+static SQLITE_NOINLINE void vdbeMemClearExternAndSetNull(Mem *p){
   assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) );
+  assert( VdbeMemDynamic(p) );
   if( p->flags&MEM_Agg ){
     sqlite3VdbeMemFinalize(p, p->u.pDef);
     assert( (p->flags & MEM_Agg)==0 );
-    sqlite3VdbeMemRelease(p);
-  }else if( p->flags&MEM_Dyn ){
+    testcase( p->flags & MEM_Dyn );
+  }
+  if( p->flags&MEM_Dyn ){
     assert( (p->flags&MEM_RowSet)==0 );
     assert( p->xDel!=SQLITE_DYNAMIC && p->xDel!=0 );
     p->xDel((void *)p->z);
-    p->xDel = 0;
   }else if( p->flags&MEM_RowSet ){
     sqlite3RowSetClear(p->u.pRowSet);
   }else if( p->flags&MEM_Frame ){
-    sqlite3VdbeMemSetNull(p);
+    VdbeFrame *pFrame = p->u.pFrame;
+    pFrame->pParent = pFrame->v->pDelFrame;
+    pFrame->v->pDelFrame = pFrame;
   }
+  p->flags = MEM_Null;
 }
 
 /*
-** Release any memory held by the Mem. This may leave the Mem in an
-** inconsistent state, for example with (Mem.z==0) and
-** (Mem.flags==MEM_Str).
+** Release memory held by the Mem p, both external memory cleared
+** by p->xDel and memory in p->zMalloc.
+**
+** This is a helper routine invoked by sqlite3VdbeMemRelease() in
+** the unusual case where there really is memory in p that needs
+** to be freed.
 */
-SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){
-  assert( sqlite3VdbeCheckMemInvariants(p) );
-  VdbeMemRelease(p);
-  if( p->zMalloc ){
+static SQLITE_NOINLINE void vdbeMemClear(Mem *p){
+  if( VdbeMemDynamic(p) ){
+    vdbeMemClearExternAndSetNull(p);
+  }
+  if( p->szMalloc ){
     sqlite3DbFree(p->db, p->zMalloc);
-    p->zMalloc = 0;
+    p->szMalloc = 0;
   }
   p->z = 0;
-  assert( p->xDel==0 );  /* Zeroed by VdbeMemRelease() above */
+}
+
+/*
+** Release any memory resources held by the Mem.  Both the memory that is
+** free by Mem.xDel and the Mem.zMalloc allocation are freed.
+**
+** Use this routine prior to clean up prior to abandoning a Mem, or to
+** reset a Mem back to its minimum memory utilization.
+**
+** Use sqlite3VdbeMemSetNull() to release just the Mem.xDel space
+** prior to inserting new content into the Mem.
+*/
+SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){
+  assert( sqlite3VdbeCheckMemInvariants(p) );
+  if( VdbeMemDynamic(p) || p->szMalloc ){
+    vdbeMemClear(p);
+  }
 }
 
 /*
@@ -61189,7 +63536,7 @@ static i64 doubleToInt64(double r){
 ** If pMem is an integer, then the value is exact.  If pMem is
 ** a floating-point then the value returned is the integer part.
 ** If pMem is a string or blob, then we make an attempt to convert
-** it into a integer and return that.  If pMem represents an
+** it into an integer and return that.  If pMem represents an
 ** an SQL-NULL value, return 0.
 **
 ** If pMem represents a string value, its encoding might be changed.
@@ -61202,11 +63549,10 @@ SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){
   if( flags & MEM_Int ){
     return pMem->u.i;
   }else if( flags & MEM_Real ){
-    return doubleToInt64(pMem->r);
+    return doubleToInt64(pMem->u.r);
   }else if( flags & (MEM_Str|MEM_Blob) ){
     i64 value = 0;
     assert( pMem->z || pMem->n==0 );
-    testcase( pMem->z==0 );
     sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
     return value;
   }else{
@@ -61224,7 +63570,7 @@ SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   assert( EIGHT_BYTE_ALIGNMENT(pMem) );
   if( pMem->flags & MEM_Real ){
-    return pMem->r;
+    return pMem->u.r;
   }else if( pMem->flags & MEM_Int ){
     return (double)pMem->u.i;
   }else if( pMem->flags & (MEM_Str|MEM_Blob) ){
@@ -61243,12 +63589,13 @@ SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
 ** MEM_Int if we can.
 */
 SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){
+  i64 ix;
   assert( pMem->flags & MEM_Real );
   assert( (pMem->flags & MEM_RowSet)==0 );
   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   assert( EIGHT_BYTE_ALIGNMENT(pMem) );
 
-  pMem->u.i = doubleToInt64(pMem->r);
+  ix = doubleToInt64(pMem->u.r);
 
   /* Only mark the value as an integer if
   **
@@ -61260,11 +63607,9 @@ SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){
   ** the second condition under the assumption that addition overflow causes
   ** values to wrap around.
   */
-  if( pMem->r==(double)pMem->u.i
-   && pMem->u.i>SMALLEST_INT64
-   && pMem->u.i<LARGEST_INT64
-  ){
-    pMem->flags |= MEM_Int;
+  if( pMem->u.r==ix && ix>SMALLEST_INT64 && ix<LARGEST_INT64 ){
+    pMem->u.i = ix;
+    MemSetTypeFlag(pMem, MEM_Int);
   }
 }
 
@@ -61289,7 +63634,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem *pMem){
   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   assert( EIGHT_BYTE_ALIGNMENT(pMem) );
 
-  pMem->r = sqlite3VdbeRealValue(pMem);
+  pMem->u.r = sqlite3VdbeRealValue(pMem);
   MemSetTypeFlag(pMem, MEM_Real);
   return SQLITE_OK;
 }
@@ -61309,7 +63654,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
     if( 0==sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc) ){
       MemSetTypeFlag(pMem, MEM_Int);
     }else{
-      pMem->r = sqlite3VdbeRealValue(pMem);
+      pMem->u.r = sqlite3VdbeRealValue(pMem);
       MemSetTypeFlag(pMem, MEM_Real);
       sqlite3VdbeIntegerAffinity(pMem);
     }
@@ -61320,18 +63665,80 @@ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
 }
 
 /*
+** Cast the datatype of the value in pMem according to the affinity
+** "aff".  Casting is different from applying affinity in that a cast
+** is forced.  In other words, the value is converted into the desired
+** affinity even if that results in loss of data.  This routine is
+** used (for example) to implement the SQL "cast()" operator.
+*/
+SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
+  if( pMem->flags & MEM_Null ) return;
+  switch( aff ){
+    case SQLITE_AFF_NONE: {   /* Really a cast to BLOB */
+      if( (pMem->flags & MEM_Blob)==0 ){
+        sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
+        assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
+        MemSetTypeFlag(pMem, MEM_Blob);
+      }else{
+        pMem->flags &= ~(MEM_TypeMask&~MEM_Blob);
+      }
+      break;
+    }
+    case SQLITE_AFF_NUMERIC: {
+      sqlite3VdbeMemNumerify(pMem);
+      break;
+    }
+    case SQLITE_AFF_INTEGER: {
+      sqlite3VdbeMemIntegerify(pMem);
+      break;
+    }
+    case SQLITE_AFF_REAL: {
+      sqlite3VdbeMemRealify(pMem);
+      break;
+    }
+    default: {
+      assert( aff==SQLITE_AFF_TEXT );
+      assert( MEM_Str==(MEM_Blob>>3) );
+      pMem->flags |= (pMem->flags&MEM_Blob)>>3;
+      sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding);
+      assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
+      pMem->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero);
+      break;
+    }
+  }
+}
+
+/*
+** Initialize bulk memory to be a consistent Mem object.
+**
+** The minimum amount of initialization feasible is performed.
+*/
+SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem *pMem, sqlite3 *db, u16 flags){
+  assert( (flags & ~MEM_TypeMask)==0 );
+  pMem->flags = flags;
+  pMem->db = db;
+  pMem->szMalloc = 0;
+}
+
+
+/*
 ** Delete any previous value and set the value stored in *pMem to NULL.
+**
+** This routine calls the Mem.xDel destructor to dispose of values that
+** require the destructor.  But it preserves the Mem.zMalloc memory allocation.
+** To free all resources, use sqlite3VdbeMemRelease(), which both calls this
+** routine to invoke the destructor and deallocates Mem.zMalloc.
+**
+** Use this routine to reset the Mem prior to insert a new value.
+**
+** Use sqlite3VdbeMemRelease() to complete erase the Mem prior to abandoning it.
 */
 SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem *pMem){
-  if( pMem->flags & MEM_Frame ){
-    VdbeFrame *pFrame = pMem->u.pFrame;
-    pFrame->pParent = pFrame->v->pDelFrame;
-    pFrame->v->pDelFrame = pFrame;
-  }
-  if( pMem->flags & MEM_RowSet ){
-    sqlite3RowSetClear(pMem->u.pRowSet);
+  if( VdbeMemDynamic(pMem) ){
+    vdbeMemClearExternAndSetNull(pMem);
+  }else{
+    pMem->flags = MEM_Null;
   }
-  MemSetTypeFlag(pMem, MEM_Null);
 }
 SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value *p){
   sqlite3VdbeMemSetNull((Mem*)p); 
@@ -61348,14 +63755,18 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
   if( n<0 ) n = 0;
   pMem->u.nZero = n;
   pMem->enc = SQLITE_UTF8;
+  pMem->z = 0;
+}
 
-#ifdef SQLITE_OMIT_INCRBLOB
-  sqlite3VdbeMemGrow(pMem, n, 0);
-  if( pMem->z ){
-    pMem->n = n;
-    memset(pMem->z, 0, n);
-  }
-#endif
+/*
+** The pMem is known to contain content that needs to be destroyed prior
+** to a value change.  So invoke the destructor, then set the value to
+** a 64-bit integer.
+*/
+static SQLITE_NOINLINE void vdbeReleaseAndSetInt64(Mem *pMem, i64 val){
+  sqlite3VdbeMemSetNull(pMem);
+  pMem->u.i = val;
+  pMem->flags = MEM_Int;
 }
 
 /*
@@ -61363,9 +63774,12 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
 ** manifest type INTEGER.
 */
 SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
-  sqlite3VdbeMemRelease(pMem);
-  pMem->u.i = val;
-  pMem->flags = MEM_Int;
+  if( VdbeMemDynamic(pMem) ){
+    vdbeReleaseAndSetInt64(pMem, val);
+  }else{
+    pMem->u.i = val;
+    pMem->flags = MEM_Int;
+  }
 }
 
 #ifndef SQLITE_OMIT_FLOATING_POINT
@@ -61374,11 +63788,9 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){
 ** manifest type REAL.
 */
 SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem *pMem, double val){
-  if( sqlite3IsNaN(val) ){
-    sqlite3VdbeMemSetNull(pMem);
-  }else{
-    sqlite3VdbeMemRelease(pMem);
-    pMem->r = val;
+  sqlite3VdbeMemSetNull(pMem);
+  if( !sqlite3IsNaN(val) ){
+    pMem->u.r = val;
     pMem->flags = MEM_Real;
   }
 }
@@ -61396,10 +63808,11 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem *pMem){
   pMem->zMalloc = sqlite3DbMallocRaw(db, 64);
   if( db->mallocFailed ){
     pMem->flags = MEM_Null;
+    pMem->szMalloc = 0;
   }else{
     assert( pMem->zMalloc );
-    pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc, 
-                                       sqlite3DbMallocSize(db, pMem->zMalloc));
+    pMem->szMalloc = sqlite3DbMallocSize(db, pMem->zMalloc);
+    pMem->u.pRowSet = sqlite3RowSetInit(db, pMem->zMalloc, pMem->szMalloc);
     assert( pMem->u.pRowSet!=0 );
     pMem->flags = MEM_RowSet;
   }
@@ -61423,7 +63836,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem *p){
 
 #ifdef SQLITE_DEBUG
 /*
-** This routine prepares a memory cell for modication by breaking
+** This routine prepares a memory cell for modification by breaking
 ** its link to a shallow copy and by marking any current shallow
 ** copies of this cell as invalid.
 **
@@ -61456,9 +63869,9 @@ SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){
 */
 SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){
   assert( (pFrom->flags & MEM_RowSet)==0 );
-  VdbeMemRelease(pTo);
+  assert( pTo->db==pFrom->db );
+  if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo);
   memcpy(pTo, pFrom, MEMCELLSIZE);
-  pTo->xDel = 0;
   if( (pFrom->flags&MEM_Static)==0 ){
     pTo->flags &= ~(MEM_Dyn|MEM_Static|MEM_Ephem);
     assert( srcType==MEM_Ephem || srcType==MEM_Static );
@@ -61473,12 +63886,11 @@ SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int sr
 SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
   int rc = SQLITE_OK;
 
+  assert( pTo->db==pFrom->db );
   assert( (pFrom->flags & MEM_RowSet)==0 );
-  VdbeMemRelease(pTo);
+  if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo);
   memcpy(pTo, pFrom, MEMCELLSIZE);
   pTo->flags &= ~MEM_Dyn;
-  pTo->xDel = 0;
-
   if( pTo->flags&(MEM_Str|MEM_Blob) ){
     if( 0==(pFrom->flags&MEM_Static) ){
       pTo->flags |= MEM_Ephem;
@@ -61503,8 +63915,7 @@ SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){
   sqlite3VdbeMemRelease(pTo);
   memcpy(pTo, pFrom, sizeof(Mem));
   pFrom->flags = MEM_Null;
-  pFrom->xDel = 0;
-  pFrom->zMalloc = 0;
+  pFrom->szMalloc = 0;
 }
 
 /*
@@ -61551,7 +63962,8 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
   if( nByte<0 ){
     assert( enc!=0 );
     if( enc==SQLITE_UTF8 ){
-      for(nByte=0; nByte<=iLimit && z[nByte]; nByte++){}
+      nByte = sqlite3Strlen30(z);
+      if( nByte>iLimit ) nByte = iLimit+1;
     }else{
       for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){}
     }
@@ -61570,14 +63982,17 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
     if( nByte>iLimit ){
       return SQLITE_TOOBIG;
     }
-    if( sqlite3VdbeMemGrow(pMem, nAlloc, 0) ){
+    testcase( nAlloc==0 );
+    testcase( nAlloc==31 );
+    testcase( nAlloc==32 );
+    if( sqlite3VdbeMemClearAndResize(pMem, MAX(nAlloc,32)) ){
       return SQLITE_NOMEM;
     }
     memcpy(pMem->z, z, nAlloc);
   }else if( xDel==SQLITE_DYNAMIC ){
     sqlite3VdbeMemRelease(pMem);
     pMem->zMalloc = pMem->z = (char *)z;
-    pMem->xDel = 0;
+    pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
   }else{
     sqlite3VdbeMemRelease(pMem);
     pMem->z = (char *)z;
@@ -61609,8 +64024,11 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr(
 ** key is true to get the key or false to get data.  The result is written
 ** into the pMem element.
 **
-** The pMem structure is assumed to be uninitialized.  Any prior content
-** is overwritten without being freed.
+** The pMem object must have been initialized.  This routine will use
+** pMem->zMalloc to hold the content from the btree, if possible.  New
+** pMem->zMalloc space will be allocated if necessary.  The calling routine
+** is responsible for making sure that the pMem object is eventually
+** destroyed.
 **
 ** If this routine fails for any reason (malloc returns NULL or unable
 ** to read from the disk) then the pMem is left in an inconsistent state.
@@ -61627,6 +64045,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(
   int rc = SQLITE_OK; /* Return code */
 
   assert( sqlite3BtreeCursorIsValid(pCur) );
+  assert( !VdbeMemDynamic(pMem) );
 
   /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() 
   ** that both the BtShared and database handle mutexes are held. */
@@ -61639,54 +64058,50 @@ SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(
   assert( zData!=0 );
 
   if( offset+amt<=available ){
-    sqlite3VdbeMemRelease(pMem);
     pMem->z = &zData[offset];
     pMem->flags = MEM_Blob|MEM_Ephem;
     pMem->n = (int)amt;
-  }else if( SQLITE_OK==(rc = sqlite3VdbeMemGrow(pMem, amt+2, 0)) ){
-    if( key ){
-      rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z);
-    }else{
-      rc = sqlite3BtreeData(pCur, offset, amt, pMem->z);
-    }
-    if( rc==SQLITE_OK ){
-      pMem->z[amt] = 0;
-      pMem->z[amt+1] = 0;
-      pMem->flags = MEM_Blob|MEM_Term;
-      pMem->n = (int)amt;
-    }else{
-      sqlite3VdbeMemRelease(pMem);
+  }else{
+    pMem->flags = MEM_Null;
+    if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+2)) ){
+      if( key ){
+        rc = sqlite3BtreeKey(pCur, offset, amt, pMem->z);
+      }else{
+        rc = sqlite3BtreeData(pCur, offset, amt, pMem->z);
+      }
+      if( rc==SQLITE_OK ){
+        pMem->z[amt] = 0;
+        pMem->z[amt+1] = 0;
+        pMem->flags = MEM_Blob|MEM_Term;
+        pMem->n = (int)amt;
+      }else{
+        sqlite3VdbeMemRelease(pMem);
+      }
     }
   }
 
   return rc;
 }
 
-/* This function is only available internally, it is not part of the
-** external API. It works in a similar way to sqlite3_value_text(),
-** except the data returned is in the encoding specified by the second
-** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or
-** SQLITE_UTF8.
-**
-** (2006-02-16:)  The enc value can be or-ed with SQLITE_UTF16_ALIGNED.
-** If that is the case, then the result must be aligned on an even byte
-** boundary.
+/*
+** The pVal argument is known to be a value other than NULL.
+** Convert it into a string with encoding enc and return a pointer
+** to a zero-terminated version of that string.
 */
-SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
-  if( !pVal ) return 0;
-
+static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){
+  assert( pVal!=0 );
   assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
   assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
   assert( (pVal->flags & MEM_RowSet)==0 );
-
-  if( pVal->flags&MEM_Null ){
-    return 0;
-  }
-  assert( (MEM_Blob>>3) == MEM_Str );
-  pVal->flags |= (pVal->flags & MEM_Blob)>>3;
-  ExpandBlob(pVal);
-  if( pVal->flags&MEM_Str ){
-    sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED);
+  assert( (pVal->flags & (MEM_Null))==0 );
+  if( pVal->flags & (MEM_Blob|MEM_Str) ){
+    pVal->flags |= MEM_Str;
+    if( pVal->flags & MEM_Zero ){
+      sqlite3VdbeMemExpandBlob(pVal);
+    }
+    if( pVal->enc != (enc & ~SQLITE_UTF16_ALIGNED) ){
+      sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED);
+    }
     if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&SQLITE_PTR_TO_INT(pVal->z)) ){
       assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 );
       if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){
@@ -61695,8 +64110,7 @@ SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
     }
     sqlite3VdbeMemNulTerminate(pVal); /* IMP: R-31275-44060 */
   }else{
-    assert( (pVal->flags&MEM_Blob)==0 );
-    sqlite3VdbeMemStringify(pVal, enc);
+    sqlite3VdbeMemStringify(pVal, enc, 0);
     assert( 0==(1&SQLITE_PTR_TO_INT(pVal->z)) );
   }
   assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0
@@ -61708,6 +64122,30 @@ SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
   }
 }
 
+/* This function is only available internally, it is not part of the
+** external API. It works in a similar way to sqlite3_value_text(),
+** except the data returned is in the encoding specified by the second
+** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or
+** SQLITE_UTF8.
+**
+** (2006-02-16:)  The enc value can be or-ed with SQLITE_UTF16_ALIGNED.
+** If that is the case, then the result must be aligned on an even byte
+** boundary.
+*/
+SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){
+  if( !pVal ) return 0;
+  assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) );
+  assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) );
+  assert( (pVal->flags & MEM_RowSet)==0 );
+  if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){
+    return pVal->z;
+  }
+  if( pVal->flags&MEM_Null ){
+    return 0;
+  }
+  return valueToText(pVal, enc);
+}
+
 /*
 ** Create a new sqlite3_value object.
 */
@@ -61739,7 +64177,7 @@ struct ValueNewStat4Ctx {
 ** Otherwise, if the second argument is non-zero, then this function is 
 ** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not
 ** already been allocated, allocate the UnpackedRecord structure that 
-** that function will return to its caller here. Then return a pointer 
+** that function will return to its caller here. Then return a pointer to
 ** an sqlite3_value within the UnpackedRecord.a[] array.
 */
 static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
@@ -61784,6 +64222,113 @@ static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){
 }
 
 /*
+** The expression object indicated by the second argument is guaranteed
+** to be a scalar SQL function. If
+**
+**   * all function arguments are SQL literals,
+**   * the SQLITE_FUNC_CONSTANT function flag is set, and
+**   * the SQLITE_FUNC_NEEDCOLL function flag is not set,
+**
+** then this routine attempts to invoke the SQL function. Assuming no
+** error occurs, output parameter (*ppVal) is set to point to a value 
+** object containing the result before returning SQLITE_OK.
+**
+** Affinity aff is applied to the result of the function before returning.
+** If the result is a text value, the sqlite3_value object uses encoding 
+** enc.
+**
+** If the conditions above are not met, this function returns SQLITE_OK
+** and sets (*ppVal) to NULL. Or, if an error occurs, (*ppVal) is set to
+** NULL and an SQLite error code returned.
+*/
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+static int valueFromFunction(
+  sqlite3 *db,                    /* The database connection */
+  Expr *p,                        /* The expression to evaluate */
+  u8 enc,                         /* Encoding to use */
+  u8 aff,                         /* Affinity to use */
+  sqlite3_value **ppVal,          /* Write the new value here */
+  struct ValueNewStat4Ctx *pCtx   /* Second argument for valueNew() */
+){
+  sqlite3_context ctx;            /* Context object for function invocation */
+  sqlite3_value **apVal = 0;      /* Function arguments */
+  int nVal = 0;                   /* Size of apVal[] array */
+  FuncDef *pFunc = 0;             /* Function definition */
+  sqlite3_value *pVal = 0;        /* New value */
+  int rc = SQLITE_OK;             /* Return code */
+  int nName;                      /* Size of function name in bytes */
+  ExprList *pList = 0;            /* Function arguments */
+  int i;                          /* Iterator variable */
+
+  assert( pCtx!=0 );
+  assert( (p->flags & EP_TokenOnly)==0 );
+  pList = p->x.pList;
+  if( pList ) nVal = pList->nExpr;
+  nName = sqlite3Strlen30(p->u.zToken);
+  pFunc = sqlite3FindFunction(db, p->u.zToken, nName, nVal, enc, 0);
+  assert( pFunc );
+  if( (pFunc->funcFlags & SQLITE_FUNC_CONSTANT)==0 
+   || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
+  ){
+    return SQLITE_OK;
+  }
+
+  if( pList ){
+    apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal);
+    if( apVal==0 ){
+      rc = SQLITE_NOMEM;
+      goto value_from_function_out;
+    }
+    for(i=0; i<nVal; i++){
+      rc = sqlite3ValueFromExpr(db, pList->a[i].pExpr, enc, aff, &apVal[i]);
+      if( apVal[i]==0 || rc!=SQLITE_OK ) goto value_from_function_out;
+    }
+  }
+
+  pVal = valueNew(db, pCtx);
+  if( pVal==0 ){
+    rc = SQLITE_NOMEM;
+    goto value_from_function_out;
+  }
+
+  assert( pCtx->pParse->rc==SQLITE_OK );
+  memset(&ctx, 0, sizeof(ctx));
+  ctx.pOut = pVal;
+  ctx.pFunc = pFunc;
+  pFunc->xFunc(&ctx, nVal, apVal);
+  if( ctx.isError ){
+    rc = ctx.isError;
+    sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal));
+  }else{
+    sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8);
+    assert( rc==SQLITE_OK );
+    rc = sqlite3VdbeChangeEncoding(pVal, enc);
+    if( rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal) ){
+      rc = SQLITE_TOOBIG;
+      pCtx->pParse->nErr++;
+    }
+  }
+  pCtx->pParse->rc = rc;
+
+ value_from_function_out:
+  if( rc!=SQLITE_OK ){
+    pVal = 0;
+  }
+  if( apVal ){
+    for(i=0; i<nVal; i++){
+      sqlite3ValueFree(apVal[i]);
+    }
+    sqlite3DbFree(db, apVal);
+  }
+
+  *ppVal = pVal;
+  return rc;
+}
+#else
+# define valueFromFunction(a,b,c,d,e,f) SQLITE_OK
+#endif /* defined(SQLITE_ENABLE_STAT3_OR_STAT4) */
+
+/*
 ** Extract a value from the supplied expression in the manner described
 ** above sqlite3ValueFromExpr(). Allocate the sqlite3_value object
 ** using valueNew().
@@ -61812,9 +64357,26 @@ static int valueFromExpr(
     *ppVal = 0;
     return SQLITE_OK;
   }
-  op = pExpr->op;
+  while( (op = pExpr->op)==TK_UPLUS ) pExpr = pExpr->pLeft;
   if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
 
+  /* Compressed expressions only appear when parsing the DEFAULT clause
+  ** on a table column definition, and hence only when pCtx==0.  This
+  ** check ensures that an EP_TokenOnly expression is never passed down
+  ** into valueFromFunction(). */
+  assert( (pExpr->flags & EP_TokenOnly)==0 || pCtx==0 );
+
+  if( op==TK_CAST ){
+    u8 aff = sqlite3AffinityType(pExpr->u.zToken,0);
+    rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx);
+    testcase( rc!=SQLITE_OK );
+    if( *ppVal ){
+      sqlite3VdbeMemCast(*ppVal, aff, SQLITE_UTF8);
+      sqlite3ValueApplyAffinity(*ppVal, affinity, SQLITE_UTF8);
+    }
+    return rc;
+  }
+
   /* Handle negative integers in a single step.  This is needed in the
   ** case when the value is -9223372036854775808.
   */
@@ -61851,14 +64413,14 @@ static int valueFromExpr(
      && pVal!=0
     ){
       sqlite3VdbeMemNumerify(pVal);
-      if( pVal->u.i==SMALLEST_INT64 ){
-        pVal->flags &= ~MEM_Int;
-        pVal->flags |= MEM_Real;
-        pVal->r = (double)SMALLEST_INT64;
+      if( pVal->flags & MEM_Real ){
+        pVal->u.r = -pVal->u.r;
+      }else if( pVal->u.i==SMALLEST_INT64 ){
+        pVal->u.r = -(double)SMALLEST_INT64;
+        MemSetTypeFlag(pVal, MEM_Real);
       }else{
         pVal->u.i = -pVal->u.i;
       }
-      pVal->r = -pVal->r;
       sqlite3ValueApplyAffinity(pVal, affinity, enc);
     }
   }else if( op==TK_NULL ){
@@ -61880,6 +64442,12 @@ static int valueFromExpr(
   }
 #endif
 
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+  else if( op==TK_FUNCTION && pCtx!=0 ){
+    rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx);
+  }
+#endif
+
   *ppVal = pVal;
   return rc;
 
@@ -61949,7 +64517,7 @@ static void recordFunc(
     sqlite3_result_error_nomem(context);
   }else{
     aRet[0] = nSerial+1;
-    sqlite3PutVarint(&aRet[1], iSerial);
+    putVarint32(&aRet[1], iSerial);
     sqlite3VdbeSerialPut(&aRet[1+nSerial], argv[0], iSerial);
     sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT);
     sqlite3DbFree(db, aRet);
@@ -62166,7 +64734,7 @@ SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){
     Mem *aMem = pRec->aMem;
     sqlite3 *db = aMem[0].db;
     for(i=0; i<nCol; i++){
-      sqlite3DbFree(db, aMem[i].zMalloc);
+      sqlite3VdbeMemRelease(&aMem[i]);
     }
     sqlite3KeyInfoUnref(pRec->pKeyInfo);
     sqlite3DbFree(db, pRec);
@@ -62226,9 +64794,7 @@ SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){
 **
 *************************************************************************
 ** This file contains code used for creating, destroying, and populating
-** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.)  Prior
-** to version 2.8.7, all this code was combined into the vdbe.c source file.
-** But that file was getting too big so this subroutines were split out.
+** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) 
 */
 
 /*
@@ -62271,7 +64837,7 @@ SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepa
 /*
 ** Return the SQL associated with a prepared statement
 */
-SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt){
+SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt){
   Vdbe *p = (Vdbe *)pStmt;
   return (p && p->isPrepareV2) ? p->zSql : 0;
 }
@@ -62612,6 +65178,7 @@ static Op *opIterNext(VdbeOpIter *p){
 */
 SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
   int hasAbort = 0;
+  int hasFkCounter = 0;
   Op *pOp;
   VdbeOpIter sIter;
   memset(&sIter, 0, sizeof(sIter));
@@ -62620,15 +65187,17 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
   while( (pOp = opIterNext(&sIter))!=0 ){
     int opcode = pOp->opcode;
     if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename 
-#ifndef SQLITE_OMIT_FOREIGN_KEY
-     || (opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1) 
-#endif
      || ((opcode==OP_Halt || opcode==OP_HaltIfNull) 
       && ((pOp->p1&0xff)==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
     ){
       hasAbort = 1;
       break;
     }
+#ifndef SQLITE_OMIT_FOREIGN_KEY
+    if( opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1 ){
+      hasFkCounter = 1;
+    }
+#endif
   }
   sqlite3DbFree(v->db, sIter.apSub);
 
@@ -62637,7 +65206,7 @@ SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){
   ** through all opcodes and hasAbort may be set incorrectly. Return
   ** true for this case to prevent the assert() in the callers frame
   ** from failing.  */
-  return ( v->db->mallocFailed || hasAbort==mayAbort );
+  return ( v->db->mallocFailed || hasAbort==mayAbort || hasFkCounter );
 }
 #endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */
 
@@ -62813,6 +65382,34 @@ SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp,
   return addr;
 }
 
+#if defined(SQLITE_ENABLE_STMT_SCANSTATUS)
+/*
+** Add an entry to the array of counters managed by sqlite3_stmt_scanstatus().
+*/
+SQLITE_PRIVATE void sqlite3VdbeScanStatus(
+  Vdbe *p,                        /* VM to add scanstatus() to */
+  int addrExplain,                /* Address of OP_Explain (or 0) */
+  int addrLoop,                   /* Address of loop counter */ 
+  int addrVisit,                  /* Address of rows visited counter */
+  LogEst nEst,                    /* Estimated number of output rows */
+  const char *zName               /* Name of table or index being scanned */
+){
+  int nByte = (p->nScan+1) * sizeof(ScanStatus);
+  ScanStatus *aNew;
+  aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte);
+  if( aNew ){
+    ScanStatus *pNew = &aNew[p->nScan++];
+    pNew->addrExplain = addrExplain;
+    pNew->addrLoop = addrLoop;
+    pNew->addrVisit = addrVisit;
+    pNew->nEst = nEst;
+    pNew->zName = sqlite3DbStrDup(p->db, zName);
+    p->aScan = aNew;
+  }
+}
+#endif
+
+
 /*
 ** Change the value of the P1 operand for a specific instruction.
 ** This routine is useful when a large program is loaded from a
@@ -62912,7 +65509,7 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){
           sqlite3ValueFree((sqlite3_value*)p4);
         }else{
           Mem *p = (Mem*)p4;
-          sqlite3DbFree(db, p->zMalloc);
+          if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
           sqlite3DbFree(db, p);
         }
         break;
@@ -62968,7 +65565,8 @@ SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
 }
 
 /*
-** Remove the last opcode inserted
+** If the last opcode is "op" and it is not a jump destination,
+** then remove it.  Return true if and only if an opcode was removed.
 */
 SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
   if( (p->nOp-1)>(p->pParse->iFixedOp) && p->aOp[p->nOp-1].opcode==op ){
@@ -63109,7 +65707,7 @@ SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe *v, int iLine){
 ** routine, then a pointer to a dummy VdbeOp will be returned.  That opcode
 ** is readable but not writable, though it is cast to a writable value.
 ** The return of a dummy opcode allows the call to continue functioning
-** after a OOM fault without having to check to see if the return from 
+** after an OOM fault without having to check to see if the return from 
 ** this routine is a valid pointer.  But because the dummy.opcode is 0,
 ** dummy will never be written to.  This is verified by code inspection and
 ** by running with Valgrind.
@@ -63290,7 +65888,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
       }else if( pMem->flags & MEM_Int ){
         sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i);
       }else if( pMem->flags & MEM_Real ){
-        sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->r);
+        sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->u.r);
       }else if( pMem->flags & MEM_Null ){
         sqlite3_snprintf(nTemp, zTemp, "NULL");
       }else{
@@ -63302,7 +65900,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){
 #ifndef SQLITE_OMIT_VIRTUALTABLE
     case P4_VTAB: {
       sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab;
-      sqlite3_snprintf(nTemp, zTemp, "vtab:%p:%p", pVtab, pVtab->pModule);
+      sqlite3_snprintf(nTemp, zTemp, "vtab:%p", pVtab);
       break;
     }
 #endif
@@ -63440,16 +66038,16 @@ SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
 */
 static void releaseMemArray(Mem *p, int N){
   if( p && N ){
-    Mem *pEnd;
+    Mem *pEnd = &p[N];
     sqlite3 *db = p->db;
     u8 malloc_failed = db->mallocFailed;
     if( db->pnBytesFreed ){
-      for(pEnd=&p[N]; p<pEnd; p++){
-        sqlite3DbFree(db, p->zMalloc);
-      }
+      do{
+        if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc);
+      }while( (++p)<pEnd );
       return;
     }
-    for(pEnd=&p[N]; p<pEnd; p++){
+    do{
       assert( (&p[1])==pEnd || p[0].db==p[1].db );
       assert( sqlite3VdbeCheckMemInvariants(p) );
 
@@ -63471,13 +66069,13 @@ static void releaseMemArray(Mem *p, int N){
       testcase( p->flags & MEM_RowSet );
       if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){
         sqlite3VdbeMemRelease(p);
-      }else if( p->zMalloc ){
+      }else if( p->szMalloc ){
         sqlite3DbFree(db, p->zMalloc);
-        p->zMalloc = 0;
+        p->szMalloc = 0;
       }
 
       p->flags = MEM_Undefined;
-    }
+    }while( (++p)<pEnd );
     db->mallocFailed = malloc_failed;
   }
 }
@@ -63640,7 +66238,7 @@ SQLITE_PRIVATE int sqlite3VdbeList(
     pMem->u.i = pOp->p3;                          /* P3 */
     pMem++;
 
-    if( sqlite3VdbeMemGrow(pMem, 32, 0) ){            /* P4 */
+    if( sqlite3VdbeMemClearAndResize(pMem, 32) ){ /* P4 */
       assert( p->db->mallocFailed );
       return SQLITE_ERROR;
     }
@@ -63656,7 +66254,7 @@ SQLITE_PRIVATE int sqlite3VdbeList(
     pMem++;
 
     if( p->explain==1 ){
-      if( sqlite3VdbeMemGrow(pMem, 4, 0) ){
+      if( sqlite3VdbeMemClearAndResize(pMem, 4) ){
         assert( p->db->mallocFailed );
         return SQLITE_ERROR;
       }
@@ -63667,7 +66265,7 @@ SQLITE_PRIVATE int sqlite3VdbeList(
       pMem++;
   
 #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
-      if( sqlite3VdbeMemGrow(pMem, 500, 0) ){
+      if( sqlite3VdbeMemClearAndResize(pMem, 500) ){
         assert( p->db->mallocFailed );
         return SQLITE_ERROR;
       }
@@ -63820,13 +66418,13 @@ SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){
 /*
 ** Prepare a virtual machine for execution for the first time after
 ** creating the virtual machine.  This involves things such
-** as allocating stack space and initializing the program counter.
+** as allocating registers and initializing the program counter.
 ** After the VDBE has be prepped, it can be executed by one or more
 ** calls to sqlite3VdbeExec().  
 **
-** This function may be called exact once on a each virtual machine.
+** This function may be called exactly once on each virtual machine.
 ** After this routine is called the VM has been "packaged" and is ready
-** to run.  After this routine is called, futher calls to 
+** to run.  After this routine is called, further calls to 
 ** sqlite3VdbeAddOp() functions are prohibited.  This routine disconnects
 ** the Vdbe from the Parse object that helped generate it so that the
 ** the Vdbe becomes an independent entity and the Parse object can be
@@ -63910,6 +66508,9 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
     p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*),
                           &zCsr, zEnd, &nByte);
     p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, &zCsr, zEnd, &nByte);
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+    p->anExec = allocSpace(p->anExec, p->nOp*sizeof(i64), &zCsr, zEnd, &nByte);
+#endif
     if( nByte ){
       p->pFree = sqlite3DbMallocZero(db, nByte);
     }
@@ -63926,7 +66527,7 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady(
       p->aVar[n].db = db;
     }
   }
-  if( p->azVar ){
+  if( p->azVar && pParse->nzVar>0 ){
     p->nzVar = pParse->nzVar;
     memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0]));
     memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0]));
@@ -63960,23 +66561,43 @@ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){
     sqlite3BtreeCloseCursor(pCx->pCursor);
   }
 #ifndef SQLITE_OMIT_VIRTUALTABLE
-  if( pCx->pVtabCursor ){
+  else if( pCx->pVtabCursor ){
     sqlite3_vtab_cursor *pVtabCursor = pCx->pVtabCursor;
     const sqlite3_module *pModule = pVtabCursor->pVtab->pModule;
-    p->inVtabMethod = 1;
+    assert( pVtabCursor->pVtab->nRef>0 );
+    pVtabCursor->pVtab->nRef--;
     pModule->xClose(pVtabCursor);
-    p->inVtabMethod = 0;
   }
 #endif
 }
 
 /*
+** Close all cursors in the current frame.
+*/
+static void closeCursorsInFrame(Vdbe *p){
+  if( p->apCsr ){
+    int i;
+    for(i=0; i<p->nCursor; i++){
+      VdbeCursor *pC = p->apCsr[i];
+      if( pC ){
+        sqlite3VdbeFreeCursor(p, pC);
+        p->apCsr[i] = 0;
+      }
+    }
+  }
+}
+
+/*
 ** Copy the values stored in the VdbeFrame structure to its Vdbe. This
 ** is used, for example, when a trigger sub-program is halted to restore
 ** control to the main program.
 */
 SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
   Vdbe *v = pFrame->v;
+  closeCursorsInFrame(v);
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+  v->anExec = pFrame->anExec;
+#endif
   v->aOnceFlag = pFrame->aOnceFlag;
   v->nOnceFlag = pFrame->nOnceFlag;
   v->aOp = pFrame->aOp;
@@ -63987,6 +66608,7 @@ SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
   v->nCursor = pFrame->nCursor;
   v->db->lastRowid = pFrame->lastRowid;
   v->nChange = pFrame->nChange;
+  v->db->nChange = pFrame->nDbChange;
   return pFrame->pc;
 }
 
@@ -64003,20 +66625,11 @@ static void closeAllCursors(Vdbe *p){
     VdbeFrame *pFrame;
     for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent);
     sqlite3VdbeFrameRestore(pFrame);
+    p->pFrame = 0;
+    p->nFrame = 0;
   }
-  p->pFrame = 0;
-  p->nFrame = 0;
-
-  if( p->apCsr ){
-    int i;
-    for(i=0; i<p->nCursor; i++){
-      VdbeCursor *pC = p->apCsr[i];
-      if( pC ){
-        sqlite3VdbeFreeCursor(p, pC);
-        p->apCsr[i] = 0;
-      }
-    }
-  }
+  assert( p->nFrame==0 );
+  closeCursorsInFrame(p);
   if( p->aMem ){
     releaseMemArray(&p->aMem[1], p->nMem);
   }
@@ -64027,16 +66640,12 @@ static void closeAllCursors(Vdbe *p){
   }
 
   /* Delete any auxdata allocations made by the VM */
-  sqlite3VdbeDeleteAuxData(p, -1, 0);
+  if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p, -1, 0);
   assert( p->pAuxData==0 );
 }
 
 /*
-** Clean up the VM after execution.
-**
-** This routine will automatically close any cursors, lists, and/or
-** sorters that were left open.  It also deletes the values of
-** variables in the aVar[] array.
+** Clean up the VM after a single run.
 */
 static void Cleanup(Vdbe *p){
   sqlite3 *db = p->db;
@@ -64204,7 +66813,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
 
   /* The complex case - There is a multi-file write-transaction active.
   ** This requires a master journal file to ensure the transaction is
-  ** committed atomicly.
+  ** committed atomically.
   */
 #ifndef SQLITE_OMIT_DISKIO
   else{
@@ -64323,7 +66932,7 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){
     ** doing this the directory is synced again before any individual
     ** transaction files are deleted.
     */
-    rc = sqlite3OsDelete(pVfs, zMaster, 1);
+    rc = sqlite3OsDelete(pVfs, zMaster, needSync);
     sqlite3DbFree(db, zMaster);
     zMaster = 0;
     if( rc ){
@@ -64557,6 +67166,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
           sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
           sqlite3CloseSavepoints(db);
           db->autoCommit = 1;
+          p->nChange = 0;
         }
       }
     }
@@ -64597,6 +67207,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
         }else if( rc!=SQLITE_OK ){
           p->rc = rc;
           sqlite3RollbackAll(db, SQLITE_OK);
+          p->nChange = 0;
         }else{
           db->nDeferredCons = 0;
           db->nDeferredImmCons = 0;
@@ -64605,6 +67216,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
         }
       }else{
         sqlite3RollbackAll(db, SQLITE_OK);
+        p->nChange = 0;
       }
       db->nStatement = 0;
     }else if( eStatementOp==0 ){
@@ -64616,6 +67228,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
         sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
         sqlite3CloseSavepoints(db);
         db->autoCommit = 1;
+        p->nChange = 0;
       }
     }
   
@@ -64636,6 +67249,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){
         sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
         sqlite3CloseSavepoints(db);
         db->autoCommit = 1;
+        p->nChange = 0;
       }
     }
   
@@ -64711,7 +67325,7 @@ SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p){
     db->mallocFailed = mallocFailed;
     db->errCode = rc;
   }else{
-    sqlite3Error(db, rc, 0);
+    sqlite3Error(db, rc);
   }
   return rc;
 }
@@ -64774,7 +67388,7 @@ SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){
     ** to sqlite3_step(). For consistency (since sqlite3_step() was
     ** called), set the database error in this case as well.
     */
-    sqlite3Error(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg);
+    sqlite3ErrorWithMsg(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg);
     sqlite3DbFree(db, p->zErrMsg);
     p->zErrMsg = 0;
   }
@@ -64852,7 +67466,7 @@ SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){
 **      from left to right), or
 **
 **    * the corresponding bit in argument mask is clear (where the first
-**      function parameter corrsponds to bit 0 etc.).
+**      function parameter corresponds to bit 0 etc.).
 */
 SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){
   AuxData **pp = &pVdbe->pAuxData;
@@ -64897,9 +67511,11 @@ SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
   sqlite3DbFree(db, p->aColName);
   sqlite3DbFree(db, p->zSql);
   sqlite3DbFree(db, p->pFree);
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
-  sqlite3DbFree(db, p->zExplain);
-  sqlite3DbFree(db, p->pExplain);
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+  for(i=0; i<p->nScan; i++){
+    sqlite3DbFree(db, p->aScan[i].zName);
+  }
+  sqlite3DbFree(db, p->aScan);
 #endif
 }
 
@@ -64928,6 +67544,57 @@ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){
 }
 
 /*
+** The cursor "p" has a pending seek operation that has not yet been
+** carried out.  Seek the cursor now.  If an error occurs, return
+** the appropriate error code.
+*/
+static int SQLITE_NOINLINE handleDeferredMoveto(VdbeCursor *p){
+  int res, rc;
+#ifdef SQLITE_TEST
+  extern int sqlite3_search_count;
+#endif
+  assert( p->deferredMoveto );
+  assert( p->isTable );
+  rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
+  if( rc ) return rc;
+  if( res!=0 ) return SQLITE_CORRUPT_BKPT;
+#ifdef SQLITE_TEST
+  sqlite3_search_count++;
+#endif
+  p->deferredMoveto = 0;
+  p->cacheStatus = CACHE_STALE;
+  return SQLITE_OK;
+}
+
+/*
+** Something has moved cursor "p" out of place.  Maybe the row it was
+** pointed to was deleted out from under it.  Or maybe the btree was
+** rebalanced.  Whatever the cause, try to restore "p" to the place it
+** is supposed to be pointing.  If the row was deleted out from under the
+** cursor, set the cursor to point to a NULL row.
+*/
+static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){
+  int isDifferentRow, rc;
+  assert( p->pCursor!=0 );
+  assert( sqlite3BtreeCursorHasMoved(p->pCursor) );
+  rc = sqlite3BtreeCursorRestore(p->pCursor, &isDifferentRow);
+  p->cacheStatus = CACHE_STALE;
+  if( isDifferentRow ) p->nullRow = 1;
+  return rc;
+}
+
+/*
+** Check to ensure that the cursor is valid.  Restore the cursor
+** if need be.  Return any I/O error from the restore operation.
+*/
+SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){
+  if( sqlite3BtreeCursorHasMoved(p->pCursor) ){
+    return handleMovedCursor(p);
+  }
+  return SQLITE_OK;
+}
+
+/*
 ** Make sure the cursor p is ready to read or write the row to which it
 ** was last positioned.  Return an error code if an OOM fault or I/O error
 ** prevents us from positioning the cursor to its correct position.
@@ -64942,29 +67609,10 @@ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){
 */
 SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){
   if( p->deferredMoveto ){
-    int res, rc;
-#ifdef SQLITE_TEST
-    extern int sqlite3_search_count;
-#endif
-    assert( p->isTable );
-    rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res);
-    if( rc ) return rc;
-    p->lastRowid = p->movetoTarget;
-    if( res!=0 ) return SQLITE_CORRUPT_BKPT;
-    p->rowidIsValid = 1;
-#ifdef SQLITE_TEST
-    sqlite3_search_count++;
-#endif
-    p->deferredMoveto = 0;
-    p->cacheStatus = CACHE_STALE;
-  }else if( p->pCursor ){
-    int hasMoved;
-    int rc = sqlite3BtreeCursorHasMoved(p->pCursor, &hasMoved);
-    if( rc ) return rc;
-    if( hasMoved ){
-      p->cacheStatus = CACHE_STALE;
-      if( hasMoved==2 ) p->nullRow = 1;
-    }
+    return handleDeferredMoveto(p);
+  }
+  if( p->pCursor && sqlite3BtreeCursorHasMoved(p->pCursor) ){
+    return handleMovedCursor(p);
   }
   return SQLITE_OK;
 }
@@ -65027,9 +67675,7 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format){
     i64 i = pMem->u.i;
     u64 u;
     if( i<0 ){
-      if( i<(-MAX_6BYTE) ) return 6;
-      /* Previous test prevents:  u = -(-9223372036854775808) */
-      u = -i;
+      u = ~i;
     }else{
       u = i;
     }
@@ -65140,17 +67786,18 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){
     u64 v;
     u32 i;
     if( serial_type==7 ){
-      assert( sizeof(v)==sizeof(pMem->r) );
-      memcpy(&v, &pMem->r, sizeof(v));
+      assert( sizeof(v)==sizeof(pMem->u.r) );
+      memcpy(&v, &pMem->u.r, sizeof(v));
       swapMixedEndianFloat(v);
     }else{
       v = pMem->u.i;
     }
     len = i = sqlite3VdbeSerialTypeLen(serial_type);
-    while( i-- ){
-      buf[i] = (u8)(v&0xFF);
+    assert( i>0 );
+    do{
+      buf[--i] = (u8)(v&0xFF);
       v >>= 8;
-    }
+    }while( i );
     return len;
   }
 
@@ -65174,51 +67821,101 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){
 #define TWO_BYTE_INT(x)    (256*(i8)((x)[0])|(x)[1])
 #define THREE_BYTE_INT(x)  (65536*(i8)((x)[0])|((x)[1]<<8)|(x)[2])
 #define FOUR_BYTE_UINT(x)  (((u32)(x)[0]<<24)|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
+#define FOUR_BYTE_INT(x) (16777216*(i8)((x)[0])|((x)[1]<<16)|((x)[2]<<8)|(x)[3])
 
 /*
 ** Deserialize the data blob pointed to by buf as serial type serial_type
 ** and store the result in pMem.  Return the number of bytes read.
+**
+** This function is implemented as two separate routines for performance.
+** The few cases that require local variables are broken out into a separate
+** routine so that in most cases the overhead of moving the stack pointer
+** is avoided.
 */ 
+static u32 SQLITE_NOINLINE serialGet(
+  const unsigned char *buf,     /* Buffer to deserialize from */
+  u32 serial_type,              /* Serial type to deserialize */
+  Mem *pMem                     /* Memory cell to write value into */
+){
+  u64 x = FOUR_BYTE_UINT(buf);
+  u32 y = FOUR_BYTE_UINT(buf+4);
+  x = (x<<32) + y;
+  if( serial_type==6 ){
+    /* EVIDENCE-OF: R-29851-52272 Value is a big-endian 64-bit
+    ** twos-complement integer. */
+    pMem->u.i = *(i64*)&x;
+    pMem->flags = MEM_Int;
+    testcase( pMem->u.i<0 );
+  }else{
+    /* EVIDENCE-OF: R-57343-49114 Value is a big-endian IEEE 754-2008 64-bit
+    ** floating point number. */
+#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT)
+    /* Verify that integers and floating point values use the same
+    ** byte order.  Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is
+    ** defined that 64-bit floating point values really are mixed
+    ** endian.
+    */
+    static const u64 t1 = ((u64)0x3ff00000)<<32;
+    static const double r1 = 1.0;
+    u64 t2 = t1;
+    swapMixedEndianFloat(t2);
+    assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 );
+#endif
+    assert( sizeof(x)==8 && sizeof(pMem->u.r)==8 );
+    swapMixedEndianFloat(x);
+    memcpy(&pMem->u.r, &x, sizeof(x));
+    pMem->flags = sqlite3IsNaN(pMem->u.r) ? MEM_Null : MEM_Real;
+  }
+  return 8;
+}
 SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(
   const unsigned char *buf,     /* Buffer to deserialize from */
   u32 serial_type,              /* Serial type to deserialize */
   Mem *pMem                     /* Memory cell to write value into */
 ){
-  u64 x;
-  u32 y;
   switch( serial_type ){
     case 10:   /* Reserved for future use */
     case 11:   /* Reserved for future use */
-    case 0: {  /* NULL */
+    case 0: {  /* Null */
+      /* EVIDENCE-OF: R-24078-09375 Value is a NULL. */
       pMem->flags = MEM_Null;
       break;
     }
-    case 1: { /* 1-byte signed integer */
+    case 1: {
+      /* EVIDENCE-OF: R-44885-25196 Value is an 8-bit twos-complement
+      ** integer. */
       pMem->u.i = ONE_BYTE_INT(buf);
       pMem->flags = MEM_Int;
       testcase( pMem->u.i<0 );
       return 1;
     }
     case 2: { /* 2-byte signed integer */
+      /* EVIDENCE-OF: R-49794-35026 Value is a big-endian 16-bit
+      ** twos-complement integer. */
       pMem->u.i = TWO_BYTE_INT(buf);
       pMem->flags = MEM_Int;
       testcase( pMem->u.i<0 );
       return 2;
     }
     case 3: { /* 3-byte signed integer */
+      /* EVIDENCE-OF: R-37839-54301 Value is a big-endian 24-bit
+      ** twos-complement integer. */
       pMem->u.i = THREE_BYTE_INT(buf);
       pMem->flags = MEM_Int;
       testcase( pMem->u.i<0 );
       return 3;
     }
     case 4: { /* 4-byte signed integer */
-      y = FOUR_BYTE_UINT(buf);
-      pMem->u.i = (i64)*(int*)&y;
+      /* EVIDENCE-OF: R-01849-26079 Value is a big-endian 32-bit
+      ** twos-complement integer. */
+      pMem->u.i = FOUR_BYTE_INT(buf);
       pMem->flags = MEM_Int;
       testcase( pMem->u.i<0 );
       return 4;
     }
     case 5: { /* 6-byte signed integer */
+      /* EVIDENCE-OF: R-50385-09674 Value is a big-endian 48-bit
+      ** twos-complement integer. */
       pMem->u.i = FOUR_BYTE_UINT(buf+2) + (((i64)1)<<32)*TWO_BYTE_INT(buf);
       pMem->flags = MEM_Int;
       testcase( pMem->u.i<0 );
@@ -65226,52 +67923,32 @@ SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(
     }
     case 6:   /* 8-byte signed integer */
     case 7: { /* IEEE floating point */
-#if !defined(NDEBUG) && !defined(SQLITE_OMIT_FLOATING_POINT)
-      /* Verify that integers and floating point values use the same
-      ** byte order.  Or, that if SQLITE_MIXED_ENDIAN_64BIT_FLOAT is
-      ** defined that 64-bit floating point values really are mixed
-      ** endian.
-      */
-      static const u64 t1 = ((u64)0x3ff00000)<<32;
-      static const double r1 = 1.0;
-      u64 t2 = t1;
-      swapMixedEndianFloat(t2);
-      assert( sizeof(r1)==sizeof(t2) && memcmp(&r1, &t2, sizeof(r1))==0 );
-#endif
-      x = FOUR_BYTE_UINT(buf);
-      y = FOUR_BYTE_UINT(buf+4);
-      x = (x<<32) | y;
-      if( serial_type==6 ){
-        pMem->u.i = *(i64*)&x;
-        pMem->flags = MEM_Int;
-        testcase( pMem->u.i<0 );
-      }else{
-        assert( sizeof(x)==8 && sizeof(pMem->r)==8 );
-        swapMixedEndianFloat(x);
-        memcpy(&pMem->r, &x, sizeof(x));
-        pMem->flags = sqlite3IsNaN(pMem->r) ? MEM_Null : MEM_Real;
-      }
-      return 8;
+      /* These use local variables, so do them in a separate routine
+      ** to avoid having to move the frame pointer in the common case */
+      return serialGet(buf,serial_type,pMem);
     }
     case 8:    /* Integer 0 */
     case 9: {  /* Integer 1 */
+      /* EVIDENCE-OF: R-12976-22893 Value is the integer 0. */
+      /* EVIDENCE-OF: R-18143-12121 Value is the integer 1. */
       pMem->u.i = serial_type-8;
       pMem->flags = MEM_Int;
       return 0;
     }
     default: {
+      /* EVIDENCE-OF: R-14606-31564 Value is a BLOB that is (N-12)/2 bytes in
+      ** length.
+      ** EVIDENCE-OF: R-28401-00140 Value is a string in the text encoding and
+      ** (N-13)/2 bytes in length. */
       static const u16 aFlag[] = { MEM_Blob|MEM_Ephem, MEM_Str|MEM_Ephem };
-      u32 len = (serial_type-12)/2;
       pMem->z = (char *)buf;
-      pMem->n = len;
-      pMem->xDel = 0;
+      pMem->n = (serial_type-12)/2;
       pMem->flags = aFlag[serial_type&1];
-      return len;
+      return pMem->n;
     }
   }
   return 0;
 }
-
 /*
 ** This routine is used to allocate sufficient space for an UnpackedRecord
 ** structure large enough to be used with sqlite3VdbeRecordUnpack() if
@@ -65341,17 +68018,17 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(
   idx = getVarint32(aKey, szHdr);
   d = szHdr;
   u = 0;
-  while( idx<szHdr && u<p->nField && d<=nKey ){
+  while( idx<szHdr && d<=nKey ){
     u32 serial_type;
 
     idx += getVarint32(&aKey[idx], serial_type);
     pMem->enc = pKeyInfo->enc;
     pMem->db = pKeyInfo->db;
     /* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */
-    pMem->zMalloc = 0;
+    pMem->szMalloc = 0;
     d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem);
     pMem++;
-    u++;
+    if( (++u)>=p->nField ) break;
   }
   assert( u<=pKeyInfo->nField + 1 );
   p->nField = u;
@@ -65365,10 +68042,14 @@ SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(
 ** sqlite3VdbeSerialGet() and sqlite3MemCompare() functions. It is used
 ** in assert() statements to ensure that the optimized code in
 ** sqlite3VdbeRecordCompare() returns results with these two primitives.
+**
+** Return true if the result of comparison is equivalent to desiredResult.
+** Return false if there is a disagreement.
 */
 static int vdbeRecordCompareDebug(
   int nKey1, const void *pKey1, /* Left key */
-  const UnpackedRecord *pPKey2  /* Right key */
+  const UnpackedRecord *pPKey2, /* Right key */
+  int desiredResult             /* Correct answer */
 ){
   u32 d1;            /* Offset into aKey[] of next data element */
   u32 idx1;          /* Offset into aKey[] of next header element */
@@ -65380,10 +68061,11 @@ static int vdbeRecordCompareDebug(
   Mem mem1;
 
   pKeyInfo = pPKey2->pKeyInfo;
+  if( pKeyInfo->db==0 ) return 1;
   mem1.enc = pKeyInfo->enc;
   mem1.db = pKeyInfo->db;
   /* mem1.flags = 0;  // Will be initialized by sqlite3VdbeSerialGet() */
-  VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */
+  VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */
 
   /* Compilers may complain that mem1.u.i is potentially uninitialized.
   ** We could initialize it, as shown here, to silence those complaints.
@@ -65426,11 +68108,11 @@ static int vdbeRecordCompareDebug(
     */
     rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->aColl[i]);
     if( rc!=0 ){
-      assert( mem1.zMalloc==0 );  /* See comment below */
+      assert( mem1.szMalloc==0 );  /* See comment below */
       if( pKeyInfo->aSortOrder[i] ){
         rc = -rc;  /* Invert the result for DESC sort order. */
       }
-      return rc;
+      goto debugCompareEnd;
     }
     i++;
   }while( idx1<szHdr1 && i<pPKey2->nField );
@@ -65439,13 +68121,57 @@ static int vdbeRecordCompareDebug(
   ** the following assert().  If the assert() fails, it indicates a
   ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1).
   */
-  assert( mem1.zMalloc==0 );
+  assert( mem1.szMalloc==0 );
 
   /* rc==0 here means that one of the keys ran out of fields and
-  ** all the fields up to that point were equal. Return the the default_rc
+  ** all the fields up to that point were equal. Return the default_rc
   ** value.  */
-  return pPKey2->default_rc;
+  rc = pPKey2->default_rc;
+
+debugCompareEnd:
+  if( desiredResult==0 && rc==0 ) return 1;
+  if( desiredResult<0 && rc<0 ) return 1;
+  if( desiredResult>0 && rc>0 ) return 1;
+  if( CORRUPT_DB ) return 1;
+  if( pKeyInfo->db->mallocFailed ) return 1;
+  return 0;
+}
+#endif
+
+#if SQLITE_DEBUG
+/*
+** Count the number of fields (a.k.a. columns) in the record given by
+** pKey,nKey.  The verify that this count is less than or equal to the
+** limit given by pKeyInfo->nField + pKeyInfo->nXField.
+**
+** If this constraint is not satisfied, it means that the high-speed
+** vdbeRecordCompareInt() and vdbeRecordCompareString() routines will
+** not work correctly.  If this assert() ever fires, it probably means
+** that the KeyInfo.nField or KeyInfo.nXField values were computed
+** incorrectly.
+*/
+static void vdbeAssertFieldCountWithinLimits(
+  int nKey, const void *pKey,   /* The record to verify */ 
+  const KeyInfo *pKeyInfo       /* Compare size with this KeyInfo */
+){
+  int nField = 0;
+  u32 szHdr;
+  u32 idx;
+  u32 notUsed;
+  const unsigned char *aKey = (const unsigned char*)pKey;
+
+  if( CORRUPT_DB ) return;
+  idx = getVarint32(aKey, szHdr);
+  assert( nKey>=0 );
+  assert( szHdr<=(u32)nKey );
+  while( idx<szHdr ){
+    idx += getVarint32(aKey+idx, notUsed);
+    nField++;
+  }
+  assert( nField <= pKeyInfo->nField+pKeyInfo->nXField );
 }
+#else
+# define vdbeAssertFieldCountWithinLimits(A,B,C)
 #endif
 
 /*
@@ -65457,7 +68183,8 @@ static int vdbeRecordCompareDebug(
 static int vdbeCompareMemString(
   const Mem *pMem1,
   const Mem *pMem2,
-  const CollSeq *pColl
+  const CollSeq *pColl,
+  u8 *prcErr                      /* If an OOM occurs, set to SQLITE_NOMEM */
 ){
   if( pMem1->enc==pColl->enc ){
     /* The strings are already in the correct encoding.  Call the
@@ -65469,8 +68196,8 @@ static int vdbeCompareMemString(
     int n1, n2;
     Mem c1;
     Mem c2;
-    memset(&c1, 0, sizeof(c1));
-    memset(&c2, 0, sizeof(c2));
+    sqlite3VdbeMemInit(&c1, pMem1->db, MEM_Null);
+    sqlite3VdbeMemInit(&c2, pMem1->db, MEM_Null);
     sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem);
     sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem);
     v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc);
@@ -65480,11 +68207,24 @@ static int vdbeCompareMemString(
     rc = pColl->xCmp(pColl->pUser, n1, v1, n2, v2);
     sqlite3VdbeMemRelease(&c1);
     sqlite3VdbeMemRelease(&c2);
+    if( (v1==0 || v2==0) && prcErr ) *prcErr = SQLITE_NOMEM;
     return rc;
   }
 }
 
 /*
+** Compare two blobs.  Return negative, zero, or positive if the first
+** is less than, equal to, or greater than the second, respectively.
+** If one blob is a prefix of the other, then the shorter is the lessor.
+*/
+static SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){
+  int c = memcmp(pB1->z, pB2->z, pB1->n>pB2->n ? pB2->n : pB1->n);
+  if( c ) return c;
+  return pB1->n - pB2->n;
+}
+
+
+/*
 ** Compare the values contained by the two memory cells, returning
 ** negative, zero or positive if pMem1 is less than, equal to, or greater
 ** than pMem2. Sorting order is NULL's first, followed by numbers (integers
@@ -65494,7 +68234,6 @@ static int vdbeCompareMemString(
 ** Two NULL values are considered equal by this function.
 */
 SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const CollSeq *pColl){
-  int rc;
   int f1, f2;
   int combined_flags;
 
@@ -65522,14 +68261,14 @@ SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const C
       return 0;
     }
     if( (f1&MEM_Real)!=0 ){
-      r1 = pMem1->r;
+      r1 = pMem1->u.r;
     }else if( (f1&MEM_Int)!=0 ){
       r1 = (double)pMem1->u.i;
     }else{
       return 1;
     }
     if( (f2&MEM_Real)!=0 ){
-      r2 = pMem2->r;
+      r2 = pMem2->u.r;
     }else if( (f2&MEM_Int)!=0 ){
       r2 = (double)pMem2->u.i;
     }else{
@@ -65562,18 +68301,14 @@ SQLITE_PRIVATE int sqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const C
     assert( !pColl || pColl->xCmp );
 
     if( pColl ){
-      return vdbeCompareMemString(pMem1, pMem2, pColl);
+      return vdbeCompareMemString(pMem1, pMem2, pColl, 0);
     }
     /* If a NULL pointer was passed as the collate function, fall through
     ** to the blob case and use memcmp().  */
   }
  
   /* Both values must be blobs.  Compare using memcmp().  */
-  rc = memcmp(pMem1->z, pMem2->z, (pMem1->n>pMem2->n)?pMem2->n:pMem1->n);
-  if( rc==0 ){
-    rc = pMem1->n - pMem2->n;
-  }
-  return rc;
+  return sqlite3BlobCompare(pMem1, pMem2);
 }
 
 
@@ -65623,7 +68358,7 @@ static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){
 ** specified by {nKey1, pKey1} and pPKey2.  It returns a negative, zero
 ** or positive integer if key1 is less than, equal to or 
 ** greater than key2.  The {nKey1, pKey1} key must be a blob
-** created by th OP_MakeRecord opcode of the VDBE.  The pPKey2
+** created by the OP_MakeRecord opcode of the VDBE.  The pPKey2
 ** key must be a parsed key such as obtained from
 ** sqlite3VdbeParseRecord.
 **
@@ -65634,10 +68369,12 @@ static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){
 ** fields that appear in both keys are equal, then pPKey2->default_rc is 
 ** returned.
 **
-** If database corruption is discovered, set pPKey2->isCorrupt to non-zero
-** and return 0.
+** If database corruption is discovered, set pPKey2->errCode to 
+** SQLITE_CORRUPT and return 0. If an OOM error is encountered, 
+** pPKey2->errCode is set to SQLITE_NOMEM and, if it is not NULL, the
+** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db).
 */
-SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
+SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(
   int nKey1, const void *pKey1,   /* Left key */
   UnpackedRecord *pPKey2,         /* Right key */
   int bSkip                       /* If true, skip the first field */
@@ -65666,13 +68403,13 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
     idx1 = getVarint32(aKey1, szHdr1);
     d1 = szHdr1;
     if( d1>(unsigned)nKey1 ){ 
-      pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT;
+      pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
       return 0;  /* Corruption */
     }
     i = 0;
   }
 
-  VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */
+  VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */
   assert( pPKey2->pKeyInfo->nField+pPKey2->pKeyInfo->nXField>=pPKey2->nField 
        || CORRUPT_DB );
   assert( pPKey2->pKeyInfo->aSortOrder!=0 );
@@ -65692,9 +68429,9 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
       }else if( serial_type==7 ){
         double rhs = (double)pRhs->u.i;
         sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
-        if( mem1.r<rhs ){
+        if( mem1.u.r<rhs ){
           rc = -1;
-        }else if( mem1.r>rhs ){
+        }else if( mem1.u.r>rhs ){
           rc = +1;
         }
       }else{
@@ -65716,11 +68453,11 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
       }else if( serial_type==0 ){
         rc = -1;
       }else{
-        double rhs = pRhs->r;
+        double rhs = pRhs->u.r;
         double lhs;
         sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1);
         if( serial_type==7 ){
-          lhs = mem1.r;
+          lhs = mem1.u.r;
         }else{
           lhs = (double)mem1.u.i;
         }
@@ -65745,14 +68482,16 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
         testcase( (d1+mem1.n)==(unsigned)nKey1 );
         testcase( (d1+mem1.n+1)==(unsigned)nKey1 );
         if( (d1+mem1.n) > (unsigned)nKey1 ){
-          pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT;
+          pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
           return 0;                /* Corruption */
         }else if( pKeyInfo->aColl[i] ){
           mem1.enc = pKeyInfo->enc;
           mem1.db = pKeyInfo->db;
           mem1.flags = MEM_Str;
           mem1.z = (char*)&aKey1[d1];
-          rc = vdbeCompareMemString(&mem1, pRhs, pKeyInfo->aColl[i]);
+          rc = vdbeCompareMemString(
+              &mem1, pRhs, pKeyInfo->aColl[i], &pPKey2->errCode
+          );
         }else{
           int nCmp = MIN(mem1.n, pRhs->n);
           rc = memcmp(&aKey1[d1], pRhs->z, nCmp);
@@ -65772,7 +68511,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
         testcase( (d1+nStr)==(unsigned)nKey1 );
         testcase( (d1+nStr+1)==(unsigned)nKey1 );
         if( (d1+nStr) > (unsigned)nKey1 ){
-          pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT;
+          pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
           return 0;                /* Corruption */
         }else{
           int nCmp = MIN(nStr, pRhs->n);
@@ -65792,12 +68531,8 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
       if( pKeyInfo->aSortOrder[i] ){
         rc = -rc;
       }
-      assert( CORRUPT_DB
-          || (rc<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0)
-          || (rc>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0)
-          || pKeyInfo->db->mallocFailed
-      );
-      assert( mem1.zMalloc==0 );  /* See comment below */
+      assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) );
+      assert( mem1.szMalloc==0 );  /* See comment below */
       return rc;
     }
 
@@ -65810,17 +68545,24 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
   /* No memory allocation is ever used on mem1.  Prove this using
   ** the following assert().  If the assert() fails, it indicates a
   ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1).  */
-  assert( mem1.zMalloc==0 );
+  assert( mem1.szMalloc==0 );
 
   /* rc==0 here means that one or both of the keys ran out of fields and
-  ** all the fields up to that point were equal. Return the the default_rc
+  ** all the fields up to that point were equal. Return the default_rc
   ** value.  */
   assert( CORRUPT_DB 
-       || pPKey2->default_rc==vdbeRecordCompareDebug(nKey1, pKey1, pPKey2) 
+       || vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc) 
        || pKeyInfo->db->mallocFailed
   );
   return pPKey2->default_rc;
 }
+SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
+  int nKey1, const void *pKey1,   /* Left key */
+  UnpackedRecord *pPKey2          /* Right key */
+){
+  return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0);
+}
+
 
 /*
 ** This function is an optimized version of sqlite3VdbeRecordCompare() 
@@ -65833,8 +68575,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
 */
 static int vdbeRecordCompareInt(
   int nKey1, const void *pKey1, /* Left key */
-  UnpackedRecord *pPKey2,       /* Right key */
-  int bSkip                     /* Ignored */
+  UnpackedRecord *pPKey2        /* Right key */
 ){
   const u8 *aKey = &((const u8*)pKey1)[*(const u8*)pKey1 & 0x3F];
   int serial_type = ((const u8*)pKey1)[1];
@@ -65843,9 +68584,8 @@ static int vdbeRecordCompareInt(
   u64 x;
   i64 v = pPKey2->aMem[0].u.i;
   i64 lhs;
-  UNUSED_PARAMETER(bSkip);
 
-  assert( bSkip==0 );
+  vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
   assert( (*(u8*)pKey1)<=0x3F || CORRUPT_DB );
   switch( serial_type ){
     case 1: { /* 1-byte signed integer */
@@ -65895,10 +68635,10 @@ static int vdbeRecordCompareInt(
     ** (as gcc is clever enough to combine the two like cases). Other 
     ** compilers might be similar.  */ 
     case 0: case 7:
-      return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2, 0);
+      return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2);
 
     default:
-      return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2, 0);
+      return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2);
   }
 
   if( v>lhs ){
@@ -65908,18 +68648,14 @@ static int vdbeRecordCompareInt(
   }else if( pPKey2->nField>1 ){
     /* The first fields of the two keys are equal. Compare the trailing 
     ** fields.  */
-    res = sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2, 1);
+    res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
   }else{
     /* The first fields of the two keys are equal and there are no trailing
     ** fields. Return pPKey2->default_rc in this case. */
     res = pPKey2->default_rc;
   }
 
-  assert( (res==0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)==0)
-       || (res<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0)
-       || (res>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0)
-       || CORRUPT_DB
-  );
+  assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res) );
   return res;
 }
 
@@ -65931,17 +68667,14 @@ static int vdbeRecordCompareInt(
 */
 static int vdbeRecordCompareString(
   int nKey1, const void *pKey1, /* Left key */
-  UnpackedRecord *pPKey2,       /* Right key */
-  int bSkip
+  UnpackedRecord *pPKey2        /* Right key */
 ){
   const u8 *aKey1 = (const u8*)pKey1;
   int serial_type;
   int res;
-  UNUSED_PARAMETER(bSkip);
 
-  assert( bSkip==0 );
+  vdbeAssertFieldCountWithinLimits(nKey1, pKey1, pPKey2->pKeyInfo);
   getVarint32(&aKey1[1], serial_type);
-
   if( serial_type<12 ){
     res = pPKey2->r1;      /* (pKey1/nKey1) is a number or a null */
   }else if( !(serial_type & 0x01) ){ 
@@ -65953,7 +68686,7 @@ static int vdbeRecordCompareString(
 
     nStr = (serial_type-12) / 2;
     if( (szHdr + nStr) > nKey1 ){
-      pPKey2->isCorrupt = (u8)SQLITE_CORRUPT_BKPT;
+      pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT;
       return 0;    /* Corruption */
     }
     nCmp = MIN( pPKey2->aMem[0].n, nStr );
@@ -65963,7 +68696,7 @@ static int vdbeRecordCompareString(
       res = nStr - pPKey2->aMem[0].n;
       if( res==0 ){
         if( pPKey2->nField>1 ){
-          res = sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2, 1);
+          res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1);
         }else{
           res = pPKey2->default_rc;
         }
@@ -65979,9 +68712,7 @@ static int vdbeRecordCompareString(
     }
   }
 
-  assert( (res==0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)==0)
-       || (res<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0)
-       || (res>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0)
+  assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, res)
        || CORRUPT_DB
        || pPKey2->pKeyInfo->db->mallocFailed
   );
@@ -66047,8 +68778,6 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
   u32 lenRowid;     /* Size of the rowid */
   Mem m, v;
 
-  UNUSED_PARAMETER(db);
-
   /* Get the size of the index entry.  Only indices entries of less
   ** than 2GiB are support - anything large must be database corruption.
   ** Any corruption is detected in sqlite3BtreeParseCellPtr(), though, so
@@ -66060,7 +68789,7 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
   assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey );
 
   /* Read in the complete content of the index entry */
-  memset(&m, 0, sizeof(m));
+  sqlite3VdbeMemInit(&m, db, 0);
   rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, 1, &m);
   if( rc ){
     return rc;
@@ -66103,7 +68832,7 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){
   /* Jump here if database corruption is detected after m has been
   ** allocated.  Free the m object and return SQLITE_CORRUPT. */
 idx_rowid_corruption:
-  testcase( m.zMalloc!=0 );
+  testcase( m.szMalloc!=0 );
   sqlite3VdbeMemRelease(&m);
   return SQLITE_CORRUPT_BKPT;
 }
@@ -66120,6 +68849,7 @@ idx_rowid_corruption:
 ** of the keys prior to the final rowid, not the entire key.
 */
 SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(
+  sqlite3 *db,                     /* Database connection */
   VdbeCursor *pC,                  /* The cursor to compare against */
   UnpackedRecord *pUnpacked,       /* Unpacked version of key */
   int *res                         /* Write the comparison result here */
@@ -66138,12 +68868,12 @@ SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(
     *res = 0;
     return SQLITE_CORRUPT_BKPT;
   }
-  memset(&m, 0, sizeof(m));
+  sqlite3VdbeMemInit(&m, db, 0);
   rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, (u32)nCellKey, 1, &m);
   if( rc ){
     return rc;
   }
-  *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked, 0);
+  *res = sqlite3VdbeRecordCompare(m.n, m.z, pUnpacked);
   sqlite3VdbeMemRelease(&m);
   return SQLITE_OK;
 }
@@ -66270,7 +69000,7 @@ SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe *p, sqlite3_vtab *pVtab){
 ** collating sequences are registered or if an authorizer function is
 ** added or changed.
 */
-SQLITE_API int sqlite3_expired(sqlite3_stmt *pStmt){
+SQLITE_API int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt *pStmt){
   Vdbe *p = (Vdbe*)pStmt;
   return p==0 || p->expired;
 }
@@ -66307,7 +69037,7 @@ static int vdbeSafetyNotNull(Vdbe *p){
 ** This routine sets the error code and string returned by
 ** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
 */
-SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){
+SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt){
   int rc;
   if( pStmt==0 ){
     /* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL
@@ -66333,7 +69063,7 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){
 ** This routine sets the error code and string returned by
 ** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16().
 */
-SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt){
+SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt){
   int rc;
   if( pStmt==0 ){
     rc = SQLITE_OK;
@@ -66352,7 +69082,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt){
 /*
 ** Set all the parameters in the compiled SQL statement to NULL.
 */
-SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
+SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt *pStmt){
   int i;
   int rc = SQLITE_OK;
   Vdbe *p = (Vdbe*)pStmt;
@@ -66376,7 +69106,7 @@ SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){
 ** The following routines extract information from a Mem or sqlite3_value
 ** structure.
 */
-SQLITE_API const void *sqlite3_value_blob(sqlite3_value *pVal){
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value *pVal){
   Mem *p = (Mem*)pVal;
   if( p->flags & (MEM_Blob|MEM_Str) ){
     sqlite3VdbeMemExpandBlob(p);
@@ -66386,36 +69116,40 @@ SQLITE_API const void *sqlite3_value_blob(sqlite3_value *pVal){
     return sqlite3_value_text(pVal);
   }
 }
-SQLITE_API int sqlite3_value_bytes(sqlite3_value *pVal){
+SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value *pVal){
   return sqlite3ValueBytes(pVal, SQLITE_UTF8);
 }
-SQLITE_API int sqlite3_value_bytes16(sqlite3_value *pVal){
+SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value *pVal){
   return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE);
 }
-SQLITE_API double sqlite3_value_double(sqlite3_value *pVal){
+SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value *pVal){
   return sqlite3VdbeRealValue((Mem*)pVal);
 }
-SQLITE_API int sqlite3_value_int(sqlite3_value *pVal){
+SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value *pVal){
   return (int)sqlite3VdbeIntValue((Mem*)pVal);
 }
-SQLITE_API sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){
+SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value *pVal){
   return sqlite3VdbeIntValue((Mem*)pVal);
 }
-SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
+SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value *pVal){
   return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8);
 }
 #ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_value_text16(sqlite3_value* pVal){
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value* pVal){
   return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
 }
-SQLITE_API const void *sqlite3_value_text16be(sqlite3_value *pVal){
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value *pVal){
   return sqlite3ValueText(pVal, SQLITE_UTF16BE);
 }
-SQLITE_API const void *sqlite3_value_text16le(sqlite3_value *pVal){
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value *pVal){
   return sqlite3ValueText(pVal, SQLITE_UTF16LE);
 }
 #endif /* SQLITE_OMIT_UTF16 */
-SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){
+/* EVIDENCE-OF: R-12793-43283 Every value in SQLite has one of five
+** fundamental datatypes: 64-bit signed integer 64-bit IEEE floating
+** point number string BLOB NULL
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value* pVal){
   static const u8 aType[] = {
      SQLITE_BLOB,     /* 0x00 */
      SQLITE_NULL,     /* 0x01 */
@@ -66457,9 +69191,12 @@ SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){
 ** The following routines are used by user-defined functions to specify
 ** the function result.
 **
-** The setStrOrError() funtion calls sqlite3VdbeMemSetStr() to store the
+** The setStrOrError() function calls sqlite3VdbeMemSetStr() to store the
 ** result as a string or blob but if the string or blob is too large, it
 ** then sets the error code to SQLITE_TOOBIG
+**
+** The invokeValueDestructor(P,X) routine invokes destructor function X()
+** on value P is not going to be used and need to be destroyed.
 */
 static void setResultStrOrError(
   sqlite3_context *pCtx,  /* Function context */
@@ -66468,121 +69205,170 @@ static void setResultStrOrError(
   u8 enc,                 /* Encoding of z.  0 for BLOBs */
   void (*xDel)(void*)     /* Destructor function */
 ){
-  if( sqlite3VdbeMemSetStr(&pCtx->s, z, n, enc, xDel)==SQLITE_TOOBIG ){
+  if( sqlite3VdbeMemSetStr(pCtx->pOut, z, n, enc, xDel)==SQLITE_TOOBIG ){
     sqlite3_result_error_toobig(pCtx);
   }
 }
-SQLITE_API void sqlite3_result_blob(
+static int invokeValueDestructor(
+  const void *p,             /* Value to destroy */
+  void (*xDel)(void*),       /* The destructor */
+  sqlite3_context *pCtx      /* Set a SQLITE_TOOBIG error if no NULL */
+){
+  assert( xDel!=SQLITE_DYNAMIC );
+  if( xDel==0 ){
+    /* noop */
+  }else if( xDel==SQLITE_TRANSIENT ){
+    /* noop */
+  }else{
+    xDel((void*)p);
+  }
+  if( pCtx ) sqlite3_result_error_toobig(pCtx);
+  return SQLITE_TOOBIG;
+}
+SQLITE_API void SQLITE_STDCALL sqlite3_result_blob(
   sqlite3_context *pCtx, 
   const void *z, 
   int n, 
   void (*xDel)(void *)
 ){
   assert( n>=0 );
-  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
+  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   setResultStrOrError(pCtx, z, n, 0, xDel);
 }
-SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
-  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
-  sqlite3VdbeMemSetDouble(&pCtx->s, rVal);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64(
+  sqlite3_context *pCtx, 
+  const void *z, 
+  sqlite3_uint64 n,
+  void (*xDel)(void *)
+){
+  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+  assert( xDel!=SQLITE_DYNAMIC );
+  if( n>0x7fffffff ){
+    (void)invokeValueDestructor(z, xDel, pCtx);
+  }else{
+    setResultStrOrError(pCtx, z, (int)n, 0, xDel);
+  }
+}
+SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context *pCtx, double rVal){
+  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+  sqlite3VdbeMemSetDouble(pCtx->pOut, rVal);
 }
-SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
-  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
+  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   pCtx->isError = SQLITE_ERROR;
   pCtx->fErrorOrAux = 1;
-  sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
+  sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
 }
 #ifndef SQLITE_OMIT_UTF16
-SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
-  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
+  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   pCtx->isError = SQLITE_ERROR;
   pCtx->fErrorOrAux = 1;
-  sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
+  sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
 }
 #endif
-SQLITE_API void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
-  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
-  sqlite3VdbeMemSetInt64(&pCtx->s, (i64)iVal);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_int(sqlite3_context *pCtx, int iVal){
+  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+  sqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal);
 }
-SQLITE_API void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
-  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
-  sqlite3VdbeMemSetInt64(&pCtx->s, iVal);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){
+  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+  sqlite3VdbeMemSetInt64(pCtx->pOut, iVal);
 }
-SQLITE_API void sqlite3_result_null(sqlite3_context *pCtx){
-  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
-  sqlite3VdbeMemSetNull(&pCtx->s);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context *pCtx){
+  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+  sqlite3VdbeMemSetNull(pCtx->pOut);
 }
-SQLITE_API void sqlite3_result_text(
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text(
   sqlite3_context *pCtx, 
   const char *z, 
   int n,
   void (*xDel)(void *)
 ){
-  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
+  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel);
 }
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(
+  sqlite3_context *pCtx, 
+  const char *z, 
+  sqlite3_uint64 n,
+  void (*xDel)(void *),
+  unsigned char enc
+){
+  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+  assert( xDel!=SQLITE_DYNAMIC );
+  if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE;
+  if( n>0x7fffffff ){
+    (void)invokeValueDestructor(z, xDel, pCtx);
+  }else{
+    setResultStrOrError(pCtx, z, (int)n, enc, xDel);
+  }
+}
 #ifndef SQLITE_OMIT_UTF16
-SQLITE_API void sqlite3_result_text16(
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(
   sqlite3_context *pCtx, 
   const void *z, 
   int n, 
   void (*xDel)(void *)
 ){
-  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
+  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel);
 }
-SQLITE_API void sqlite3_result_text16be(
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(
   sqlite3_context *pCtx, 
   const void *z, 
   int n, 
   void (*xDel)(void *)
 ){
-  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
+  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel);
 }
-SQLITE_API void sqlite3_result_text16le(
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(
   sqlite3_context *pCtx, 
   const void *z, 
   int n, 
   void (*xDel)(void *)
 ){
-  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
+  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel);
 }
 #endif /* SQLITE_OMIT_UTF16 */
-SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
-  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
-  sqlite3VdbeMemCopy(&pCtx->s, pValue);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){
+  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+  sqlite3VdbeMemCopy(pCtx->pOut, pValue);
 }
-SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
-  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
-  sqlite3VdbeMemSetZeroBlob(&pCtx->s, n);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){
+  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+  sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n);
 }
-SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
   pCtx->isError = errCode;
   pCtx->fErrorOrAux = 1;
-  if( pCtx->s.flags & MEM_Null ){
-    sqlite3VdbeMemSetStr(&pCtx->s, sqlite3ErrStr(errCode), -1, 
+#ifdef SQLITE_DEBUG
+  if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
+#endif
+  if( pCtx->pOut->flags & MEM_Null ){
+    sqlite3VdbeMemSetStr(pCtx->pOut, sqlite3ErrStr(errCode), -1, 
                          SQLITE_UTF8, SQLITE_STATIC);
   }
 }
 
 /* Force an SQLITE_TOOBIG error. */
-SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){
-  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context *pCtx){
+  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   pCtx->isError = SQLITE_TOOBIG;
   pCtx->fErrorOrAux = 1;
-  sqlite3VdbeMemSetStr(&pCtx->s, "string or blob too big", -1, 
+  sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1, 
                        SQLITE_UTF8, SQLITE_STATIC);
 }
 
 /* An SQLITE_NOMEM error. */
-SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){
-  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
-  sqlite3VdbeMemSetNull(&pCtx->s);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context *pCtx){
+  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+  sqlite3VdbeMemSetNull(pCtx->pOut);
   pCtx->isError = SQLITE_NOMEM;
   pCtx->fErrorOrAux = 1;
-  pCtx->s.db->mallocFailed = 1;
+  pCtx->pOut->db->mallocFailed = 1;
 }
 
 /*
@@ -66596,7 +69382,10 @@ static int doWalCallbacks(sqlite3 *db){
   for(i=0; i<db->nDb; i++){
     Btree *pBt = db->aDb[i].pBt;
     if( pBt ){
-      int nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt));
+      int nEntry;
+      sqlite3BtreeEnter(pBt);
+      nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt));
+      sqlite3BtreeLeave(pBt);
       if( db->xWalCallback && nEntry>0 && rc==SQLITE_OK ){
         rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zName, nEntry);
       }
@@ -66638,7 +69427,7 @@ static int sqlite3Step(Vdbe *p){
     ** or SQLITE_BUSY error.
     */
 #ifdef SQLITE_OMIT_AUTORESET
-    if( p->rc==SQLITE_BUSY || p->rc==SQLITE_LOCKED ){
+    if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){
       sqlite3_reset((sqlite3_stmt*)p);
     }else{
       return SQLITE_MISUSE_BKPT;
@@ -66684,6 +69473,9 @@ static int sqlite3Step(Vdbe *p){
     if( p->bIsReader ) db->nVdbeRead++;
     p->pc = 0;
   }
+#ifdef SQLITE_DEBUG
+  p->rcApp = SQLITE_OK;
+#endif
 #ifndef SQLITE_OMIT_EXPLAIN
   if( p->explain ){
     rc = sqlite3VdbeList(p);
@@ -66728,7 +69520,7 @@ end_of_step:
   assert( rc==SQLITE_ROW  || rc==SQLITE_DONE   || rc==SQLITE_ERROR 
        || rc==SQLITE_BUSY || rc==SQLITE_MISUSE
   );
-  assert( p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE );
+  assert( (p->rc!=SQLITE_ROW && p->rc!=SQLITE_DONE) || p->rc==p->rcApp );
   if( p->isPrepareV2 && rc!=SQLITE_ROW && rc!=SQLITE_DONE ){
     /* If this statement was prepared using sqlite3_prepare_v2(), and an
     ** error has occurred, then return the error code in p->rc to the
@@ -66744,7 +69536,7 @@ end_of_step:
 ** sqlite3Step() to do most of the work.  If a schema error occurs,
 ** call sqlite3Reprepare() and try again.
 */
-SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
+SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt *pStmt){
   int rc = SQLITE_OK;      /* Result from sqlite3Step() */
   int rc2 = SQLITE_OK;     /* Result from sqlite3Reprepare() */
   Vdbe *v = (Vdbe*)pStmt;  /* the prepared statement */
@@ -66758,10 +69550,12 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
   sqlite3_mutex_enter(db->mutex);
   v->doingRerun = 0;
   while( (rc = sqlite3Step(v))==SQLITE_SCHEMA
-         && cnt++ < SQLITE_MAX_SCHEMA_RETRY
-         && (rc2 = rc = sqlite3Reprepare(v))==SQLITE_OK ){
+         && cnt++ < SQLITE_MAX_SCHEMA_RETRY ){
+    int savedPc = v->pc;
+    rc2 = rc = sqlite3Reprepare(v);
+    if( rc!=SQLITE_OK) break;
     sqlite3_reset(pStmt);
-    v->doingRerun = 1;
+    if( savedPc>=0 ) v->doingRerun = 1;
     assert( v->expired==0 );
   }
   if( rc2!=SQLITE_OK ){
@@ -66774,7 +69568,6 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
     ** sqlite3_errmsg() and sqlite3_errcode().
     */
     const char *zErr = (const char *)sqlite3_value_text(db->pErr); 
-    assert( zErr!=0 || db->mallocFailed );
     sqlite3DbFree(db, v->zErrMsg);
     if( !db->mallocFailed ){
       v->zErrMsg = sqlite3DbStrDup(db, zErr);
@@ -66794,7 +69587,7 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){
 ** Extract the user data from a sqlite3_context structure and return a
 ** pointer to it.
 */
-SQLITE_API void *sqlite3_user_data(sqlite3_context *p){
+SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context *p){
   assert( p && p->pFunc );
   return p->pFunc->pUserData;
 }
@@ -66809,22 +69602,32 @@ SQLITE_API void *sqlite3_user_data(sqlite3_context *p){
 ** sqlite3_create_function16() routines that originally registered the
 ** application defined function.
 */
-SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
+SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context *p){
   assert( p && p->pFunc );
-  return p->s.db;
+  return p->pOut->db;
 }
 
 /*
-** Return the current time for a statement
+** Return the current time for a statement.  If the current time
+** is requested more than once within the same run of a single prepared
+** statement, the exact same time is returned for each invocation regardless
+** of the amount of time that elapses between invocations.  In other words,
+** the time returned is always the time of the first call.
 */
 SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){
-  Vdbe *v = p->pVdbe;
   int rc;
-  if( v->iCurrentTime==0 ){
-    rc = sqlite3OsCurrentTimeInt64(p->s.db->pVfs, &v->iCurrentTime);
-    if( rc ) v->iCurrentTime = 0;
+#ifndef SQLITE_ENABLE_STAT3_OR_STAT4
+  sqlite3_int64 *piTime = &p->pVdbe->iCurrentTime;
+  assert( p->pVdbe!=0 );
+#else
+  sqlite3_int64 iTime = 0;
+  sqlite3_int64 *piTime = p->pVdbe!=0 ? &p->pVdbe->iCurrentTime : &iTime;
+#endif
+  if( *piTime==0 ){
+    rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, piTime);
+    if( rc ) *piTime = 0;
   }
-  return v->iCurrentTime;
+  return *piTime;
 }
 
 /*
@@ -66850,41 +69653,55 @@ SQLITE_PRIVATE void sqlite3InvalidFunction(
 }
 
 /*
+** Create a new aggregate context for p and return a pointer to
+** its pMem->z element.
+*/
+static SQLITE_NOINLINE void *createAggContext(sqlite3_context *p, int nByte){
+  Mem *pMem = p->pMem;
+  assert( (pMem->flags & MEM_Agg)==0 );
+  if( nByte<=0 ){
+    sqlite3VdbeMemSetNull(pMem);
+    pMem->z = 0;
+  }else{
+    sqlite3VdbeMemClearAndResize(pMem, nByte);
+    pMem->flags = MEM_Agg;
+    pMem->u.pDef = p->pFunc;
+    if( pMem->z ){
+      memset(pMem->z, 0, nByte);
+    }
+  }
+  return (void*)pMem->z;
+}
+
+/*
 ** Allocate or return the aggregate context for a user function.  A new
 ** context is allocated on the first call.  Subsequent calls return the
 ** same context that was returned on prior calls.
 */
-SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){
-  Mem *pMem;
+SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context *p, int nByte){
   assert( p && p->pFunc && p->pFunc->xStep );
-  assert( sqlite3_mutex_held(p->s.db->mutex) );
-  pMem = p->pMem;
+  assert( sqlite3_mutex_held(p->pOut->db->mutex) );
   testcase( nByte<0 );
-  if( (pMem->flags & MEM_Agg)==0 ){
-    if( nByte<=0 ){
-      sqlite3VdbeMemReleaseExternal(pMem);
-      pMem->flags = MEM_Null;
-      pMem->z = 0;
-    }else{
-      sqlite3VdbeMemGrow(pMem, nByte, 0);
-      pMem->flags = MEM_Agg;
-      pMem->u.pDef = p->pFunc;
-      if( pMem->z ){
-        memset(pMem->z, 0, nByte);
-      }
-    }
+  if( (p->pMem->flags & MEM_Agg)==0 ){
+    return createAggContext(p, nByte);
+  }else{
+    return (void*)p->pMem->z;
   }
-  return (void*)pMem->z;
 }
 
 /*
-** Return the auxilary data pointer, if any, for the iArg'th argument to
+** Return the auxiliary data pointer, if any, for the iArg'th argument to
 ** the user-function defined by pCtx.
 */
-SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
+SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
   AuxData *pAuxData;
 
-  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
+  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
+#if SQLITE_ENABLE_STAT3_OR_STAT4
+  if( pCtx->pVdbe==0 ) return 0;
+#else
+  assert( pCtx->pVdbe!=0 );
+#endif
   for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
     if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
   }
@@ -66893,11 +69710,11 @@ SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
 }
 
 /*
-** Set the auxilary data pointer and delete function, for the iArg'th
+** Set the auxiliary data pointer and delete function, for the iArg'th
 ** argument to the user-function defined by pCtx. Any previous value is
 ** deleted by calling the delete function specified when it was set.
 */
-SQLITE_API void sqlite3_set_auxdata(
+SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata(
   sqlite3_context *pCtx, 
   int iArg, 
   void *pAux, 
@@ -66906,8 +69723,13 @@ SQLITE_API void sqlite3_set_auxdata(
   AuxData *pAuxData;
   Vdbe *pVdbe = pCtx->pVdbe;
 
-  assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
+  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   if( iArg<0 ) goto failed;
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+  if( pVdbe==0 ) goto failed;
+#else
+  assert( pVdbe!=0 );
+#endif
 
   for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
     if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
@@ -66939,7 +69761,7 @@ failed:
 
 #ifndef SQLITE_OMIT_DEPRECATED
 /*
-** Return the number of times the Step function of a aggregate has been 
+** Return the number of times the Step function of an aggregate has been 
 ** called.
 **
 ** This function is deprecated.  Do not use it for new code.  It is
@@ -66947,7 +69769,7 @@ failed:
 ** implementations should keep their own counts within their aggregate
 ** context.
 */
-SQLITE_API int sqlite3_aggregate_count(sqlite3_context *p){
+SQLITE_API int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context *p){
   assert( p && p->pMem && p->pFunc && p->pFunc->xStep );
   return p->pMem->n;
 }
@@ -66956,7 +69778,7 @@ SQLITE_API int sqlite3_aggregate_count(sqlite3_context *p){
 /*
 ** Return the number of columns in the result set for the statement pStmt.
 */
-SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){
+SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt){
   Vdbe *pVm = (Vdbe *)pStmt;
   return pVm ? pVm->nResColumn : 0;
 }
@@ -66965,7 +69787,7 @@ SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){
 ** Return the number of values available from the current row of the
 ** currently executing statement pStmt.
 */
-SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt){
+SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt){
   Vdbe *pVm = (Vdbe *)pStmt;
   if( pVm==0 || pVm->pResultSet==0 ) return 0;
   return pVm->nResColumn;
@@ -66988,11 +69810,22 @@ static const Mem *columnNullValue(void){
 #if defined(SQLITE_DEBUG) && defined(__GNUC__)
     __attribute__((aligned(8))) 
 #endif
-    = {0, "", (double)0, {0}, 0, MEM_Null, 0,
+    = {
+        /* .u          = */ {0},
+        /* .flags      = */ MEM_Null,
+        /* .enc        = */ 0,
+        /* .n          = */ 0,
+        /* .z          = */ 0,
+        /* .zMalloc    = */ 0,
+        /* .szMalloc   = */ 0,
+        /* .iPadding1  = */ 0,
+        /* .db         = */ 0,
+        /* .xDel       = */ 0,
 #ifdef SQLITE_DEBUG
-       0, 0,  /* pScopyFrom, pFiller */
+        /* .pScopyFrom = */ 0,
+        /* .pFiller    = */ 0,
 #endif
-       0, 0 };
+      };
   return &nullMem;
 }
 
@@ -67013,7 +69846,7 @@ static Mem *columnMem(sqlite3_stmt *pStmt, int i){
   }else{
     if( pVm && ALWAYS(pVm->db) ){
       sqlite3_mutex_enter(pVm->db->mutex);
-      sqlite3Error(pVm->db, SQLITE_RANGE, 0);
+      sqlite3Error(pVm->db, SQLITE_RANGE);
     }
     pOut = (Mem*)columnNullValue();
   }
@@ -67056,7 +69889,7 @@ static void columnMallocFailure(sqlite3_stmt *pStmt)
 ** The following routines are used to access elements of the current row
 ** in the result set.
 */
-SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt *pStmt, int i){
   const void *val;
   val = sqlite3_value_blob( columnMem(pStmt,i) );
   /* Even though there is no encoding conversion, value_blob() might
@@ -67066,37 +69899,37 @@ SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){
   columnMallocFailure(pStmt);
   return val;
 }
-SQLITE_API int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
+SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){
   int val = sqlite3_value_bytes( columnMem(pStmt,i) );
   columnMallocFailure(pStmt);
   return val;
 }
-SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){
+SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){
   int val = sqlite3_value_bytes16( columnMem(pStmt,i) );
   columnMallocFailure(pStmt);
   return val;
 }
-SQLITE_API double sqlite3_column_double(sqlite3_stmt *pStmt, int i){
+SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt *pStmt, int i){
   double val = sqlite3_value_double( columnMem(pStmt,i) );
   columnMallocFailure(pStmt);
   return val;
 }
-SQLITE_API int sqlite3_column_int(sqlite3_stmt *pStmt, int i){
+SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt *pStmt, int i){
   int val = sqlite3_value_int( columnMem(pStmt,i) );
   columnMallocFailure(pStmt);
   return val;
 }
-SQLITE_API sqlite_int64 sqlite3_column_int64(sqlite3_stmt *pStmt, int i){
+SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_column_int64(sqlite3_stmt *pStmt, int i){
   sqlite_int64 val = sqlite3_value_int64( columnMem(pStmt,i) );
   columnMallocFailure(pStmt);
   return val;
 }
-SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){
+SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt *pStmt, int i){
   const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) );
   columnMallocFailure(pStmt);
   return val;
 }
-SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){
+SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt *pStmt, int i){
   Mem *pOut = columnMem(pStmt, i);
   if( pOut->flags&MEM_Static ){
     pOut->flags &= ~MEM_Static;
@@ -67106,13 +69939,13 @@ SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){
   return (sqlite3_value *)pOut;
 }
 #ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_text16(sqlite3_stmt *pStmt, int i){
   const void *val = sqlite3_value_text16( columnMem(pStmt,i) );
   columnMallocFailure(pStmt);
   return val;
 }
 #endif /* SQLITE_OMIT_UTF16 */
-SQLITE_API int sqlite3_column_type(sqlite3_stmt *pStmt, int i){
+SQLITE_API int SQLITE_STDCALL sqlite3_column_type(sqlite3_stmt *pStmt, int i){
   int iType = sqlite3_value_type( columnMem(pStmt,i) );
   columnMallocFailure(pStmt);
   return iType;
@@ -67140,11 +69973,19 @@ static const void *columnName(
   const void *(*xFunc)(Mem*),
   int useType
 ){
-  const void *ret = 0;
-  Vdbe *p = (Vdbe *)pStmt;
+  const void *ret;
+  Vdbe *p;
   int n;
-  sqlite3 *db = p->db;
-  
+  sqlite3 *db;
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( pStmt==0 ){
+    (void)SQLITE_MISUSE_BKPT;
+    return 0;
+  }
+#endif
+  ret = 0;
+  p = (Vdbe *)pStmt;
+  db = p->db;
   assert( db!=0 );
   n = sqlite3_column_count(pStmt);
   if( N<n && N>=0 ){
@@ -67168,12 +70009,12 @@ static const void *columnName(
 ** Return the name of the Nth column of the result set returned by SQL
 ** statement pStmt.
 */
-SQLITE_API const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_name(sqlite3_stmt *pStmt, int N){
   return columnName(
       pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_NAME);
 }
 #ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
   return columnName(
       pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_NAME);
 }
@@ -67193,12 +70034,12 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){
 ** Return the column declaration type (if applicable) of the 'i'th column
 ** of the result set of SQL statement pStmt.
 */
-SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){
   return columnName(
       pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DECLTYPE);
 }
 #ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
   return columnName(
       pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DECLTYPE);
 }
@@ -67209,14 +70050,14 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){
 /*
 ** Return the name of the database from which a result column derives.
 ** NULL is returned if the result column is an expression or constant or
-** anything else which is not an unabiguous reference to a database column.
+** anything else which is not an unambiguous reference to a database column.
 */
-SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){
   return columnName(
       pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_DATABASE);
 }
 #ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){
   return columnName(
       pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_DATABASE);
 }
@@ -67225,14 +70066,14 @@ SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N
 /*
 ** Return the name of the table from which a result column derives.
 ** NULL is returned if the result column is an expression or constant or
-** anything else which is not an unabiguous reference to a database column.
+** anything else which is not an unambiguous reference to a database column.
 */
-SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){
   return columnName(
       pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_TABLE);
 }
 #ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
   return columnName(
       pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_TABLE);
 }
@@ -67241,14 +70082,14 @@ SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){
 /*
 ** Return the name of the table column from which a result column derives.
 ** NULL is returned if the result column is an expression or constant or
-** anything else which is not an unabiguous reference to a database column.
+** anything else which is not an unambiguous reference to a database column.
 */
-SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){
   return columnName(
       pStmt, N, (const void*(*)(Mem*))sqlite3_value_text, COLNAME_COLUMN);
 }
 #ifndef SQLITE_OMIT_UTF16
-SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){
   return columnName(
       pStmt, N, (const void*(*)(Mem*))sqlite3_value_text16, COLNAME_COLUMN);
 }
@@ -67278,14 +70119,14 @@ static int vdbeUnbind(Vdbe *p, int i){
   }
   sqlite3_mutex_enter(p->db->mutex);
   if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){
-    sqlite3Error(p->db, SQLITE_MISUSE, 0);
+    sqlite3Error(p->db, SQLITE_MISUSE);
     sqlite3_mutex_leave(p->db->mutex);
     sqlite3_log(SQLITE_MISUSE, 
         "bind on a busy prepared statement: [%s]", p->zSql);
     return SQLITE_MISUSE_BKPT;
   }
   if( i<1 || i>p->nVar ){
-    sqlite3Error(p->db, SQLITE_RANGE, 0);
+    sqlite3Error(p->db, SQLITE_RANGE);
     sqlite3_mutex_leave(p->db->mutex);
     return SQLITE_RANGE;
   }
@@ -67293,7 +70134,7 @@ static int vdbeUnbind(Vdbe *p, int i){
   pVar = &p->aVar[i];
   sqlite3VdbeMemRelease(pVar);
   pVar->flags = MEM_Null;
-  sqlite3Error(p->db, SQLITE_OK, 0);
+  sqlite3Error(p->db, SQLITE_OK);
 
   /* If the bit corresponding to this variable in Vdbe.expmask is set, then 
   ** binding a new value to this variable invalidates the current query plan.
@@ -67335,7 +70176,7 @@ static int bindText(
       if( rc==SQLITE_OK && encoding!=0 ){
         rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db));
       }
-      sqlite3Error(p->db, rc, 0);
+      sqlite3Error(p->db, rc);
       rc = sqlite3ApiExit(p->db, rc);
     }
     sqlite3_mutex_leave(p->db->mutex);
@@ -67349,7 +70190,7 @@ static int bindText(
 /*
 ** Bind a blob value to an SQL statement variable.
 */
-SQLITE_API int sqlite3_bind_blob(
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(
   sqlite3_stmt *pStmt, 
   int i, 
   const void *zData, 
@@ -67358,7 +70199,21 @@ SQLITE_API int sqlite3_bind_blob(
 ){
   return bindText(pStmt, i, zData, nData, xDel, 0);
 }
-SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(
+  sqlite3_stmt *pStmt, 
+  int i, 
+  const void *zData, 
+  sqlite3_uint64 nData, 
+  void (*xDel)(void*)
+){
+  assert( xDel!=SQLITE_DYNAMIC );
+  if( nData>0x7fffffff ){
+    return invokeValueDestructor(zData, xDel, 0);
+  }else{
+    return bindText(pStmt, i, zData, (int)nData, xDel, 0);
+  }
+}
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
   int rc;
   Vdbe *p = (Vdbe *)pStmt;
   rc = vdbeUnbind(p, i);
@@ -67368,10 +70223,10 @@ SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){
   }
   return rc;
 }
-SQLITE_API int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){
   return sqlite3_bind_int64(p, i, (i64)iValue);
 }
-SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){
   int rc;
   Vdbe *p = (Vdbe *)pStmt;
   rc = vdbeUnbind(p, i);
@@ -67381,7 +70236,7 @@ SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValu
   }
   return rc;
 }
-SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
   int rc;
   Vdbe *p = (Vdbe*)pStmt;
   rc = vdbeUnbind(p, i);
@@ -67390,7 +70245,7 @@ SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){
   }
   return rc;
 }
-SQLITE_API int sqlite3_bind_text( 
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_text( 
   sqlite3_stmt *pStmt, 
   int i, 
   const char *zData, 
@@ -67399,8 +70254,24 @@ SQLITE_API int sqlite3_bind_text(
 ){
   return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8);
 }
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64( 
+  sqlite3_stmt *pStmt, 
+  int i, 
+  const char *zData, 
+  sqlite3_uint64 nData, 
+  void (*xDel)(void*),
+  unsigned char enc
+){
+  assert( xDel!=SQLITE_DYNAMIC );
+  if( nData>0x7fffffff ){
+    return invokeValueDestructor(zData, xDel, 0);
+  }else{
+    if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE;
+    return bindText(pStmt, i, zData, (int)nData, xDel, enc);
+  }
+}
 #ifndef SQLITE_OMIT_UTF16
-SQLITE_API int sqlite3_bind_text16(
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(
   sqlite3_stmt *pStmt, 
   int i, 
   const void *zData, 
@@ -67410,7 +70281,7 @@ SQLITE_API int sqlite3_bind_text16(
   return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE);
 }
 #endif /* SQLITE_OMIT_UTF16 */
-SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){
   int rc;
   switch( sqlite3_value_type((sqlite3_value*)pValue) ){
     case SQLITE_INTEGER: {
@@ -67418,7 +70289,7 @@ SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_valu
       break;
     }
     case SQLITE_FLOAT: {
-      rc = sqlite3_bind_double(pStmt, i, pValue->r);
+      rc = sqlite3_bind_double(pStmt, i, pValue->u.r);
       break;
     }
     case SQLITE_BLOB: {
@@ -67441,7 +70312,7 @@ SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_valu
   }
   return rc;
 }
-SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
   int rc;
   Vdbe *p = (Vdbe *)pStmt;
   rc = vdbeUnbind(p, i);
@@ -67456,7 +70327,7 @@ SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
 ** Return the number of wildcards that can be potentially bound to.
 ** This routine is added to support DBD::SQLite.  
 */
-SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
   Vdbe *p = (Vdbe*)pStmt;
   return p ? p->nVar : 0;
 }
@@ -67467,7 +70338,7 @@ SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){
 **
 ** The result is always UTF-8.
 */
-SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
+SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){
   Vdbe *p = (Vdbe*)pStmt;
   if( p==0 || i<1 || i>p->nzVar ){
     return 0;
@@ -67495,7 +70366,7 @@ SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nNa
   }
   return 0;
 }
-SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){
   return sqlite3VdbeParameterIndex((Vdbe*)pStmt, zName, sqlite3Strlen30(zName));
 }
 
@@ -67521,7 +70392,7 @@ SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *pFromStmt, sqlite3_stmt
 ** Deprecated external interface.  Internal/core SQLite code
 ** should call sqlite3TransferBindings.
 **
-** Is is misuse to call this routine with statements from different
+** It is misuse to call this routine with statements from different
 ** database connections.  But as this is a deprecated interface, we
 ** will not bother to check for that condition.
 **
@@ -67529,7 +70400,7 @@ SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *pFromStmt, sqlite3_stmt
 ** an SQLITE_ERROR is returned.  Nothing else can go wrong, so otherwise
 ** SQLITE_OK is returned.
 */
-SQLITE_API int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
+SQLITE_API int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){
   Vdbe *pFrom = (Vdbe*)pFromStmt;
   Vdbe *pTo = (Vdbe*)pToStmt;
   if( pFrom->nVar!=pTo->nVar ){
@@ -67551,7 +70422,7 @@ SQLITE_API int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *
 ** the first argument to the sqlite3_prepare() that was used to create
 ** the statement in the first place.
 */
-SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
+SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt *pStmt){
   return pStmt ? ((Vdbe*)pStmt)->db : 0;
 }
 
@@ -67559,14 +70430,14 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
 ** Return true if the prepared statement is guaranteed to not modify the
 ** database.
 */
-SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
+SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
   return pStmt ? ((Vdbe*)pStmt)->readOnly : 1;
 }
 
 /*
 ** Return true if the prepared statement is in need of being reset.
 */
-SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
+SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt *pStmt){
   Vdbe *v = (Vdbe*)pStmt;
   return v!=0 && v->pc>=0 && v->magic==VDBE_MAGIC_RUN;
 }
@@ -67577,8 +70448,14 @@ SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){
 ** prepared statement for the database connection.  Return NULL if there
 ** are no more.
 */
-SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
+SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
   sqlite3_stmt *pNext;
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !sqlite3SafetyCheckOk(pDb) ){
+    (void)SQLITE_MISUSE_BKPT;
+    return 0;
+  }
+#endif
   sqlite3_mutex_enter(pDb->mutex);
   if( pStmt==0 ){
     pNext = (sqlite3_stmt*)pDb->pVdbe;
@@ -67592,13 +70469,89 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
 /*
 ** Return the value of a status counter for a prepared statement
 */
-SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
+SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){
   Vdbe *pVdbe = (Vdbe*)pStmt;
-  u32 v = pVdbe->aCounter[op];
+  u32 v;
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !pStmt ){
+    (void)SQLITE_MISUSE_BKPT;
+    return 0;
+  }
+#endif
+  v = pVdbe->aCounter[op];
   if( resetFlag ) pVdbe->aCounter[op] = 0;
   return (int)v;
 }
 
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+/*
+** Return status data for a single loop within query pStmt.
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_stmt_scanstatus(
+  sqlite3_stmt *pStmt,            /* Prepared statement being queried */
+  int idx,                        /* Index of loop to report on */
+  int iScanStatusOp,              /* Which metric to return */
+  void *pOut                      /* OUT: Write the answer here */
+){
+  Vdbe *p = (Vdbe*)pStmt;
+  ScanStatus *pScan;
+  if( idx<0 || idx>=p->nScan ) return 1;
+  pScan = &p->aScan[idx];
+  switch( iScanStatusOp ){
+    case SQLITE_SCANSTAT_NLOOP: {
+      *(sqlite3_int64*)pOut = p->anExec[pScan->addrLoop];
+      break;
+    }
+    case SQLITE_SCANSTAT_NVISIT: {
+      *(sqlite3_int64*)pOut = p->anExec[pScan->addrVisit];
+      break;
+    }
+    case SQLITE_SCANSTAT_EST: {
+      double r = 1.0;
+      LogEst x = pScan->nEst;
+      while( x<100 ){
+        x += 10;
+        r *= 0.5;
+      }
+      *(double*)pOut = r*sqlite3LogEstToInt(x);
+      break;
+    }
+    case SQLITE_SCANSTAT_NAME: {
+      *(const char**)pOut = pScan->zName;
+      break;
+    }
+    case SQLITE_SCANSTAT_EXPLAIN: {
+      if( pScan->addrExplain ){
+        *(const char**)pOut = p->aOp[ pScan->addrExplain ].p4.z;
+      }else{
+        *(const char**)pOut = 0;
+      }
+      break;
+    }
+    case SQLITE_SCANSTAT_SELECTID: {
+      if( pScan->addrExplain ){
+        *(int*)pOut = p->aOp[ pScan->addrExplain ].p1;
+      }else{
+        *(int*)pOut = -1;
+      }
+      break;
+    }
+    default: {
+      return 1;
+    }
+  }
+  return 0;
+}
+
+/*
+** Zero all counters associated with the sqlite3_stmt_scanstatus() data.
+*/
+SQLITE_API void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){
+  Vdbe *p = (Vdbe*)pStmt;
+  memset(p->anExec, 0, p->nOp * sizeof(i64));
+}
+#endif /* SQLITE_ENABLE_STMT_SCANSTATUS */
+
 /************** End of vdbeapi.c *********************************************/
 /************** Begin file vdbetrace.c ***************************************/
 /*
@@ -67665,7 +70618,7 @@ static int findNextHostParameter(const char *zSql, int *pnToken){
 ** ALGORITHM:  Scan the input string looking for host parameters in any of
 ** these forms:  ?, ?N, $A, @A, :A.  Take care to avoid text within
 ** string literals, quoted identifier names, and comments.  For text forms,
-** the host parameter index is found by scanning the perpared
+** the host parameter index is found by scanning the prepared
 ** statement for the corresponding OP_Variable opcode.  Once the host
 ** parameter index is known, locate the value in p->aVar[].  Then render
 ** the value as a literal in place of the host parameter name.
@@ -67685,9 +70638,8 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
   char zBase[100];         /* Initial working space */
 
   db = p->db;
-  sqlite3StrAccumInit(&out, zBase, sizeof(zBase), 
+  sqlite3StrAccumInit(&out, db, zBase, sizeof(zBase), 
                       db->aLimit[SQLITE_LIMIT_LENGTH]);
-  out.db = db;
   if( db->nVdbeExec>1 ){
     while( *zRawSql ){
       const char *zStart = zRawSql;
@@ -67696,6 +70648,8 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
       assert( (zRawSql - zStart) > 0 );
       sqlite3StrAccumAppend(&out, zStart, (int)(zRawSql-zStart));
     }
+  }else if( p->nVar==0 ){
+    sqlite3StrAccumAppend(&out, zRawSql, sqlite3Strlen30(zRawSql));
   }else{
     while( zRawSql[0] ){
       n = findNextHostParameter(zRawSql, &nToken);
@@ -67712,10 +70666,12 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
           idx = nextIndex;
         }
       }else{
-        assert( zRawSql[0]==':' || zRawSql[0]=='$' || zRawSql[0]=='@' );
+        assert( zRawSql[0]==':' || zRawSql[0]=='$' ||
+                zRawSql[0]=='@' || zRawSql[0]=='#' );
         testcase( zRawSql[0]==':' );
         testcase( zRawSql[0]=='$' );
         testcase( zRawSql[0]=='@' );
+        testcase( zRawSql[0]=='#' );
         idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken);
         assert( idx>0 );
       }
@@ -67728,7 +70684,7 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
       }else if( pVar->flags & MEM_Int ){
         sqlite3XPrintf(&out, 0, "%lld", pVar->u.i);
       }else if( pVar->flags & MEM_Real ){
-        sqlite3XPrintf(&out, 0, "%!.15g", pVar->r);
+        sqlite3XPrintf(&out, 0, "%!.15g", pVar->u.r);
       }else if( pVar->flags & MEM_Str ){
         int nOut;  /* Number of bytes of the string text to include in output */
 #ifndef SQLITE_OMIT_UTF16
@@ -67785,121 +70741,6 @@ SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
 
 #endif /* #ifndef SQLITE_OMIT_TRACE */
 
-/*****************************************************************************
-** The following code implements the data-structure explaining logic
-** for the Vdbe.
-*/
-
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
-
-/*
-** Allocate a new Explain object
-*/
-SQLITE_PRIVATE void sqlite3ExplainBegin(Vdbe *pVdbe){
-  if( pVdbe ){
-    Explain *p;
-    sqlite3BeginBenignMalloc();
-    p = (Explain *)sqlite3MallocZero( sizeof(Explain) );
-    if( p ){
-      p->pVdbe = pVdbe;
-      sqlite3_free(pVdbe->pExplain);
-      pVdbe->pExplain = p;
-      sqlite3StrAccumInit(&p->str, p->zBase, sizeof(p->zBase),
-                          SQLITE_MAX_LENGTH);
-      p->str.useMalloc = 2;
-    }else{
-      sqlite3EndBenignMalloc();
-    }
-  }
-}
-
-/*
-** Return true if the Explain ends with a new-line.
-*/
-static int endsWithNL(Explain *p){
-  return p && p->str.zText && p->str.nChar
-           && p->str.zText[p->str.nChar-1]=='\n';
-}
-    
-/*
-** Append text to the indentation
-*/
-SQLITE_PRIVATE void sqlite3ExplainPrintf(Vdbe *pVdbe, const char *zFormat, ...){
-  Explain *p;
-  if( pVdbe && (p = pVdbe->pExplain)!=0 ){
-    va_list ap;
-    if( p->nIndent && endsWithNL(p) ){
-      int n = p->nIndent;
-      if( n>ArraySize(p->aIndent) ) n = ArraySize(p->aIndent);
-      sqlite3AppendSpace(&p->str, p->aIndent[n-1]);
-    }   
-    va_start(ap, zFormat);
-    sqlite3VXPrintf(&p->str, SQLITE_PRINTF_INTERNAL, zFormat, ap);
-    va_end(ap);
-  }
-}
-
-/*
-** Append a '\n' if there is not already one.
-*/
-SQLITE_PRIVATE void sqlite3ExplainNL(Vdbe *pVdbe){
-  Explain *p;
-  if( pVdbe && (p = pVdbe->pExplain)!=0 && !endsWithNL(p) ){
-    sqlite3StrAccumAppend(&p->str, "\n", 1);
-  }
-}
-
-/*
-** Push a new indentation level.  Subsequent lines will be indented
-** so that they begin at the current cursor position.
-*/
-SQLITE_PRIVATE void sqlite3ExplainPush(Vdbe *pVdbe){
-  Explain *p;
-  if( pVdbe && (p = pVdbe->pExplain)!=0 ){
-    if( p->str.zText && p->nIndent<ArraySize(p->aIndent) ){
-      const char *z = p->str.zText;
-      int i = p->str.nChar-1;
-      int x;
-      while( i>=0 && z[i]!='\n' ){ i--; }
-      x = (p->str.nChar - 1) - i;
-      if( p->nIndent && x<p->aIndent[p->nIndent-1] ){
-        x = p->aIndent[p->nIndent-1];
-      }
-      p->aIndent[p->nIndent] = x;
-    }
-    p->nIndent++;
-  }
-}
-
-/*
-** Pop the indentation stack by one level.
-*/
-SQLITE_PRIVATE void sqlite3ExplainPop(Vdbe *p){
-  if( p && p->pExplain ) p->pExplain->nIndent--;
-}
-
-/*
-** Free the indentation structure
-*/
-SQLITE_PRIVATE void sqlite3ExplainFinish(Vdbe *pVdbe){
-  if( pVdbe && pVdbe->pExplain ){
-    sqlite3_free(pVdbe->zExplain);
-    sqlite3ExplainNL(pVdbe);
-    pVdbe->zExplain = sqlite3StrAccumFinish(&pVdbe->pExplain->str);
-    sqlite3_free(pVdbe->pExplain);
-    pVdbe->pExplain = 0;
-    sqlite3EndBenignMalloc();
-  }
-}
-
-/*
-** Return the explanation of a virtual machine.
-*/
-SQLITE_PRIVATE const char *sqlite3VdbeExplanation(Vdbe *pVdbe){
-  return (pVdbe && pVdbe->zExplain) ? pVdbe->zExplain : 0;
-}
-#endif /* defined(SQLITE_DEBUG) */
-
 /************** End of vdbetrace.c *******************************************/
 /************** Begin file vdbe.c ********************************************/
 /*
@@ -68048,7 +70889,7 @@ SQLITE_API int sqlite3_found_count = 0;
 ** already. Return non-zero if a malloc() fails.
 */
 #define Stringify(P, enc) \
-   if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc)) \
+   if(((P)->flags&(MEM_Str|MEM_Blob))==0 && sqlite3VdbeMemStringify(P,enc,0)) \
      { goto no_mem; }
 
 /*
@@ -68111,11 +70952,12 @@ static VdbeCursor *allocateCursor(
     sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
     p->apCsr[iCur] = 0;
   }
-  if( SQLITE_OK==sqlite3VdbeMemGrow(pMem, nByte, 0) ){
+  if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){
     p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
     memset(pCx, 0, sizeof(VdbeCursor));
     pCx->iDb = iDb;
     pCx->nField = nField;
+    pCx->aOffset = &pCx->aType[nField];
     if( isBtreeCursor ){
       pCx->pCursor = (BtCursor*)
           &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField];
@@ -68130,23 +70972,31 @@ static VdbeCursor *allocateCursor(
 ** do so without loss of information.  In other words, if the string
 ** looks like a number, convert it into a number.  If it does not
 ** look like a number, leave it alone.
+**
+** If the bTryForInt flag is true, then extra effort is made to give
+** an integer representation.  Strings that look like floating point
+** values but which have no fractional component (example: '48.00')
+** will have a MEM_Int representation when bTryForInt is true.
+**
+** If bTryForInt is false, then if the input string contains a decimal
+** point or exponential notation, the result is only MEM_Real, even
+** if there is an exact integer representation of the quantity.
 */
-static void applyNumericAffinity(Mem *pRec){
+static void applyNumericAffinity(Mem *pRec, int bTryForInt){
   double rValue;
   i64 iValue;
   u8 enc = pRec->enc;
-  if( (pRec->flags&MEM_Str)==0 ) return;
+  assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real))==MEM_Str );
   if( sqlite3AtoF(pRec->z, &rValue, pRec->n, enc)==0 ) return;
   if( 0==sqlite3Atoi64(pRec->z, &iValue, pRec->n, enc) ){
     pRec->u.i = iValue;
     pRec->flags |= MEM_Int;
   }else{
-    pRec->r = rValue;
+    pRec->u.r = rValue;
     pRec->flags |= MEM_Real;
+    if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec);
   }
 }
-#define ApplyNumericAffinity(X)  \
-   if(((X)->flags&(MEM_Real|MEM_Int))==0){applyNumericAffinity(X);}
 
 /*
 ** Processing is determine by the affinity parameter:
@@ -68171,22 +71021,25 @@ static void applyAffinity(
   char affinity,      /* The affinity to be applied */
   u8 enc              /* Use this text encoding */
 ){
-  if( affinity==SQLITE_AFF_TEXT ){
+  if( affinity>=SQLITE_AFF_NUMERIC ){
+    assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL
+             || affinity==SQLITE_AFF_NUMERIC );
+    if( (pRec->flags & MEM_Int)==0 ){
+      if( (pRec->flags & MEM_Real)==0 ){
+        if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1);
+      }else{
+        sqlite3VdbeIntegerAffinity(pRec);
+      }
+    }
+  }else if( affinity==SQLITE_AFF_TEXT ){
     /* Only attempt the conversion to TEXT if there is an integer or real
     ** representation (blob and NULL do not get converted) but no string
     ** representation.
     */
     if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){
-      sqlite3VdbeMemStringify(pRec, enc);
+      sqlite3VdbeMemStringify(pRec, enc, 1);
     }
     pRec->flags &= ~(MEM_Real|MEM_Int);
-  }else if( affinity!=SQLITE_AFF_NONE ){
-    assert( affinity==SQLITE_AFF_INTEGER || affinity==SQLITE_AFF_REAL
-             || affinity==SQLITE_AFF_NUMERIC );
-    ApplyNumericAffinity(pRec);
-    if( pRec->flags & MEM_Real ){
-      sqlite3VdbeIntegerAffinity(pRec);
-    }
   }
 }
 
@@ -68196,11 +71049,11 @@ static void applyAffinity(
 ** is appropriate.  But only do the conversion if it is possible without
 ** loss of information and return the revised type of the argument.
 */
-SQLITE_API int sqlite3_value_numeric_type(sqlite3_value *pVal){
+SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value *pVal){
   int eType = sqlite3_value_type(pVal);
   if( eType==SQLITE_TEXT ){
     Mem *pMem = (Mem*)pVal;
-    applyNumericAffinity(pMem);
+    applyNumericAffinity(pMem, 0);
     eType = sqlite3_value_type(pVal);
   }
   return eType;
@@ -68219,24 +71072,36 @@ SQLITE_PRIVATE void sqlite3ValueApplyAffinity(
 }
 
 /*
+** pMem currently only holds a string type (or maybe a BLOB that we can
+** interpret as a string if we want to).  Compute its corresponding
+** numeric type, if has one.  Set the pMem->u.r and pMem->u.i fields
+** accordingly.
+*/
+static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){
+  assert( (pMem->flags & (MEM_Int|MEM_Real))==0 );
+  assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 );
+  if( sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc)==0 ){
+    return 0;
+  }
+  if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==SQLITE_OK ){
+    return MEM_Int;
+  }
+  return MEM_Real;
+}
+
+/*
 ** Return the numeric type for pMem, either MEM_Int or MEM_Real or both or
 ** none.  
 **
 ** Unlike applyNumericAffinity(), this routine does not modify pMem->flags.
-** But it does set pMem->r and pMem->u.i appropriately.
+** But it does set pMem->u.r and pMem->u.i appropriately.
 */
 static u16 numericType(Mem *pMem){
   if( pMem->flags & (MEM_Int|MEM_Real) ){
     return pMem->flags & (MEM_Int|MEM_Real);
   }
   if( pMem->flags & (MEM_Str|MEM_Blob) ){
-    if( sqlite3AtoF(pMem->z, &pMem->r, pMem->n, pMem->enc)==0 ){
-      return 0;
-    }
-    if( sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc)==SQLITE_OK ){
-      return MEM_Int;
-    }
-    return MEM_Real;
+    return computeNumericType(pMem);
   }
   return 0;
 }
@@ -68339,7 +71204,7 @@ static void memTracePrint(Mem *p){
     printf(" i:%lld", p->u.i);
 #ifndef SQLITE_OMIT_FLOATING_POINT
   }else if( p->flags & MEM_Real ){
-    printf(" r:%g", p->r);
+    printf(" r:%g", p->u.r);
 #endif
   }else if( p->flags & MEM_RowSet ){
     printf(" (rowset)");
@@ -68482,6 +71347,21 @@ static int checkSavepointCount(sqlite3 *db){
 }
 #endif
 
+/*
+** Return the register of pOp->p2 after first preparing it to be
+** overwritten with an integer value.
+*/ 
+static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){
+  Mem *pOut;
+  assert( pOp->p2>0 );
+  assert( pOp->p2<=(p->nMem-p->nCursor) );
+  pOut = &p->aMem[pOp->p2];
+  memAboutToChange(p, pOut);
+  if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut);
+  pOut->flags = MEM_Int;
+  return pOut;
+}
+
 
 /*
 ** Execute as much of a VDBE program as we can.
@@ -68490,9 +71370,11 @@ static int checkSavepointCount(sqlite3 *db){
 SQLITE_PRIVATE int sqlite3VdbeExec(
   Vdbe *p                    /* The VDBE */
 ){
-  int pc=0;                  /* The program counter */
   Op *aOp = p->aOp;          /* Copy of p->aOp */
-  Op *pOp;                   /* Current operation */
+  Op *pOp = aOp;             /* Current operation */
+#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
+  Op *pOrigOp;               /* Value of pOp at the top of the loop */
+#endif
   int rc = SQLITE_OK;        /* Value to return */
   sqlite3 *db = p->db;       /* The database */
   u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
@@ -68568,20 +71450,22 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
   }
   sqlite3EndBenignMalloc();
 #endif
-  for(pc=p->pc; rc==SQLITE_OK; pc++){
-    assert( pc>=0 && pc<p->nOp );
+  for(pOp=&aOp[p->pc]; rc==SQLITE_OK; pOp++){
+    assert( pOp>=aOp && pOp<&aOp[p->nOp]);
     if( db->mallocFailed ) goto no_mem;
 #ifdef VDBE_PROFILE
     start = sqlite3Hwtime();
 #endif
     nVmStep++;
-    pOp = &aOp[pc];
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+    if( p->anExec ) p->anExec[(int)(pOp-aOp)]++;
+#endif
 
     /* Only allow tracing if SQLITE_DEBUG is defined.
     */
 #ifdef SQLITE_DEBUG
     if( db->flags & SQLITE_VdbeTrace ){
-      sqlite3VdbePrintOp(stdout, pc, pOp);
+      sqlite3VdbePrintOp(stdout, (int)(pOp - aOp), pOp);
     }
 #endif
       
@@ -68598,23 +71482,9 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
     }
 #endif
 
-    /* On any opcode with the "out2-prerelease" tag, free any
-    ** external allocations out of mem[p2] and set mem[p2] to be
-    ** an undefined integer.  Opcodes will either fill in the integer
-    ** value or convert mem[p2] to a different type.
-    */
-    assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
-    if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){
-      assert( pOp->p2>0 );
-      assert( pOp->p2<=(p->nMem-p->nCursor) );
-      pOut = &aMem[pOp->p2];
-      memAboutToChange(p, pOut);
-      VdbeMemRelease(pOut);
-      pOut->flags = MEM_Int;
-    }
-
     /* Sanity checking on other operands */
 #ifdef SQLITE_DEBUG
+    assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] );
     if( (pOp->opflags & OPFLG_IN1)!=0 ){
       assert( pOp->p1>0 );
       assert( pOp->p1<=(p->nMem-p->nCursor) );
@@ -68647,6 +71517,9 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
       memAboutToChange(p, &aMem[pOp->p3]);
     }
 #endif
+#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
+    pOrigOp = pOp;
+#endif
   
     switch( pOp->opcode ){
 
@@ -68670,7 +71543,7 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
 **
 ** Other keywords in the comment that follows each case are used to
 ** construct the OPFLG_INITIALIZER value that initializes opcodeProperty[].
-** Keywords include: in1, in2, in3, out2_prerelease, out2, out3.  See
+** Keywords include: in1, in2, in3, out2, out3.  See
 ** the mkopcodeh.awk script for additional information.
 **
 ** Documentation about VDBE opcodes is generated by scanning this file
@@ -68698,7 +71571,8 @@ SQLITE_PRIVATE int sqlite3VdbeExec(
 ** to the current line should be indented for EXPLAIN output.
 */
 case OP_Goto: {             /* jump */
-  pc = pOp->p2 - 1;
+jump_to_p2_and_check_for_interrupt:
+  pOp = &aOp[pOp->p2 - 1];
 
   /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
   ** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon
@@ -68743,9 +71617,13 @@ case OP_Gosub: {            /* jump */
   assert( VdbeMemDynamic(pIn1)==0 );
   memAboutToChange(p, pIn1);
   pIn1->flags = MEM_Int;
-  pIn1->u.i = pc;
+  pIn1->u.i = (int)(pOp-aOp);
   REGISTER_TRACE(pOp->p1, pIn1);
-  pc = pOp->p2 - 1;
+
+  /* Most jump operations do a goto to this spot in order to update
+  ** the pOp pointer. */
+jump_to_p2:
+  pOp = &aOp[pOp->p2 - 1];
   break;
 }
 
@@ -68757,7 +71635,7 @@ case OP_Gosub: {            /* jump */
 case OP_Return: {           /* in1 */
   pIn1 = &aMem[pOp->p1];
   assert( pIn1->flags==MEM_Int );
-  pc = (int)pIn1->u.i;
+  pOp = &aOp[pIn1->u.i];
   pIn1->flags = MEM_Undefined;
   break;
 }
@@ -68781,7 +71659,7 @@ case OP_InitCoroutine: {     /* jump */
   assert( !VdbeMemDynamic(pOut) );
   pOut->u.i = pOp->p3 - 1;
   pOut->flags = MEM_Int;
-  if( pOp->p2 ) pc = pOp->p2 - 1;
+  if( pOp->p2 ) goto jump_to_p2;
   break;
 }
 
@@ -68801,7 +71679,7 @@ case OP_EndCoroutine: {           /* in1 */
   pCaller = &aOp[pIn1->u.i];
   assert( pCaller->opcode==OP_Yield );
   assert( pCaller->p2>=0 && pCaller->p2<p->nOp );
-  pc = pCaller->p2 - 1;
+  pOp = &aOp[pCaller->p2 - 1];
   pIn1->flags = MEM_Undefined;
   break;
 }
@@ -68825,9 +71703,9 @@ case OP_Yield: {            /* in1, jump */
   assert( VdbeMemDynamic(pIn1)==0 );
   pIn1->flags = MEM_Int;
   pcDest = (int)pIn1->u.i;
-  pIn1->u.i = pc;
+  pIn1->u.i = (int)(pOp - aOp);
   REGISTER_TRACE(pOp->p1, pIn1);
-  pc = pcDest;
+  pOp = &aOp[pcDest];
   break;
 }
 
@@ -68878,30 +71756,34 @@ case OP_HaltIfNull: {      /* in3 */
 case OP_Halt: {
   const char *zType;
   const char *zLogFmt;
+  VdbeFrame *pFrame;
+  int pcx;
 
+  pcx = (int)(pOp - aOp);
   if( pOp->p1==SQLITE_OK && p->pFrame ){
     /* Halt the sub-program. Return control to the parent frame. */
-    VdbeFrame *pFrame = p->pFrame;
+    pFrame = p->pFrame;
     p->pFrame = pFrame->pParent;
     p->nFrame--;
     sqlite3VdbeSetChanges(db, p->nChange);
-    pc = sqlite3VdbeFrameRestore(pFrame);
+    pcx = sqlite3VdbeFrameRestore(pFrame);
     lastRowid = db->lastRowid;
     if( pOp->p2==OE_Ignore ){
-      /* Instruction pc is the OP_Program that invoked the sub-program 
+      /* Instruction pcx is the OP_Program that invoked the sub-program 
       ** currently being halted. If the p2 instruction of this OP_Halt
       ** instruction is set to OE_Ignore, then the sub-program is throwing
       ** an IGNORE exception. In this case jump to the address specified
       ** as the p2 of the calling OP_Program.  */
-      pc = p->aOp[pc].p2-1;
+      pcx = p->aOp[pcx].p2-1;
     }
     aOp = p->aOp;
     aMem = p->aMem;
+    pOp = &aOp[pcx];
     break;
   }
   p->rc = pOp->p1;
   p->errorAction = (u8)pOp->p2;
-  p->pc = pc;
+  p->pc = pcx;
   if( p->rc ){
     if( pOp->p5 ){
       static const char * const azType[] = { "NOT NULL", "UNIQUE", "CHECK",
@@ -68925,7 +71807,7 @@ case OP_Halt: {
     }else{
       sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", zType);
     }
-    sqlite3_log(pOp->p1, zLogFmt, pc, p->zSql, p->zErrMsg);
+    sqlite3_log(pOp->p1, zLogFmt, pcx, p->zSql, p->zErrMsg);
   }
   rc = sqlite3VdbeHalt(p);
   assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
@@ -68944,7 +71826,8 @@ case OP_Halt: {
 **
 ** The 32-bit integer value P1 is written into register P2.
 */
-case OP_Integer: {         /* out2-prerelease */
+case OP_Integer: {         /* out2 */
+  pOut = out2Prerelease(p, pOp);
   pOut->u.i = pOp->p1;
   break;
 }
@@ -68955,7 +71838,8 @@ case OP_Integer: {         /* out2-prerelease */
 ** P4 is a pointer to a 64-bit integer value.
 ** Write that value into register P2.
 */
-case OP_Int64: {           /* out2-prerelease */
+case OP_Int64: {           /* out2 */
+  pOut = out2Prerelease(p, pOp);
   assert( pOp->p4.pI64!=0 );
   pOut->u.i = *pOp->p4.pI64;
   break;
@@ -68968,10 +71852,11 @@ case OP_Int64: {           /* out2-prerelease */
 ** P4 is a pointer to a 64-bit floating point value.
 ** Write that value into register P2.
 */
-case OP_Real: {            /* same as TK_FLOAT, out2-prerelease */
+case OP_Real: {            /* same as TK_FLOAT, out2 */
+  pOut = out2Prerelease(p, pOp);
   pOut->flags = MEM_Real;
   assert( !sqlite3IsNaN(*pOp->p4.pReal) );
-  pOut->r = *pOp->p4.pReal;
+  pOut->u.r = *pOp->p4.pReal;
   break;
 }
 #endif
@@ -68980,12 +71865,13 @@ case OP_Real: {            /* same as TK_FLOAT, out2-prerelease */
 ** Synopsis: r[P2]='P4'
 **
 ** P4 points to a nul terminated UTF-8 string. This opcode is transformed 
-** into a String before it is executed for the first time.  During
+** into a String opcode before it is executed for the first time.  During
 ** this transformation, the length of string P4 is computed and stored
 ** as the P1 parameter.
 */
-case OP_String8: {         /* same as TK_STRING, out2-prerelease */
+case OP_String8: {         /* same as TK_STRING, out2 */
   assert( pOp->p4.z!=0 );
+  pOut = out2Prerelease(p, pOp);
   pOp->opcode = OP_String;
   pOp->p1 = sqlite3Strlen30(pOp->p4.z);
 
@@ -68994,9 +71880,9 @@ case OP_String8: {         /* same as TK_STRING, out2-prerelease */
     rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC);
     if( rc==SQLITE_TOOBIG ) goto too_big;
     if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem;
-    assert( pOut->zMalloc==pOut->z );
+    assert( pOut->szMalloc>0 && pOut->zMalloc==pOut->z );
     assert( VdbeMemDynamic(pOut)==0 );
-    pOut->zMalloc = 0;
+    pOut->szMalloc = 0;
     pOut->flags |= MEM_Static;
     if( pOp->p4type==P4_DYNAMIC ){
       sqlite3DbFree(db, pOp->p4.z);
@@ -69012,18 +71898,31 @@ case OP_String8: {         /* same as TK_STRING, out2-prerelease */
   /* Fall through to the next case, OP_String */
 }
   
-/* Opcode: String P1 P2 * P4 *
+/* Opcode: String P1 P2 P3 P4 P5
 ** Synopsis: r[P2]='P4' (len=P1)
 **
 ** The string value P4 of length P1 (bytes) is stored in register P2.
+**
+** If P5!=0 and the content of register P3 is greater than zero, then
+** the datatype of the register P2 is converted to BLOB.  The content is
+** the same sequence of bytes, it is merely interpreted as a BLOB instead
+** of a string, as if it had been CAST.
 */
-case OP_String: {          /* out2-prerelease */
+case OP_String: {          /* out2 */
   assert( pOp->p4.z!=0 );
+  pOut = out2Prerelease(p, pOp);
   pOut->flags = MEM_Str|MEM_Static|MEM_Term;
   pOut->z = pOp->p4.z;
   pOut->n = pOp->p1;
   pOut->enc = encoding;
   UPDATE_MAX_BLOBSIZE(pOut);
+  if( pOp->p5 ){
+    assert( pOp->p3>0 );
+    assert( pOp->p3<=(p->nMem-p->nCursor) );
+    pIn3 = &aMem[pOp->p3];
+    assert( pIn3->flags & MEM_Int );
+    if( pIn3->u.i ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term;
+  }
   break;
 }
 
@@ -69039,16 +71938,17 @@ case OP_String: {          /* out2-prerelease */
 ** NULL values will not compare equal even if SQLITE_NULLEQ is set on
 ** OP_Ne or OP_Eq.
 */
-case OP_Null: {           /* out2-prerelease */
+case OP_Null: {           /* out2 */
   int cnt;
   u16 nullFlag;
+  pOut = out2Prerelease(p, pOp);
   cnt = pOp->p3-pOp->p2;
   assert( pOp->p3<=(p->nMem-p->nCursor) );
   pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null;
   while( cnt>0 ){
     pOut++;
     memAboutToChange(p, pOut);
-    VdbeMemRelease(pOut);
+    sqlite3VdbeMemSetNull(pOut);
     pOut->flags = nullFlag;
     cnt--;
   }
@@ -69076,8 +71976,9 @@ case OP_SoftNull: {
 ** P4 points to a blob of data P1 bytes long.  Store this
 ** blob in register P2.
 */
-case OP_Blob: {                /* out2-prerelease */
+case OP_Blob: {                /* out2 */
   assert( pOp->p1 <= SQLITE_MAX_LENGTH );
+  pOut = out2Prerelease(p, pOp);
   sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
   pOut->enc = encoding;
   UPDATE_MAX_BLOBSIZE(pOut);
@@ -69092,7 +71993,7 @@ case OP_Blob: {                /* out2-prerelease */
 ** If the parameter is named, then its name appears in P4.
 ** The P4 value is used by sqlite3_bind_parameter_name().
 */
-case OP_Variable: {            /* out2-prerelease */
+case OP_Variable: {            /* out2 */
   Mem *pVar;       /* Value being transferred */
 
   assert( pOp->p1>0 && pOp->p1<=p->nVar );
@@ -69101,6 +72002,7 @@ case OP_Variable: {            /* out2-prerelease */
   if( sqlite3VdbeMemTooBig(pVar) ){
     goto too_big;
   }
+  pOut = out2Prerelease(p, pOp);
   sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
   UPDATE_MAX_BLOBSIZE(pOut);
   break;
@@ -69116,7 +72018,6 @@ case OP_Variable: {            /* out2-prerelease */
 ** for P3 to be less than 1.
 */
 case OP_Move: {
-  char *zMalloc;   /* Holding variable for allocated memory */
   int n;           /* Number of registers left to copy */
   int p1;          /* Register to copy from */
   int p2;          /* Register to copy to */
@@ -69134,17 +72035,13 @@ case OP_Move: {
     assert( pIn1<=&aMem[(p->nMem-p->nCursor)] );
     assert( memIsValid(pIn1) );
     memAboutToChange(p, pOut);
-    VdbeMemRelease(pOut);
-    zMalloc = pOut->zMalloc;
-    memcpy(pOut, pIn1, sizeof(Mem));
+    sqlite3VdbeMemMove(pOut, pIn1);
 #ifdef SQLITE_DEBUG
-    if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<&aMem[p1+pOp->p3] ){
-      pOut->pScopyFrom += p1 - pOp->p2;
+    if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<pOut ){
+      pOut->pScopyFrom += pOp->p2 - p1;
     }
 #endif
-    pIn1->flags = MEM_Undefined;
-    pIn1->xDel = 0;
-    pIn1->zMalloc = zMalloc;
+    Deephemeralize(pOut);
     REGISTER_TRACE(p2++, pOut);
     pIn1++;
     pOut++;
@@ -69283,7 +72180,7 @@ case OP_ResultRow: {
 
   /* Return SQLITE_ROW
   */
-  p->pc = pc + 1;
+  p->pc = (int)(pOp - aOp) + 1;
   rc = SQLITE_ROW;
   goto vdbe_return;
 }
@@ -69449,7 +72346,7 @@ fp_math:
     if( sqlite3IsNaN(rB) ){
       goto arithmetic_result_is_null;
     }
-    pOut->r = rB;
+    pOut->u.r = rB;
     MemSetTypeFlag(pOut, MEM_Real);
     if( ((type1|type2)&MEM_Real)==0 && !bIntint ){
       sqlite3VdbeIntegerAffinity(pOut);
@@ -69476,7 +72373,7 @@ arithmetic_result_is_null:
 **
 ** The interface used by the implementation of the aforementioned functions
 ** to retrieve the collation sequence set by this opcode is not available
-** publicly, only to user functions defined in func.c.
+** publicly.  Only built-in functions have access to this feature.
 */
 case OP_CollSeq: {
   assert( pOp->p4type==P4_COLLSEQ );
@@ -69514,8 +72411,8 @@ case OP_Function: {
   apVal = p->apArg;
   assert( apVal || n==0 );
   assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
-  pOut = &aMem[pOp->p3];
-  memAboutToChange(p, pOut);
+  ctx.pOut = &aMem[pOp->p3];
+  memAboutToChange(p, ctx.pOut);
 
   assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) );
   assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
@@ -69529,67 +72426,31 @@ case OP_Function: {
 
   assert( pOp->p4type==P4_FUNCDEF );
   ctx.pFunc = pOp->p4.pFunc;
-  ctx.iOp = pc;
+  ctx.iOp = (int)(pOp - aOp);
   ctx.pVdbe = p;
-
-  /* The output cell may already have a buffer allocated. Move
-  ** the pointer to ctx.s so in case the user-function can use
-  ** the already allocated buffer instead of allocating a new one.
-  */
-  memcpy(&ctx.s, pOut, sizeof(Mem));
-  pOut->flags = MEM_Null;
-  pOut->xDel = 0;
-  pOut->zMalloc = 0;
-  MemSetTypeFlag(&ctx.s, MEM_Null);
-
+  MemSetTypeFlag(ctx.pOut, MEM_Null);
   ctx.fErrorOrAux = 0;
-  if( ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
-    assert( pOp>aOp );
-    assert( pOp[-1].p4type==P4_COLLSEQ );
-    assert( pOp[-1].opcode==OP_CollSeq );
-    ctx.pColl = pOp[-1].p4.pColl;
-  }
   db->lastRowid = lastRowid;
   (*ctx.pFunc->xFunc)(&ctx, n, apVal); /* IMP: R-24505-23230 */
-  lastRowid = db->lastRowid;
-
-  if( db->mallocFailed ){
-    /* Even though a malloc() has failed, the implementation of the
-    ** user function may have called an sqlite3_result_XXX() function
-    ** to return a value. The following call releases any resources
-    ** associated with such a value.
-    */
-    sqlite3VdbeMemRelease(&ctx.s);
-    goto no_mem;
-  }
+  lastRowid = db->lastRowid;  /* Remember rowid changes made by xFunc */
 
   /* If the function returned an error, throw an exception */
   if( ctx.fErrorOrAux ){
     if( ctx.isError ){
-      sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s));
+      sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut));
       rc = ctx.isError;
     }
-    sqlite3VdbeDeleteAuxData(p, pc, pOp->p1);
+    sqlite3VdbeDeleteAuxData(p, (int)(pOp - aOp), pOp->p1);
   }
 
   /* Copy the result of the function into register P3 */
-  sqlite3VdbeChangeEncoding(&ctx.s, encoding);
-  assert( pOut->flags==MEM_Null );
-  memcpy(pOut, &ctx.s, sizeof(Mem));
-  if( sqlite3VdbeMemTooBig(pOut) ){
+  sqlite3VdbeChangeEncoding(ctx.pOut, encoding);
+  if( sqlite3VdbeMemTooBig(ctx.pOut) ){
     goto too_big;
   }
 
-#if 0
-  /* The app-defined function has done something that as caused this
-  ** statement to expire.  (Perhaps the function called sqlite3_exec()
-  ** with a CREATE TABLE statement.)
-  */
-  if( p->expired ) rc = SQLITE_ABORT;
-#endif
-
-  REGISTER_TRACE(pOp->p3, pOut);
-  UPDATE_MAX_BLOBSIZE(pOut);
+  REGISTER_TRACE(pOp->p3, ctx.pOut);
+  UPDATE_MAX_BLOBSIZE(ctx.pOut);
   break;
 }
 
@@ -69708,8 +72569,7 @@ case OP_MustBeInt: {            /* jump, in1 */
         rc = SQLITE_MISMATCH;
         goto abort_due_to_error;
       }else{
-        pc = pOp->p2 - 1;
-        break;
+        goto jump_to_p2;
       }
     }
   }
@@ -69737,106 +72597,37 @@ case OP_RealAffinity: {                  /* in1 */
 #endif
 
 #ifndef SQLITE_OMIT_CAST
-/* Opcode: ToText P1 * * * *
+/* Opcode: Cast P1 P2 * * *
+** Synopsis: affinity(r[P1])
 **
-** Force the value in register P1 to be text.
-** If the value is numeric, convert it to a string using the
-** equivalent of sprintf().  Blob values are unchanged and
-** are afterwards simply interpreted as text.
+** Force the value in register P1 to be the type defined by P2.
+** 
+** <ul>
+** <li value="97"> TEXT
+** <li value="98"> BLOB
+** <li value="99"> NUMERIC
+** <li value="100"> INTEGER
+** <li value="101"> REAL
+** </ul>
 **
 ** A NULL value is not changed by this routine.  It remains NULL.
 */
-case OP_ToText: {                  /* same as TK_TO_TEXT, in1 */
+case OP_Cast: {                  /* in1 */
+  assert( pOp->p2>=SQLITE_AFF_NONE && pOp->p2<=SQLITE_AFF_REAL );
+  testcase( pOp->p2==SQLITE_AFF_TEXT );
+  testcase( pOp->p2==SQLITE_AFF_NONE );
+  testcase( pOp->p2==SQLITE_AFF_NUMERIC );
+  testcase( pOp->p2==SQLITE_AFF_INTEGER );
+  testcase( pOp->p2==SQLITE_AFF_REAL );
   pIn1 = &aMem[pOp->p1];
   memAboutToChange(p, pIn1);
-  if( pIn1->flags & MEM_Null ) break;
-  assert( MEM_Str==(MEM_Blob>>3) );
-  pIn1->flags |= (pIn1->flags&MEM_Blob)>>3;
-  applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding);
   rc = ExpandBlob(pIn1);
-  assert( pIn1->flags & MEM_Str || db->mallocFailed );
-  pIn1->flags &= ~(MEM_Int|MEM_Real|MEM_Blob|MEM_Zero);
+  sqlite3VdbeMemCast(pIn1, pOp->p2, encoding);
   UPDATE_MAX_BLOBSIZE(pIn1);
   break;
 }
-
-/* Opcode: ToBlob P1 * * * *
-**
-** Force the value in register P1 to be a BLOB.
-** If the value is numeric, convert it to a string first.
-** Strings are simply reinterpreted as blobs with no change
-** to the underlying data.
-**
-** A NULL value is not changed by this routine.  It remains NULL.
-*/
-case OP_ToBlob: {                  /* same as TK_TO_BLOB, in1 */
-  pIn1 = &aMem[pOp->p1];
-  if( pIn1->flags & MEM_Null ) break;
-  if( (pIn1->flags & MEM_Blob)==0 ){
-    applyAffinity(pIn1, SQLITE_AFF_TEXT, encoding);
-    assert( pIn1->flags & MEM_Str || db->mallocFailed );
-    MemSetTypeFlag(pIn1, MEM_Blob);
-  }else{
-    pIn1->flags &= ~(MEM_TypeMask&~MEM_Blob);
-  }
-  UPDATE_MAX_BLOBSIZE(pIn1);
-  break;
-}
-
-/* Opcode: ToNumeric P1 * * * *
-**
-** Force the value in register P1 to be numeric (either an
-** integer or a floating-point number.)
-** If the value is text or blob, try to convert it to an using the
-** equivalent of atoi() or atof() and store 0 if no such conversion 
-** is possible.
-**
-** A NULL value is not changed by this routine.  It remains NULL.
-*/
-case OP_ToNumeric: {                  /* same as TK_TO_NUMERIC, in1 */
-  pIn1 = &aMem[pOp->p1];
-  sqlite3VdbeMemNumerify(pIn1);
-  break;
-}
 #endif /* SQLITE_OMIT_CAST */
 
-/* Opcode: ToInt P1 * * * *
-**
-** Force the value in register P1 to be an integer.  If
-** The value is currently a real number, drop its fractional part.
-** If the value is text or blob, try to convert it to an integer using the
-** equivalent of atoi() and store 0 if no such conversion is possible.
-**
-** A NULL value is not changed by this routine.  It remains NULL.
-*/
-case OP_ToInt: {                  /* same as TK_TO_INT, in1 */
-  pIn1 = &aMem[pOp->p1];
-  if( (pIn1->flags & MEM_Null)==0 ){
-    sqlite3VdbeMemIntegerify(pIn1);
-  }
-  break;
-}
-
-#if !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_FLOATING_POINT)
-/* Opcode: ToReal P1 * * * *
-**
-** Force the value in register P1 to be a floating point number.
-** If The value is currently an integer, convert it.
-** If the value is text or blob, try to convert it to an integer using the
-** equivalent of atoi() and store 0.0 if no such conversion is possible.
-**
-** A NULL value is not changed by this routine.  It remains NULL.
-*/
-case OP_ToReal: {                  /* same as TK_TO_REAL, in1 */
-  pIn1 = &aMem[pOp->p1];
-  memAboutToChange(p, pIn1);
-  if( (pIn1->flags & MEM_Null)==0 ){
-    sqlite3VdbeMemRealify(pIn1);
-  }
-  break;
-}
-#endif /* !defined(SQLITE_OMIT_CAST) && !defined(SQLITE_OMIT_FLOATING_POINT) */
-
 /* Opcode: Lt P1 P2 P3 P4 P5
 ** Synopsis: if r[P1]<r[P3] goto P2
 **
@@ -69964,7 +72755,7 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
       }else{
         VdbeBranchTaken(2,3);
         if( pOp->p5 & SQLITE_JUMPIFNULL ){
-          pc = pOp->p2-1;
+          goto jump_to_p2;
         }
       }
       break;
@@ -69972,15 +72763,39 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
   }else{
     /* Neither operand is NULL.  Do a comparison. */
     affinity = pOp->p5 & SQLITE_AFF_MASK;
-    if( affinity ){
-      applyAffinity(pIn1, affinity, encoding);
-      applyAffinity(pIn3, affinity, encoding);
-      if( db->mallocFailed ) goto no_mem;
+    if( affinity>=SQLITE_AFF_NUMERIC ){
+      if( (pIn1->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+        applyNumericAffinity(pIn1,0);
+      }
+      if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+        applyNumericAffinity(pIn3,0);
+      }
+    }else if( affinity==SQLITE_AFF_TEXT ){
+      if( (pIn1->flags & MEM_Str)==0 && (pIn1->flags & (MEM_Int|MEM_Real))!=0 ){
+        testcase( pIn1->flags & MEM_Int );
+        testcase( pIn1->flags & MEM_Real );
+        sqlite3VdbeMemStringify(pIn1, encoding, 1);
+        testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) );
+        flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask);
+      }
+      if( (pIn3->flags & MEM_Str)==0 && (pIn3->flags & (MEM_Int|MEM_Real))!=0 ){
+        testcase( pIn3->flags & MEM_Int );
+        testcase( pIn3->flags & MEM_Real );
+        sqlite3VdbeMemStringify(pIn3, encoding, 1);
+        testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn) );
+        flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask);
+      }
     }
-
     assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 );
-    ExpandBlob(pIn1);
-    ExpandBlob(pIn3);
+    if( pIn1->flags & MEM_Zero ){
+      sqlite3VdbeMemExpandBlob(pIn1);
+      flags1 &= ~MEM_Zero;
+    }
+    if( pIn3->flags & MEM_Zero ){
+      sqlite3VdbeMemExpandBlob(pIn3);
+      flags3 &= ~MEM_Zero;
+    }
+    if( db->mallocFailed ) goto no_mem;
     res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl);
   }
   switch( pOp->opcode ){
@@ -69992,6 +72807,12 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
     default:       res = res>=0;     break;
   }
 
+  /* Undo any changes made by applyAffinity() to the input registers. */
+  assert( (pIn1->flags & MEM_Dyn) == (flags1 & MEM_Dyn) );
+  pIn1->flags = flags1;
+  assert( (pIn3->flags & MEM_Dyn) == (flags3 & MEM_Dyn) );
+  pIn3->flags = flags3;
+
   if( pOp->p5 & SQLITE_STOREP2 ){
     pOut = &aMem[pOp->p2];
     memAboutToChange(p, pOut);
@@ -70001,12 +72822,9 @@ case OP_Ge: {             /* same as TK_GE, jump, in1, in3 */
   }else{
     VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
     if( res ){
-      pc = pOp->p2-1;
+      goto jump_to_p2;
     }
   }
-  /* Undo any changes made by applyAffinity() to the input registers. */
-  pIn1->flags = (pIn1->flags&~MEM_TypeMask) | (flags1&MEM_TypeMask);
-  pIn3->flags = (pIn3->flags&~MEM_TypeMask) | (flags3&MEM_TypeMask);
   break;
 }
 
@@ -70101,11 +72919,11 @@ case OP_Compare: {
 */
 case OP_Jump: {             /* jump */
   if( iCompare<0 ){
-    pc = pOp->p1 - 1;  VdbeBranchTaken(0,3);
+    VdbeBranchTaken(0,3); pOp = &aOp[pOp->p1 - 1];
   }else if( iCompare==0 ){
-    pc = pOp->p2 - 1;  VdbeBranchTaken(1,3);
+    VdbeBranchTaken(1,3); pOp = &aOp[pOp->p2 - 1];
   }else{
-    pc = pOp->p3 - 1;  VdbeBranchTaken(2,3);
+    VdbeBranchTaken(2,3); pOp = &aOp[pOp->p3 - 1];
   }
   break;
 }
@@ -70174,10 +72992,10 @@ case OP_Or: {             /* same as TK_OR, in1, in2, out3 */
 case OP_Not: {                /* same as TK_NOT, in1, out2 */
   pIn1 = &aMem[pOp->p1];
   pOut = &aMem[pOp->p2];
-  if( pIn1->flags & MEM_Null ){
-    sqlite3VdbeMemSetNull(pOut);
-  }else{
-    sqlite3VdbeMemSetInt64(pOut, !sqlite3VdbeIntValue(pIn1));
+  sqlite3VdbeMemSetNull(pOut);
+  if( (pIn1->flags & MEM_Null)==0 ){
+    pOut->flags = MEM_Int;
+    pOut->u.i = !sqlite3VdbeIntValue(pIn1);
   }
   break;
 }
@@ -70192,10 +73010,10 @@ case OP_Not: {                /* same as TK_NOT, in1, out2 */
 case OP_BitNot: {             /* same as TK_BITNOT, in1, out2 */
   pIn1 = &aMem[pOp->p1];
   pOut = &aMem[pOp->p2];
-  if( pIn1->flags & MEM_Null ){
-    sqlite3VdbeMemSetNull(pOut);
-  }else{
-    sqlite3VdbeMemSetInt64(pOut, ~sqlite3VdbeIntValue(pIn1));
+  sqlite3VdbeMemSetNull(pOut);
+  if( (pIn1->flags & MEM_Null)==0 ){
+    pOut->flags = MEM_Int;
+    pOut->u.i = ~sqlite3VdbeIntValue(pIn1);
   }
   break;
 }
@@ -70215,7 +73033,7 @@ case OP_Once: {             /* jump */
   assert( pOp->p1<p->nOnceFlag );
   VdbeBranchTaken(p->aOnceFlag[pOp->p1]!=0, 2);
   if( p->aOnceFlag[pOp->p1] ){
-    pc = pOp->p2-1;
+    goto jump_to_p2;
   }else{
     p->aOnceFlag[pOp->p1] = 1;
   }
@@ -70250,7 +73068,7 @@ case OP_IfNot: {            /* jump, in1 */
   }
   VdbeBranchTaken(c!=0, 2);
   if( c ){
-    pc = pOp->p2-1;
+    goto jump_to_p2;
   }
   break;
 }
@@ -70264,7 +73082,7 @@ case OP_IsNull: {            /* same as TK_ISNULL, jump, in1 */
   pIn1 = &aMem[pOp->p1];
   VdbeBranchTaken( (pIn1->flags & MEM_Null)!=0, 2);
   if( (pIn1->flags & MEM_Null)!=0 ){
-    pc = pOp->p2 - 1;
+    goto jump_to_p2;
   }
   break;
 }
@@ -70278,7 +73096,7 @@ case OP_NotNull: {            /* same as TK_NOTNULL, jump, in1 */
   pIn1 = &aMem[pOp->p1];
   VdbeBranchTaken( (pIn1->flags & MEM_Null)==0, 2);
   if( (pIn1->flags & MEM_Null)==0 ){
-    pc = pOp->p2 - 1;
+    goto jump_to_p2;
   }
   break;
 }
@@ -70313,7 +73131,6 @@ case OP_Column: {
   int p2;            /* column number to retrieve */
   VdbeCursor *pC;    /* The VDBE cursor */
   BtCursor *pCrsr;   /* The BTree cursor */
-  u32 *aType;        /* aType[i] holds the numeric type of the i-th column */
   u32 *aOffset;      /* aOffset[i] is offset to start of data for i-th column */
   int len;           /* The length of the serialized data for the column */
   int i;             /* Loop counter */
@@ -70326,6 +73143,7 @@ case OP_Column: {
   u32 szField;       /* Number of bytes in the content of a field */
   u32 avail;         /* Number of bytes of available data */
   u32 t;             /* A type code from the record header */
+  u16 fx;            /* pDest->flags value */
   Mem *pReg;         /* PseudoTable input register */
 
   p2 = pOp->p2;
@@ -70336,8 +73154,7 @@ case OP_Column: {
   pC = p->apCsr[pOp->p1];
   assert( pC!=0 );
   assert( p2<pC->nField );
-  aType = pC->aType;
-  aOffset = aType + pC->nField;
+  aOffset = pC->aOffset;
 #ifndef SQLITE_OMIT_VIRTUALTABLE
   assert( pC->pVtabCursor==0 ); /* OP_Column never called on virtual table */
 #endif
@@ -70348,7 +73165,7 @@ case OP_Column: {
   /* If the cursor cache is stale, bring it up-to-date */
   rc = sqlite3VdbeCursorMoveto(pC);
   if( rc ) goto abort_due_to_error;
-  if( pC->cacheStatus!=p->cacheCtr || (pOp->p5&OPFLAG_CLEARCACHE)!=0 ){
+  if( pC->cacheStatus!=p->cacheCtr ){
     if( pC->nullRow ){
       if( pCrsr==0 ){
         assert( pC->pseudoTableReg>0 );
@@ -70358,7 +73175,7 @@ case OP_Column: {
         pC->payloadSize = pC->szRow = avail = pReg->n;
         pC->aRow = (u8*)pReg->z;
       }else{
-        MemSetTypeFlag(pDest, MEM_Null);
+        sqlite3VdbeMemSetNull(pDest);
         goto op_column_out;
       }
     }else{
@@ -70393,14 +73210,6 @@ case OP_Column: {
     pC->iHdrOffset = getVarint32(pC->aRow, offset);
     pC->nHdrParsed = 0;
     aOffset[0] = offset;
-    if( avail<offset ){
-      /* pC->aRow does not have to hold the entire row, but it does at least
-      ** need to cover the header of the record.  If pC->aRow does not contain
-      ** the complete header, then set it to zero, forcing the header to be
-      ** dynamically allocated. */
-      pC->aRow = 0;
-      pC->szRow = 0;
-    }
 
     /* Make sure a corrupt database has not given us an oversize header.
     ** Do this now to avoid an oversize memory allocation.
@@ -70415,15 +73224,32 @@ case OP_Column: {
       rc = SQLITE_CORRUPT_BKPT;
       goto op_column_error;
     }
+
+    if( avail<offset ){
+      /* pC->aRow does not have to hold the entire row, but it does at least
+      ** need to cover the header of the record.  If pC->aRow does not contain
+      ** the complete header, then set it to zero, forcing the header to be
+      ** dynamically allocated. */
+      pC->aRow = 0;
+      pC->szRow = 0;
+    }
+
+    /* The following goto is an optimization.  It can be omitted and
+    ** everything will still work.  But OP_Column is measurably faster
+    ** by skipping the subsequent conditional, which is always true.
+    */
+    assert( pC->nHdrParsed<=p2 );         /* Conditional skipped */
+    goto op_column_read_header;
   }
 
   /* Make sure at least the first p2+1 entries of the header have been
-  ** parsed and valid information is in aOffset[] and aType[].
+  ** parsed and valid information is in aOffset[] and pC->aType[].
   */
   if( pC->nHdrParsed<=p2 ){
     /* If there is more header available for parsing in the record, try
     ** to extract additional fields up through the p2+1-th field 
     */
+    op_column_read_header:
     if( pC->iHdrOffset<aOffset[0] ){
       /* Make sure zData points to enough of the record to cover the header. */
       if( pC->aRow==0 ){
@@ -70438,7 +73264,7 @@ case OP_Column: {
         zData = pC->aRow;
       }
   
-      /* Fill in aType[i] and aOffset[i] values through the p2-th field. */
+      /* Fill in pC->aType[i] and aOffset[i] values through the p2-th field. */
       i = pC->nHdrParsed;
       offset = aOffset[i];
       zHdr = zData + pC->iHdrOffset;
@@ -70451,7 +73277,7 @@ case OP_Column: {
         }else{
           zHdr += sqlite3GetVarint32(zHdr, &t);
         }
-        aType[i] = t;
+        pC->aType[i] = t;
         szField = sqlite3VdbeSerialTypeLen(t);
         offset += szField;
         if( offset<szField ){  /* True if offset overflows */
@@ -70468,22 +73294,23 @@ case OP_Column: {
         sMem.flags = MEM_Null;
       }
   
-      /* If we have read more header data than was contained in the header,
-      ** or if the end of the last field appears to be past the end of the
-      ** record, or if the end of the last field appears to be before the end
-      ** of the record (when all fields present), then we must be dealing 
-      ** with a corrupt database.
+      /* The record is corrupt if any of the following are true:
+      ** (1) the bytes of the header extend past the declared header size
+      **          (zHdr>zEndHdr)
+      ** (2) the entire header was used but not all data was used
+      **          (zHdr==zEndHdr && offset!=pC->payloadSize)
+      ** (3) the end of the data extends beyond the end of the record.
+      **          (offset > pC->payloadSize)
       */
-      if( (zHdr > zEndHdr)
+      if( (zHdr>=zEndHdr && (zHdr>zEndHdr || offset!=pC->payloadSize))
        || (offset > pC->payloadSize)
-       || (zHdr==zEndHdr && offset!=pC->payloadSize)
       ){
         rc = SQLITE_CORRUPT_BKPT;
         goto op_column_error;
       }
     }
 
-    /* If after trying to extra new entries from the header, nHdrParsed is
+    /* If after trying to extract new entries from the header, nHdrParsed is
     ** still not up to p2, that means that the record has fewer than p2
     ** columns.  So the result will be either the default value or a NULL.
     */
@@ -70491,68 +73318,68 @@ case OP_Column: {
       if( pOp->p4type==P4_MEM ){
         sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static);
       }else{
-        MemSetTypeFlag(pDest, MEM_Null);
+        sqlite3VdbeMemSetNull(pDest);
       }
       goto op_column_out;
     }
   }
 
   /* Extract the content for the p2+1-th column.  Control can only
-  ** reach this point if aOffset[p2], aOffset[p2+1], and aType[p2] are
+  ** reach this point if aOffset[p2], aOffset[p2+1], and pC->aType[p2] are
   ** all valid.
   */
   assert( p2<pC->nHdrParsed );
   assert( rc==SQLITE_OK );
   assert( sqlite3VdbeCheckMemInvariants(pDest) );
+  if( VdbeMemDynamic(pDest) ) sqlite3VdbeMemSetNull(pDest);
+  t = pC->aType[p2];
   if( pC->szRow>=aOffset[p2+1] ){
     /* This is the common case where the desired content fits on the original
     ** page - where the content is not on an overflow page */
-    VdbeMemRelease(pDest);
-    sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], aType[p2], pDest);
+    sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], t, pDest);
   }else{
     /* This branch happens only when content is on overflow pages */
-    t = aType[p2];
     if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0
           && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0))
      || (len = sqlite3VdbeSerialTypeLen(t))==0
     ){
-      /* Content is irrelevant for the typeof() function and for
-      ** the length(X) function if X is a blob.  So we might as well use
-      ** bogus content rather than reading content from disk.  NULL works
-      ** for text and blob and whatever is in the payloadSize64 variable
-      ** will work for everything else.  Content is also irrelevant if
-      ** the content length is 0. */
-      zData = t<=13 ? (u8*)&payloadSize64 : 0;
-      sMem.zMalloc = 0;
+      /* Content is irrelevant for
+      **    1. the typeof() function,
+      **    2. the length(X) function if X is a blob, and
+      **    3. if the content length is zero.
+      ** So we might as well use bogus content rather than reading
+      ** content from disk.  NULL will work for the value for strings
+      ** and blobs and whatever is in the payloadSize64 variable
+      ** will work for everything else. */
+      sqlite3VdbeSerialGet(t<=13 ? (u8*)&payloadSize64 : 0, t, pDest);
     }else{
-      memset(&sMem, 0, sizeof(sMem));
-      sqlite3VdbeMemMove(&sMem, pDest);
       rc = sqlite3VdbeMemFromBtree(pCrsr, aOffset[p2], len, !pC->isTable,
-                                   &sMem);
+                                   pDest);
       if( rc!=SQLITE_OK ){
         goto op_column_error;
       }
-      zData = (u8*)sMem.z;
-    }
-    sqlite3VdbeSerialGet(zData, t, pDest);
-    /* If we dynamically allocated space to hold the data (in the
-    ** sqlite3VdbeMemFromBtree() call above) then transfer control of that
-    ** dynamically allocated space over to the pDest structure.
-    ** This prevents a memory copy. */
-    if( sMem.zMalloc ){
-      assert( sMem.z==sMem.zMalloc );
-      assert( VdbeMemDynamic(pDest)==0 );
-      assert( (pDest->flags & (MEM_Blob|MEM_Str))==0 || pDest->z==sMem.z );
-      pDest->flags &= ~(MEM_Ephem|MEM_Static);
-      pDest->flags |= MEM_Term;
-      pDest->z = sMem.z;
-      pDest->zMalloc = sMem.zMalloc;
+      sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
+      pDest->flags &= ~MEM_Ephem;
     }
   }
   pDest->enc = encoding;
 
 op_column_out:
-  Deephemeralize(pDest);
+  /* If the column value is an ephemeral string, go ahead and persist
+  ** that string in case the cursor moves before the column value is
+  ** used.  The following code does the equivalent of Deephemeralize()
+  ** but does it faster. */
+  if( (pDest->flags & MEM_Ephem)!=0 && pDest->z ){
+    fx = pDest->flags & (MEM_Str|MEM_Blob);
+    assert( fx!=0 );
+    zData = (const u8*)pDest->z;
+    len = pDest->n;
+    if( sqlite3VdbeMemClearAndResize(pDest, len+2) ) goto no_mem;
+    memcpy(pDest->z, zData, len);
+    pDest->z[len] = 0;
+    pDest->z[len+1] = 0;
+    pDest->flags = fx|MEM_Term;
+  }
 op_column_error:
   UPDATE_MAX_BLOBSIZE(pDest);
   REGISTER_TRACE(pOp->p3, pDest);
@@ -70607,7 +73434,7 @@ case OP_MakeRecord: {
   u64 nData;             /* Number of bytes of data space */
   int nHdr;              /* Number of bytes of header space */
   i64 nByte;             /* Data space required for this record */
-  int nZero;             /* Number of zero bytes at the end of the record */
+  i64 nZero;             /* Number of zero bytes at the end of the record */
   int nVarint;           /* Number of bytes in a varint */
   u32 serial_type;       /* Type field */
   Mem *pData0;           /* First field to be combined into the record */
@@ -70627,7 +73454,7 @@ case OP_MakeRecord: {
   ** ------------------------------------------------------------------------
   **
   ** Data(0) is taken from register P1.  Data(1) comes from register P1+1
-  ** and so froth.
+  ** and so forth.
   **
   ** Each type field is a varint representing the serial type of the 
   ** corresponding data element (see sqlite3VdbeSerialType()). The
@@ -70667,7 +73494,7 @@ case OP_MakeRecord: {
   pRec = pLast;
   do{
     assert( memIsValid(pRec) );
-    serial_type = sqlite3VdbeSerialType(pRec, file_format);
+    pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format);
     len = sqlite3VdbeSerialTypeLen(serial_type);
     if( pRec->flags & MEM_Zero ){
       if( nData ){
@@ -70683,7 +73510,10 @@ case OP_MakeRecord: {
     nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
   }while( (--pRec)>=pData0 );
 
-  /* Add the initial header varint and total the size */
+  /* EVIDENCE-OF: R-22564-11647 The header begins with a single varint
+  ** which determines the total number of bytes in the header. The varint
+  ** value is the size of the header in bytes including the size varint
+  ** itself. */
   testcase( nHdr==126 );
   testcase( nHdr==127 );
   if( nHdr<=126 ){
@@ -70696,16 +73526,16 @@ case OP_MakeRecord: {
     if( nVarint<sqlite3VarintLen(nHdr) ) nHdr++;
   }
   nByte = nHdr+nData;
-  if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
+  if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){
     goto too_big;
   }
 
   /* Make sure the output register has a buffer large enough to store 
   ** the new record. The output register (pOp->p3) is not allowed to
   ** be one of the input registers (because the following call to
-  ** sqlite3VdbeMemGrow() could clobber the value before it is used).
+  ** sqlite3VdbeMemClearAndResize() could clobber the value before it is used).
   */
-  if( sqlite3VdbeMemGrow(pOut, (int)nByte, 0) ){
+  if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){
     goto no_mem;
   }
   zNewRecord = (u8 *)pOut->z;
@@ -70716,8 +73546,12 @@ case OP_MakeRecord: {
   assert( pData0<=pLast );
   pRec = pData0;
   do{
-    serial_type = sqlite3VdbeSerialType(pRec, file_format);
+    serial_type = pRec->uTemp;
+    /* EVIDENCE-OF: R-06529-47362 Following the size varint are one or more
+    ** additional varints, one per column. */
     i += putVarint32(&zNewRecord[i], serial_type);            /* serial type */
+    /* EVIDENCE-OF: R-64536-51728 The values for each column in the record
+    ** immediately follow the header. */
     j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */
   }while( (++pRec)<=pLast );
   assert( i==nHdr );
@@ -70726,7 +73560,6 @@ case OP_MakeRecord: {
   assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
   pOut->n = (int)nByte;
   pOut->flags = MEM_Blob;
-  pOut->xDel = 0;
   if( nZero ){
     pOut->u.nZero = nZero;
     pOut->flags |= MEM_Zero;
@@ -70744,7 +73577,7 @@ case OP_MakeRecord: {
 ** opened by cursor P1 in register P2
 */
 #ifndef SQLITE_OMIT_BTREECOUNT
-case OP_Count: {         /* out2-prerelease */
+case OP_Count: {         /* out2 */
   i64 nEntry;
   BtCursor *pCrsr;
 
@@ -70752,6 +73585,7 @@ case OP_Count: {         /* out2-prerelease */
   assert( pCrsr );
   nEntry = 0;  /* Not needed.  Only used to silence a warning. */
   rc = sqlite3BtreeCount(pCrsr, &nEntry);
+  pOut = out2Prerelease(p, pOp);
   pOut->u.i = nEntry;
   break;
 }
@@ -70865,7 +73699,7 @@ case OP_Savepoint: {
         }
         db->autoCommit = 1;
         if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
-          p->pc = pc;
+          p->pc = (int)(pOp - aOp);
           db->autoCommit = 0;
           p->rc = rc = SQLITE_BUSY;
           goto vdbe_return;
@@ -70873,11 +73707,18 @@ case OP_Savepoint: {
         db->isTransactionSavepoint = 0;
         rc = p->rc;
       }else{
+        int isSchemaChange;
         iSavepoint = db->nSavepoint - iSavepoint - 1;
         if( p1==SAVEPOINT_ROLLBACK ){
+          isSchemaChange = (db->flags & SQLITE_InternChanges)!=0;
           for(ii=0; ii<db->nDb; ii++){
-            sqlite3BtreeTripAllCursors(db->aDb[ii].pBt, SQLITE_ABORT);
+            rc = sqlite3BtreeTripAllCursors(db->aDb[ii].pBt,
+                                       SQLITE_ABORT_ROLLBACK,
+                                       isSchemaChange==0);
+            if( rc!=SQLITE_OK ) goto abort_due_to_error;
           }
+        }else{
+          isSchemaChange = 0;
         }
         for(ii=0; ii<db->nDb; ii++){
           rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint);
@@ -70885,7 +73726,7 @@ case OP_Savepoint: {
             goto abort_due_to_error;
           }
         }
-        if( p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){
+        if( isSchemaChange ){
           sqlite3ExpirePreparedStatements(db);
           sqlite3ResetAllSchemasOfConnection(db);
           db->flags = (db->flags | SQLITE_InternChanges);
@@ -70917,7 +73758,7 @@ case OP_Savepoint: {
         db->nDeferredImmCons = pSavepoint->nDeferredImmCons;
       }
 
-      if( !isTransaction ){
+      if( !isTransaction || p1==SAVEPOINT_ROLLBACK ){
         rc = sqlite3VtabSavepoint(db, p1, iSavepoint);
         if( rc!=SQLITE_OK ) goto abort_due_to_error;
       }
@@ -70977,7 +73818,7 @@ case OP_AutoCommit: {
     }else{
       db->autoCommit = (u8)desiredAutoCommit;
       if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
-        p->pc = pc;
+        p->pc = (int)(pOp - aOp);
         db->autoCommit = (u8)(1-desiredAutoCommit);
         p->rc = rc = SQLITE_BUSY;
         goto vdbe_return;
@@ -71054,7 +73895,7 @@ case OP_Transaction: {
   if( pBt ){
     rc = sqlite3BtreeBeginTrans(pBt, pOp->p2);
     if( rc==SQLITE_BUSY ){
-      p->pc = pc;
+      p->pc = (int)(pOp - aOp);
       p->rc = rc = SQLITE_BUSY;
       goto vdbe_return;
     }
@@ -71084,7 +73925,12 @@ case OP_Transaction: {
       p->nStmtDefImmCons = db->nDeferredImmCons;
     }
 
-    /* Gather the schema version number for checking */
+    /* Gather the schema version number for checking:
+    ** IMPLEMENTATION-OF: R-32195-19465 The schema version is used by SQLite
+    ** each time a query is executed to ensure that the internal cache of the
+    ** schema used when compiling the SQL query matches the schema of the
+    ** database against which the compiled query is actually executed.
+    */
     sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&iMeta);
     iGen = db->aDb[pOp->p1].pSchema->iGeneration;
   }else{
@@ -71128,7 +73974,7 @@ case OP_Transaction: {
 ** must be started or there must be an open cursor) before
 ** executing this instruction.
 */
-case OP_ReadCookie: {               /* out2-prerelease */
+case OP_ReadCookie: {               /* out2 */
   int iMeta;
   int iDb;
   int iCookie;
@@ -71142,6 +73988,7 @@ case OP_ReadCookie: {               /* out2-prerelease */
   assert( DbMaskTest(p->btreeMask, iDb) );
 
   sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta);
+  pOut = out2Prerelease(p, pOp);
   pOut->u.i = iMeta;
   break;
 }
@@ -71252,37 +74099,35 @@ case OP_SetCookie: {       /* in3 */
 ** See also OpenRead.
 */
 case OP_ReopenIdx: {
+  int nField;
+  KeyInfo *pKeyInfo;
+  int p2;
+  int iDb;
+  int wrFlag;
+  Btree *pX;
   VdbeCursor *pCur;
+  Db *pDb;
 
-  assert( pOp->p5==0 );
+  assert( pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ );
   assert( pOp->p4type==P4_KEYINFO );
   pCur = p->apCsr[pOp->p1];
   if( pCur && pCur->pgnoRoot==(u32)pOp->p2 ){
     assert( pCur->iDb==pOp->p3 );      /* Guaranteed by the code generator */
-    break;
+    goto open_cursor_set_hints;
   }
   /* If the cursor is not currently open or is open on a different
   ** index, then fall through into OP_OpenRead to force a reopen */
-}
 case OP_OpenRead:
-case OP_OpenWrite: {
-  int nField;
-  KeyInfo *pKeyInfo;
-  int p2;
-  int iDb;
-  int wrFlag;
-  Btree *pX;
-  VdbeCursor *pCur;
-  Db *pDb;
+case OP_OpenWrite:
 
-  assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 );
-  assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 );
+  assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR|OPFLAG_SEEKEQ))==pOp->p5 );
+  assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 || pOp->p5==OPFLAG_SEEKEQ );
   assert( p->bIsReader );
   assert( pOp->opcode==OP_OpenRead || pOp->opcode==OP_ReopenIdx
           || p->readOnly==0 );
 
   if( p->expired ){
-    rc = SQLITE_ABORT;
+    rc = SQLITE_ABORT_ROLLBACK;
     break;
   }
 
@@ -71339,18 +74184,17 @@ case OP_OpenWrite: {
   pCur->pgnoRoot = p2;
   rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->pCursor);
   pCur->pKeyInfo = pKeyInfo;
-  assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
-  sqlite3BtreeCursorHints(pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR));
-
-  /* Since it performs no memory allocation or IO, the only value that
-  ** sqlite3BtreeCursor() may return is SQLITE_OK. */
-  assert( rc==SQLITE_OK );
-
   /* Set the VdbeCursor.isTable variable. Previous versions of
   ** SQLite used to check if the root-page flags were sane at this point
   ** and report database corruption if they were not, but this check has
   ** since moved into the btree layer.  */  
   pCur->isTable = pOp->p4type!=P4_KEYINFO;
+
+open_cursor_set_hints:
+  assert( OPFLAG_BULKCSR==BTREE_BULKLOAD );
+  assert( OPFLAG_SEEKEQ==BTREE_SEEK_EQ );
+  sqlite3BtreeCursorHints(pCur->pCursor,
+                          (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ)));
   break;
 }
 
@@ -71429,11 +74273,15 @@ case OP_OpenEphemeral: {
   break;
 }
 
-/* Opcode: SorterOpen P1 P2 * P4 *
+/* Opcode: SorterOpen P1 P2 P3 P4 *
 **
 ** This opcode works like OP_OpenEphemeral except that it opens
 ** a transient index that is specifically designed to sort large
 ** tables using an external merge-sort algorithm.
+**
+** If argument P3 is non-zero, then it indicates that the sorter may
+** assume that a stable sort considering the first P3 fields of each
+** key is sufficient to produce the required results.
 */
 case OP_SorterOpen: {
   VdbeCursor *pCx;
@@ -71445,7 +74293,25 @@ case OP_SorterOpen: {
   pCx->pKeyInfo = pOp->p4.pKeyInfo;
   assert( pCx->pKeyInfo->db==db );
   assert( pCx->pKeyInfo->enc==ENC(db) );
-  rc = sqlite3VdbeSorterInit(db, pCx);
+  rc = sqlite3VdbeSorterInit(db, pOp->p3, pCx);
+  break;
+}
+
+/* Opcode: SequenceTest P1 P2 * * *
+** Synopsis: if( cursor[P1].ctr++ ) pc = P2
+**
+** P1 is a sorter cursor. If the sequence counter is currently zero, jump
+** to P2. Regardless of whether or not the jump is taken, increment the
+** the sequence value.
+*/
+case OP_SequenceTest: {
+  VdbeCursor *pC;
+  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+  pC = p->apCsr[pOp->p1];
+  assert( pC->pSorter );
+  if( (pC->seqCount++)==0 ){
+    goto jump_to_p2;
+  }
   break;
 }
 
@@ -71589,14 +74455,31 @@ case OP_SeekGT: {       /* jump, in3 */
 #ifdef SQLITE_DEBUG
   pC->seekOp = pOp->opcode;
 #endif
+
+  /* For a cursor with the BTREE_SEEK_EQ hint, only the OP_SeekGE and
+  ** OP_SeekLE opcodes are allowed, and these must be immediately followed
+  ** by an OP_IdxGT or OP_IdxLT opcode, respectively, with the same key.
+  */
+#ifdef SQLITE_DEBUG
+  if( sqlite3BtreeCursorHasHint(pC->pCursor, BTREE_SEEK_EQ) ){
+    assert( pOp->opcode==OP_SeekGE || pOp->opcode==OP_SeekLE );
+    assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT );
+    assert( pOp[1].p1==pOp[0].p1 );
+    assert( pOp[1].p2==pOp[0].p2 );
+    assert( pOp[1].p3==pOp[0].p3 );
+    assert( pOp[1].p4.i==pOp[0].p4.i );
+  }
+#endif
+ 
   if( pC->isTable ){
     /* The input value in P3 might be of any type: integer, real, string,
     ** blob, or NULL.  But it needs to be an integer before we can do
-    ** the seek, so covert it. */
+    ** the seek, so convert it. */
     pIn3 = &aMem[pOp->p3];
-    ApplyNumericAffinity(pIn3);
+    if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_Str))==MEM_Str ){
+      applyNumericAffinity(pIn3, 0);
+    }
     iKey = sqlite3VdbeIntValue(pIn3);
-    pC->rowidIsValid = 0;
 
     /* If the P3 value could not be converted into an integer without
     ** loss of information, then special processing is required... */
@@ -71604,7 +74487,7 @@ case OP_SeekGT: {       /* jump, in3 */
       if( (pIn3->flags & MEM_Real)==0 ){
         /* If the P3 value cannot be converted into any kind of a number,
         ** then the seek is not possible, so jump to P2 */
-        pc = pOp->p2 - 1;  VdbeBranchTaken(1,2);
+        VdbeBranchTaken(1,2); goto jump_to_p2;
         break;
       }
 
@@ -71615,7 +74498,7 @@ case OP_SeekGT: {       /* jump, in3 */
       **        (x >  4.9)    ->     (x >= 5)
       **        (x <= 4.9)    ->     (x <  5)
       */
-      if( pIn3->r<(double)iKey ){
+      if( pIn3->u.r<(double)iKey ){
         assert( OP_SeekGE==(OP_SeekGT-1) );
         assert( OP_SeekLT==(OP_SeekLE-1) );
         assert( (OP_SeekLE & 0x0001)==(OP_SeekGT & 0x0001) );
@@ -71624,7 +74507,7 @@ case OP_SeekGT: {       /* jump, in3 */
 
       /* If the approximation iKey is smaller than the actual real search
       ** term, substitute <= for < and > for >=.  */
-      else if( pIn3->r>(double)iKey ){
+      else if( pIn3->u.r>(double)iKey ){
         assert( OP_SeekLE==(OP_SeekLT+1) );
         assert( OP_SeekGT==(OP_SeekGE+1) );
         assert( (OP_SeekLT & 0x0001)==(OP_SeekGE & 0x0001) );
@@ -71632,13 +74515,10 @@ case OP_SeekGT: {       /* jump, in3 */
       }
     } 
     rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)iKey, 0, &res);
+    pC->movetoTarget = iKey;  /* Used by OP_Delete */
     if( rc!=SQLITE_OK ){
       goto abort_due_to_error;
     }
-    if( res==0 ){
-      pC->rowidIsValid = 1;
-      pC->lastRowid = iKey;
-    }
   }else{
     nField = pOp->p4.i;
     assert( pOp->p4type==P4_INT32 );
@@ -71668,7 +74548,6 @@ case OP_SeekGT: {       /* jump, in3 */
     if( rc!=SQLITE_OK ){
       goto abort_due_to_error;
     }
-    pC->rowidIsValid = 0;
   }
   pC->deferredMoveto = 0;
   pC->cacheStatus = CACHE_STALE;
@@ -71680,7 +74559,6 @@ case OP_SeekGT: {       /* jump, in3 */
       res = 0;
       rc = sqlite3BtreeNext(pC->pCursor, &res);
       if( rc!=SQLITE_OK ) goto abort_due_to_error;
-      pC->rowidIsValid = 0;
     }else{
       res = 0;
     }
@@ -71690,7 +74568,6 @@ case OP_SeekGT: {       /* jump, in3 */
       res = 0;
       rc = sqlite3BtreePrevious(pC->pCursor, &res);
       if( rc!=SQLITE_OK ) goto abort_due_to_error;
-      pC->rowidIsValid = 0;
     }else{
       /* res might be negative because the table is empty.  Check to
       ** see if this is the case.
@@ -71701,7 +74578,7 @@ case OP_SeekGT: {       /* jump, in3 */
   assert( pOp->p2>0 );
   VdbeBranchTaken(res!=0,2);
   if( res ){
-    pc = pOp->p2 - 1;
+    goto jump_to_p2;
   }
   break;
 }
@@ -71727,7 +74604,6 @@ case OP_Seek: {    /* in2 */
   pC->nullRow = 0;
   pIn2 = &aMem[pOp->p2];
   pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
-  pC->rowidIsValid = 0;
   pC->deferredMoveto = 1;
   break;
 }
@@ -71796,6 +74672,7 @@ case OP_NoConflict:     /* jump, in3 */
 case OP_NotFound:       /* jump, in3 */
 case OP_Found: {        /* jump, in3 */
   int alreadyExists;
+  int takeJump;
   int ii;
   VdbeCursor *pC;
   int res;
@@ -71818,7 +74695,7 @@ case OP_Found: {        /* jump, in3 */
   pIn3 = &aMem[pOp->p3];
   assert( pC->pCursor!=0 );
   assert( pC->isTable==0 );
-  pFree = 0;  /* Not needed.  Only used to suppress a compiler warning. */
+  pFree = 0;
   if( pOp->p4.i>0 ){
     r.pKeyInfo = pC->pKeyInfo;
     r.nField = (u16)pOp->p4.i;
@@ -71834,28 +74711,27 @@ case OP_Found: {        /* jump, in3 */
   }else{
     pIdxKey = sqlite3VdbeAllocUnpackedRecord(
         pC->pKeyInfo, aTempRec, sizeof(aTempRec), &pFree
-    ); 
+    );
     if( pIdxKey==0 ) goto no_mem;
     assert( pIn3->flags & MEM_Blob );
-    assert( (pIn3->flags & MEM_Zero)==0 );  /* zeroblobs already expanded */
+    ExpandBlob(pIn3);
     sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey);
   }
   pIdxKey->default_rc = 0;
+  takeJump = 0;
   if( pOp->opcode==OP_NoConflict ){
     /* For the OP_NoConflict opcode, take the jump if any of the
     ** input fields are NULL, since any key with a NULL will not
     ** conflict */
-    for(ii=0; ii<r.nField; ii++){
-      if( r.aMem[ii].flags & MEM_Null ){
-        pc = pOp->p2 - 1; VdbeBranchTaken(1,2);
+    for(ii=0; ii<pIdxKey->nField; ii++){
+      if( pIdxKey->aMem[ii].flags & MEM_Null ){
+        takeJump = 1;
         break;
       }
     }
   }
   rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, pIdxKey, 0, 0, &res);
-  if( pOp->p4.i==0 ){
-    sqlite3DbFree(db, pFree);
-  }
+  sqlite3DbFree(db, pFree);
   if( rc!=SQLITE_OK ){
     break;
   }
@@ -71866,10 +74742,10 @@ case OP_Found: {        /* jump, in3 */
   pC->cacheStatus = CACHE_STALE;
   if( pOp->opcode==OP_Found ){
     VdbeBranchTaken(alreadyExists!=0,2);
-    if( alreadyExists ) pc = pOp->p2 - 1;
+    if( alreadyExists ) goto jump_to_p2;
   }else{
-    VdbeBranchTaken(alreadyExists==0,2);
-    if( !alreadyExists ) pc = pOp->p2 - 1;
+    VdbeBranchTaken(takeJump||alreadyExists==0,2);
+    if( takeJump || !alreadyExists ) goto jump_to_p2;
   }
   break;
 }
@@ -71913,17 +74789,13 @@ case OP_NotExists: {        /* jump, in3 */
   res = 0;
   iKey = pIn3->u.i;
   rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res);
-  pC->lastRowid = pIn3->u.i;
-  pC->rowidIsValid = res==0 ?1:0;
+  pC->movetoTarget = iKey;  /* Used by OP_Delete */
   pC->nullRow = 0;
   pC->cacheStatus = CACHE_STALE;
   pC->deferredMoveto = 0;
   VdbeBranchTaken(res!=0,2);
-  if( res!=0 ){
-    pc = pOp->p2 - 1;
-    assert( pC->rowidIsValid==0 );
-  }
   pC->seekResult = res;
+  if( res!=0 ) goto jump_to_p2;
   break;
 }
 
@@ -71935,9 +74807,10 @@ case OP_NotExists: {        /* jump, in3 */
 ** The sequence number on the cursor is incremented after this
 ** instruction.  
 */
-case OP_Sequence: {           /* out2-prerelease */
+case OP_Sequence: {           /* out2 */
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
   assert( p->apCsr[pOp->p1]!=0 );
+  pOut = out2Prerelease(p, pOp);
   pOut->u.i = p->apCsr[pOp->p1]->seqCount++;
   break;
 }
@@ -71958,7 +74831,7 @@ case OP_Sequence: {           /* out2-prerelease */
 ** generated record number. This P3 mechanism is used to help implement the
 ** AUTOINCREMENT feature.
 */
-case OP_NewRowid: {           /* out2-prerelease */
+case OP_NewRowid: {           /* out2 */
   i64 v;                 /* The new rowid */
   VdbeCursor *pC;        /* Cursor of table to get the new rowid */
   int res;               /* Result of an sqlite3BtreeLast() */
@@ -71968,6 +74841,7 @@ case OP_NewRowid: {           /* out2-prerelease */
 
   v = 0;
   res = 0;
+  pOut = out2Prerelease(p, pOp);
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
   pC = p->apCsr[pOp->p1];
   assert( pC!=0 );
@@ -72055,32 +74929,20 @@ case OP_NewRowid: {           /* out2-prerelease */
       ** it finds one that is not previously used. */
       assert( pOp->p3==0 );  /* We cannot be in random rowid mode if this is
                              ** an AUTOINCREMENT table. */
-      /* on the first attempt, simply do one more than previous */
-      v = lastRowid;
-      v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
-      v++; /* ensure non-zero */
       cnt = 0;
-      while(   ((rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)v,
+      do{
+        sqlite3_randomness(sizeof(v), &v);
+        v &= (MAX_ROWID>>1); v++;  /* Ensure that v is greater than zero */
+      }while(  ((rc = sqlite3BtreeMovetoUnpacked(pC->pCursor, 0, (u64)v,
                                                  0, &res))==SQLITE_OK)
             && (res==0)
-            && (++cnt<100)){
-        /* collision - try another random rowid */
-        sqlite3_randomness(sizeof(v), &v);
-        if( cnt<5 ){
-          /* try "small" random rowids for the initial attempts */
-          v &= 0xffffff;
-        }else{
-          v &= (MAX_ROWID>>1); /* ensure doesn't go negative */
-        }
-        v++; /* ensure non-zero */
-      }
+            && (++cnt<100));
       if( rc==SQLITE_OK && res==0 ){
         rc = SQLITE_FULL;   /* IMP: R-38219-53002 */
         goto abort_due_to_error;
       }
       assert( v>0 );  /* EV: R-40812-03570 */
     }
-    pC->rowidIsValid = 0;
     pC->deferredMoveto = 0;
     pC->cacheStatus = CACHE_STALE;
   }
@@ -72185,7 +75047,6 @@ case OP_InsertInt: {
                           pData->z, pData->n, nZero,
                           (pOp->p5 & OPFLAG_APPEND)!=0, seekResult
   );
-  pC->rowidIsValid = 0;
   pC->deferredMoveto = 0;
   pC->cacheStatus = CACHE_STALE;
 
@@ -72222,33 +75083,32 @@ case OP_InsertInt: {
 ** using OP_NotFound prior to invoking this opcode.
 */
 case OP_Delete: {
-  i64 iKey;
   VdbeCursor *pC;
 
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
   pC = p->apCsr[pOp->p1];
   assert( pC!=0 );
   assert( pC->pCursor!=0 );  /* Only valid for real tables, no pseudotables */
-  iKey = pC->lastRowid;      /* Only used for the update hook */
-
-  /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or
-  ** OP_Column on the same table without any intervening operations that
-  ** might move or invalidate the cursor.  Hence cursor pC is always pointing
-  ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation
-  ** below is always a no-op and cannot fail.  We will run it anyhow, though,
-  ** to guard against future changes to the code generator.
-  **/
   assert( pC->deferredMoveto==0 );
-  rc = sqlite3VdbeCursorMoveto(pC);
-  if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
 
+#ifdef SQLITE_DEBUG
+  /* The seek operation that positioned the cursor prior to OP_Delete will
+  ** have also set the pC->movetoTarget field to the rowid of the row that
+  ** is being deleted */
+  if( pOp->p4.z && pC->isTable ){
+    i64 iKey = 0;
+    sqlite3BtreeKeySize(pC->pCursor, &iKey);
+    assert( pC->movetoTarget==iKey ); 
+  }
+#endif
+ 
   rc = sqlite3BtreeDelete(pC->pCursor);
   pC->cacheStatus = CACHE_STALE;
 
   /* Invoke the update-hook if required. */
   if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && pC->isTable ){
     db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE,
-                        db->aDb[pC->iDb].zName, pOp->p4.z, iKey);
+                        db->aDb[pC->iDb].zName, pOp->p4.z, pC->movetoTarget);
     assert( pC->iDb>=0 );
   }
   if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++;
@@ -72292,18 +75152,24 @@ case OP_SorterCompare: {
   assert( pOp->p4type==P4_INT32 );
   pIn3 = &aMem[pOp->p3];
   nKeyCol = pOp->p4.i;
+  res = 0;
   rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res);
   VdbeBranchTaken(res!=0,2);
-  if( res ){
-    pc = pOp->p2-1;
-  }
+  if( res ) goto jump_to_p2;
   break;
 };
 
-/* Opcode: SorterData P1 P2 * * *
+/* Opcode: SorterData P1 P2 P3 * *
 ** Synopsis: r[P2]=data
 **
 ** Write into register P2 the current sorter data for sorter cursor P1.
+** Then clear the column header cache on cursor P3.
+**
+** This opcode is normally use to move a record out of the sorter and into
+** a register that is the source for a pseudo-table cursor created using
+** OpenPseudo.  That pseudo-table cursor is the one that is identified by
+** parameter P3.  Clearing the P3 column cache as part of this opcode saves
+** us from having to issue a separate NullRow instruction to clear that cache.
 */
 case OP_SorterData: {
   VdbeCursor *pC;
@@ -72313,6 +75179,8 @@ case OP_SorterData: {
   assert( isSorter(pC) );
   rc = sqlite3VdbeSorterRowkey(pC, pOut);
   assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) );
+  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
+  p->apCsr[pOp->p3]->cacheStatus = CACHE_STALE;
   break;
 }
 
@@ -72359,16 +75227,20 @@ case OP_RowData: {
   assert( pC->pseudoTableReg==0 );
   assert( pC->pCursor!=0 );
   pCrsr = pC->pCursor;
-  assert( sqlite3BtreeCursorIsValid(pCrsr) );
 
   /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or
   ** OP_Rewind/Op_Next with no intervening instructions that might invalidate
-  ** the cursor.  Hence the following sqlite3VdbeCursorMoveto() call is always
-  ** a no-op and can never fail.  But we leave it in place as a safety.
+  ** the cursor.  If this where not the case, on of the following assert()s
+  ** would fail.  Should this ever change (because of changes in the code
+  ** generator) then the fix would be to insert a call to
+  ** sqlite3VdbeCursorMoveto().
   */
   assert( pC->deferredMoveto==0 );
+  assert( sqlite3BtreeCursorIsValid(pCrsr) );
+#if 0  /* Not required due to the previous to assert() statements */
   rc = sqlite3VdbeCursorMoveto(pC);
-  if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
+  if( rc!=SQLITE_OK ) goto abort_due_to_error;
+#endif
 
   if( pC->isTable==0 ){
     assert( !pC->isTable );
@@ -72385,7 +75257,8 @@ case OP_RowData: {
       goto too_big;
     }
   }
-  if( sqlite3VdbeMemGrow(pOut, n, 0) ){
+  testcase( n==0 );
+  if( sqlite3VdbeMemClearAndResize(pOut, MAX(n,32)) ){
     goto no_mem;
   }
   pOut->n = n;
@@ -72411,12 +75284,13 @@ case OP_RowData: {
 ** be a separate OP_VRowid opcode for use with virtual tables, but this
 ** one opcode now works for both table types.
 */
-case OP_Rowid: {                 /* out2-prerelease */
+case OP_Rowid: {                 /* out2 */
   VdbeCursor *pC;
   i64 v;
   sqlite3_vtab *pVtab;
   const sqlite3_module *pModule;
 
+  pOut = out2Prerelease(p, pOp);
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
   pC = p->apCsr[pOp->p1];
   assert( pC!=0 );
@@ -72436,14 +75310,14 @@ case OP_Rowid: {                 /* out2-prerelease */
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
   }else{
     assert( pC->pCursor!=0 );
-    rc = sqlite3VdbeCursorMoveto(pC);
+    rc = sqlite3VdbeCursorRestore(pC);
     if( rc ) goto abort_due_to_error;
-    if( pC->rowidIsValid ){
-      v = pC->lastRowid;
-    }else{
-      rc = sqlite3BtreeKeySize(pC->pCursor, &v);
-      assert( rc==SQLITE_OK );  /* Always so because of CursorMoveto() above */
+    if( pC->nullRow ){
+      pOut->flags = MEM_Null;
+      break;
     }
+    rc = sqlite3BtreeKeySize(pC->pCursor, &v);
+    assert( rc==SQLITE_OK );  /* Always so because of CursorRestore() above */
   }
   pOut->u.i = v;
   break;
@@ -72462,7 +75336,6 @@ case OP_NullRow: {
   pC = p->apCsr[pOp->p1];
   assert( pC!=0 );
   pC->nullRow = 1;
-  pC->rowidIsValid = 0;
   pC->cacheStatus = CACHE_STALE;
   if( pC->pCursor ){
     sqlite3BtreeClearCursor(pC->pCursor);
@@ -72470,7 +75343,7 @@ case OP_NullRow: {
   break;
 }
 
-/* Opcode: Last P1 P2 * * *
+/* Opcode: Last P1 P2 P3 * *
 **
 ** The next use of the Rowid or Column or Prev instruction for P1 
 ** will refer to the last entry in the database table or index.
@@ -72496,14 +75369,14 @@ case OP_Last: {        /* jump */
   rc = sqlite3BtreeLast(pCrsr, &res);
   pC->nullRow = (u8)res;
   pC->deferredMoveto = 0;
-  pC->rowidIsValid = 0;
   pC->cacheStatus = CACHE_STALE;
+  pC->seekResult = pOp->p3;
 #ifdef SQLITE_DEBUG
   pC->seekOp = OP_Last;
 #endif
   if( pOp->p2>0 ){
     VdbeBranchTaken(res!=0,2);
-    if( res ) pc = pOp->p2 - 1;
+    if( res ) goto jump_to_p2;
   }
   break;
 }
@@ -72534,9 +75407,9 @@ case OP_Sort: {        /* jump */
 **
 ** The next use of the Rowid or Column or Next instruction for P1 
 ** will refer to the first entry in the database table or index.
-** If the table or index is empty and P2>0, then jump immediately to P2.
-** If P2 is 0 or if the table or index is not empty, fall through
-** to the following instruction.
+** If the table or index is empty, jump immediately to P2.
+** If the table or index is not empty, fall through to the following 
+** instruction.
 **
 ** This opcode leaves the cursor configured to move in forward order,
 ** from the beginning toward the end.  In other words, the cursor is
@@ -72556,21 +75429,18 @@ case OP_Rewind: {        /* jump */
   pC->seekOp = OP_Rewind;
 #endif
   if( isSorter(pC) ){
-    rc = sqlite3VdbeSorterRewind(db, pC, &res);
+    rc = sqlite3VdbeSorterRewind(pC, &res);
   }else{
     pCrsr = pC->pCursor;
     assert( pCrsr );
     rc = sqlite3BtreeFirst(pCrsr, &res);
     pC->deferredMoveto = 0;
     pC->cacheStatus = CACHE_STALE;
-    pC->rowidIsValid = 0;
   }
   pC->nullRow = (u8)res;
   assert( pOp->p2>0 && pOp->p2<p->nOp );
   VdbeBranchTaken(res!=0,2);
-  if( res ){
-    pc = pOp->p2 - 1;
-  }
+  if( res ) goto jump_to_p2;
   break;
 }
 
@@ -72681,15 +75551,14 @@ next_tail:
   VdbeBranchTaken(res==0,2);
   if( res==0 ){
     pC->nullRow = 0;
-    pc = pOp->p2 - 1;
     p->aCounter[pOp->p5]++;
 #ifdef SQLITE_TEST
     sqlite3_search_count++;
 #endif
+    goto jump_to_p2_and_check_for_interrupt;
   }else{
     pC->nullRow = 1;
   }
-  pC->rowidIsValid = 0;
   goto check_for_interrupt;
 }
 
@@ -72734,7 +75603,7 @@ case OP_IdxInsert: {        /* in2 */
   rc = ExpandBlob(pIn2);
   if( rc==SQLITE_OK ){
     if( isSorter(pC) ){
-      rc = sqlite3VdbeSorterWrite(db, pC, pIn2);
+      rc = sqlite3VdbeSorterWrite(pC, pIn2);
     }else{
       nKey = pIn2->n;
       zKey = pIn2->z;
@@ -72794,21 +75663,28 @@ case OP_IdxDelete: {
 **
 ** See also: Rowid, MakeRecord.
 */
-case OP_IdxRowid: {              /* out2-prerelease */
+case OP_IdxRowid: {              /* out2 */
   BtCursor *pCrsr;
   VdbeCursor *pC;
   i64 rowid;
 
+  pOut = out2Prerelease(p, pOp);
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
   pC = p->apCsr[pOp->p1];
   assert( pC!=0 );
   pCrsr = pC->pCursor;
   assert( pCrsr!=0 );
   pOut->flags = MEM_Null;
-  rc = sqlite3VdbeCursorMoveto(pC);
-  if( NEVER(rc) ) goto abort_due_to_error;
-  assert( pC->deferredMoveto==0 );
   assert( pC->isTable==0 );
+  assert( pC->deferredMoveto==0 );
+
+  /* sqlite3VbeCursorRestore() can only fail if the record has been deleted
+  ** out from under the cursor.  That will never happend for an IdxRowid
+  ** opcode, hence the NEVER() arround the check of the return value.
+  */
+  rc = sqlite3VdbeCursorRestore(pC);
+  if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
+
   if( !pC->nullRow ){
     rowid = 0;  /* Not needed.  Only used to silence a warning. */
     rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid);
@@ -72895,7 +75771,7 @@ case OP_IdxGE:  {       /* jump */
   { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
 #endif
   res = 0;  /* Not needed.  Only used to silence a warning. */
-  rc = sqlite3VdbeIdxKeyCompare(pC, &r, &res);
+  rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res);
   assert( (OP_IdxLE&1)==(OP_IdxLT&1) && (OP_IdxGE&1)==(OP_IdxGT&1) );
   if( (pOp->opcode&1)==(OP_IdxLT&1) ){
     assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxLT );
@@ -72905,9 +75781,7 @@ case OP_IdxGE:  {       /* jump */
     res++;
   }
   VdbeBranchTaken(res>0,2);
-  if( res>0 ){
-    pc = pOp->p2 - 1 ;
-  }
+  if( res>0 ) goto jump_to_p2;
   break;
 }
 
@@ -72931,32 +75805,18 @@ case OP_IdxGE:  {       /* jump */
 **
 ** See also: Clear
 */
-case OP_Destroy: {     /* out2-prerelease */
+case OP_Destroy: {     /* out2 */
   int iMoved;
-  int iCnt;
-  Vdbe *pVdbe;
   int iDb;
 
   assert( p->readOnly==0 );
-#ifndef SQLITE_OMIT_VIRTUALTABLE
-  iCnt = 0;
-  for(pVdbe=db->pVdbe; pVdbe; pVdbe = pVdbe->pNext){
-    if( pVdbe->magic==VDBE_MAGIC_RUN && pVdbe->bIsReader 
-     && pVdbe->inVtabMethod<2 && pVdbe->pc>=0 
-    ){
-      iCnt++;
-    }
-  }
-#else
-  iCnt = db->nVdbeRead;
-#endif
+  pOut = out2Prerelease(p, pOp);
   pOut->flags = MEM_Null;
-  if( iCnt>1 ){
+  if( db->nVdbeRead > db->nVDestroy+1 ){
     rc = SQLITE_LOCKED;
     p->errorAction = OE_Abort;
   }else{
     iDb = pOp->p3;
-    assert( iCnt==1 );
     assert( DbMaskTest(p->btreeMask, iDb) );
     iMoved = 0;  /* Not needed.  Only to silence a warning. */
     rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved);
@@ -73059,12 +75919,13 @@ case OP_ResetSorter: {
 **
 ** See documentation on OP_CreateTable for additional information.
 */
-case OP_CreateIndex:            /* out2-prerelease */
-case OP_CreateTable: {          /* out2-prerelease */
+case OP_CreateIndex:            /* out2 */
+case OP_CreateTable: {          /* out2 */
   int pgno;
   int flags;
   Db *pDb;
 
+  pOut = out2Prerelease(p, pOp);
   pgno = 0;
   assert( pOp->p1>=0 && pOp->p1<db->nDb );
   assert( DbMaskTest(p->btreeMask, pOp->p1) );
@@ -73290,12 +76151,12 @@ case OP_RowSetRead: {       /* jump, in1, out3 */
   ){
     /* The boolean index is empty */
     sqlite3VdbeMemSetNull(pIn1);
-    pc = pOp->p2 - 1;
     VdbeBranchTaken(1,2);
+    goto jump_to_p2_and_check_for_interrupt;
   }else{
     /* A value was pulled from the index */
-    sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val);
     VdbeBranchTaken(0,2);
+    sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val);
   }
   goto check_for_interrupt;
 }
@@ -73346,10 +76207,7 @@ case OP_RowSetTest: {                     /* jump, in1, in3 */
   if( iSet ){
     exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet, pIn3->u.i);
     VdbeBranchTaken(exists!=0,2);
-    if( exists ){
-      pc = pOp->p2 - 1;
-      break;
-    }
+    if( exists ) goto jump_to_p2;
   }
   if( iSet>=0 ){
     sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i);
@@ -73438,7 +76296,7 @@ case OP_Program: {        /* jump */
     pFrame->v = p;
     pFrame->nChildMem = nMem;
     pFrame->nChildCsr = pProgram->nCsr;
-    pFrame->pc = pc;
+    pFrame->pc = (int)(pOp - aOp);
     pFrame->aMem = p->aMem;
     pFrame->nMem = p->nMem;
     pFrame->apCsr = p->apCsr;
@@ -73448,6 +76306,9 @@ case OP_Program: {        /* jump */
     pFrame->token = pProgram->token;
     pFrame->aOnceFlag = p->aOnceFlag;
     pFrame->nOnceFlag = p->nOnceFlag;
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+    pFrame->anExec = p->anExec;
+#endif
 
     pEnd = &VdbeFrameMem(pFrame)[pFrame->nChildMem];
     for(pMem=VdbeFrameMem(pFrame); pMem!=pEnd; pMem++){
@@ -73458,13 +76319,14 @@ case OP_Program: {        /* jump */
     pFrame = pRt->u.pFrame;
     assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem );
     assert( pProgram->nCsr==pFrame->nChildCsr );
-    assert( pc==pFrame->pc );
+    assert( (int)(pOp - aOp)==pFrame->pc );
   }
 
   p->nFrame++;
   pFrame->pParent = p->pFrame;
   pFrame->lastRowid = lastRowid;
   pFrame->nChange = p->nChange;
+  pFrame->nDbChange = p->db->nChange;
   p->nChange = 0;
   p->pFrame = pFrame;
   p->aMem = aMem = &VdbeFrameMem(pFrame)[-1];
@@ -73475,7 +76337,10 @@ case OP_Program: {        /* jump */
   p->nOp = pProgram->nOp;
   p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor];
   p->nOnceFlag = pProgram->nOnce;
-  pc = -1;
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+  p->anExec = 0;
+#endif
+  pOp = &aOp[-1];
   memset(p->aOnceFlag, 0, p->nOnceFlag);
 
   break;
@@ -73493,9 +76358,10 @@ case OP_Program: {        /* jump */
 ** the value of the P1 argument to the value of the P1 argument to the
 ** calling OP_Program instruction.
 */
-case OP_Param: {           /* out2-prerelease */
+case OP_Param: {           /* out2 */
   VdbeFrame *pFrame;
   Mem *pIn;
+  pOut = out2Prerelease(p, pOp);
   pFrame = p->pFrame;
   pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1];   
   sqlite3VdbeMemShallowCopy(pOut, pIn, MEM_Ephem);
@@ -73539,10 +76405,10 @@ case OP_FkCounter: {
 case OP_FkIfZero: {         /* jump */
   if( pOp->p1 ){
     VdbeBranchTaken(db->nDeferredCons==0 && db->nDeferredImmCons==0, 2);
-    if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
+    if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) goto jump_to_p2;
   }else{
     VdbeBranchTaken(p->nFkConstraint==0 && db->nDeferredImmCons==0, 2);
-    if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
+    if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) goto jump_to_p2;
   }
   break;
 }
@@ -73582,18 +76448,18 @@ case OP_MemMax: {        /* in2 */
 /* Opcode: IfPos P1 P2 * * *
 ** Synopsis: if r[P1]>0 goto P2
 **
-** If the value of register P1 is 1 or greater, jump to P2.
+** Register P1 must contain an integer.
+** If the value of register P1 is 1 or greater, jump to P2 and
+** add the literal value P3 to register P1.
 **
-** It is illegal to use this instruction on a register that does
-** not contain an integer.  An assertion fault will result if you try.
+** If the initial value of register P1 is less than 1, then the
+** value is unchanged and control passes through to the next instruction.
 */
 case OP_IfPos: {        /* jump, in1 */
   pIn1 = &aMem[pOp->p1];
   assert( pIn1->flags&MEM_Int );
   VdbeBranchTaken( pIn1->u.i>0, 2);
-  if( pIn1->u.i>0 ){
-     pc = pOp->p2 - 1;
-  }
+  if( pIn1->u.i>0 ) goto jump_to_p2;
   break;
 }
 
@@ -73608,26 +76474,56 @@ case OP_IfNeg: {        /* jump, in1 */
   assert( pIn1->flags&MEM_Int );
   pIn1->u.i += pOp->p3;
   VdbeBranchTaken(pIn1->u.i<0, 2);
-  if( pIn1->u.i<0 ){
-     pc = pOp->p2 - 1;
+  if( pIn1->u.i<0 ) goto jump_to_p2;
+  break;
+}
+
+/* Opcode: IfNotZero P1 P2 P3 * *
+** Synopsis: if r[P1]!=0 then r[P1]+=P3, goto P2
+**
+** Register P1 must contain an integer.  If the content of register P1 is
+** initially nonzero, then add P3 to P1 and jump to P2.  If register P1 is
+** initially zero, leave it unchanged and fall through.
+*/
+case OP_IfNotZero: {        /* jump, in1 */
+  pIn1 = &aMem[pOp->p1];
+  assert( pIn1->flags&MEM_Int );
+  VdbeBranchTaken(pIn1->u.i<0, 2);
+  if( pIn1->u.i ){
+     pIn1->u.i += pOp->p3;
+     goto jump_to_p2;
   }
   break;
 }
 
-/* Opcode: IfZero P1 P2 P3 * *
-** Synopsis: r[P1]+=P3, if r[P1]==0 goto P2
+/* Opcode: DecrJumpZero P1 P2 * * *
+** Synopsis: if (--r[P1])==0 goto P2
 **
-** The register P1 must contain an integer.  Add literal P3 to the
-** value in register P1.  If the result is exactly 0, jump to P2. 
+** Register P1 must hold an integer.  Decrement the value in register P1
+** then jump to P2 if the new value is exactly zero.
 */
-case OP_IfZero: {        /* jump, in1 */
+case OP_DecrJumpZero: {      /* jump, in1 */
   pIn1 = &aMem[pOp->p1];
   assert( pIn1->flags&MEM_Int );
-  pIn1->u.i += pOp->p3;
+  pIn1->u.i--;
   VdbeBranchTaken(pIn1->u.i==0, 2);
-  if( pIn1->u.i==0 ){
-     pc = pOp->p2 - 1;
-  }
+  if( pIn1->u.i==0 ) goto jump_to_p2;
+  break;
+}
+
+
+/* Opcode: JumpZeroIncr P1 P2 * * *
+** Synopsis: if (r[P1]++)==0 ) goto P2
+**
+** The register P1 must contain an integer.  If register P1 is initially
+** zero, then jump to P2.  Increment register P1 regardless of whether or
+** not the jump is taken.
+*/
+case OP_JumpZeroIncr: {        /* jump, in1 */
+  pIn1 = &aMem[pOp->p1];
+  assert( pIn1->flags&MEM_Int );
+  VdbeBranchTaken(pIn1->u.i==0, 2);
+  if( (pIn1->u.i++)==0 ) goto jump_to_p2;
   break;
 }
 
@@ -73647,6 +76543,7 @@ case OP_AggStep: {
   int i;
   Mem *pMem;
   Mem *pRec;
+  Mem t;
   sqlite3_context ctx;
   sqlite3_value **apVal;
 
@@ -73664,23 +76561,15 @@ case OP_AggStep: {
   assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
   ctx.pMem = pMem = &aMem[pOp->p3];
   pMem->n++;
-  ctx.s.flags = MEM_Null;
-  ctx.s.z = 0;
-  ctx.s.zMalloc = 0;
-  ctx.s.xDel = 0;
-  ctx.s.db = db;
+  sqlite3VdbeMemInit(&t, db, MEM_Null);
+  ctx.pOut = &t;
   ctx.isError = 0;
-  ctx.pColl = 0;
+  ctx.pVdbe = p;
+  ctx.iOp = (int)(pOp - aOp);
   ctx.skipFlag = 0;
-  if( ctx.pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
-    assert( pOp>p->aOp );
-    assert( pOp[-1].p4type==P4_COLLSEQ );
-    assert( pOp[-1].opcode==OP_CollSeq );
-    ctx.pColl = pOp[-1].p4.pColl;
-  }
   (ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
   if( ctx.isError ){
-    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s));
+    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&t));
     rc = ctx.isError;
   }
   if( ctx.skipFlag ){
@@ -73688,9 +76577,7 @@ case OP_AggStep: {
     i = pOp[-1].p1;
     if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1);
   }
-
-  sqlite3VdbeMemRelease(&ctx.s);
-
+  sqlite3VdbeMemRelease(&t);
   break;
 }
 
@@ -73728,8 +76615,8 @@ case OP_AggFinal: {
 /* Opcode: Checkpoint P1 P2 P3 * *
 **
 ** Checkpoint database P1. This is a no-op if P1 is not currently in
-** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL
-** or RESTART.  Write 1 or 0 into mem[P3] if the checkpoint returns
+** WAL mode. Parameter P2 is one of SQLITE_CHECKPOINT_PASSIVE, FULL,
+** RESTART, or TRUNCATE.  Write 1 or 0 into mem[P3] if the checkpoint returns
 ** SQLITE_BUSY or not, respectively.  Write the number of pages in the
 ** WAL after the checkpoint into mem[P3+1] and the number of pages
 ** in the WAL that have been checkpointed after the checkpoint
@@ -73747,6 +76634,7 @@ case OP_Checkpoint: {
   assert( pOp->p2==SQLITE_CHECKPOINT_PASSIVE
        || pOp->p2==SQLITE_CHECKPOINT_FULL
        || pOp->p2==SQLITE_CHECKPOINT_RESTART
+       || pOp->p2==SQLITE_CHECKPOINT_TRUNCATE
   );
   rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]);
   if( rc==SQLITE_BUSY ){
@@ -73772,7 +76660,7 @@ case OP_Checkpoint: {
 **
 ** Write a string containing the final journal-mode to register P2.
 */
-case OP_JournalMode: {    /* out2-prerelease */
+case OP_JournalMode: {    /* out2 */
   Btree *pBt;                     /* Btree to change journal mode of */
   Pager *pPager;                  /* Pager associated with pBt */
   int eNew;                       /* New journal mode */
@@ -73781,6 +76669,7 @@ case OP_JournalMode: {    /* out2-prerelease */
   const char *zFilename;          /* Name of database file for pPager */
 #endif
 
+  pOut = out2Prerelease(p, pOp);
   eNew = pOp->p3;
   assert( eNew==PAGER_JOURNALMODE_DELETE 
        || eNew==PAGER_JOURNALMODE_TRUNCATE 
@@ -73856,7 +76745,6 @@ case OP_JournalMode: {    /* out2-prerelease */
   }
   eNew = sqlite3PagerSetJournalMode(pPager, eNew);
 
-  pOut = &aMem[pOp->p2];
   pOut->flags = MEM_Str|MEM_Static|MEM_Term;
   pOut->z = (char *)sqlite3JournalModename(eNew);
   pOut->n = sqlite3Strlen30(pOut->z);
@@ -73897,8 +76785,8 @@ case OP_IncrVacuum: {        /* jump */
   rc = sqlite3BtreeIncrVacuum(pBt);
   VdbeBranchTaken(rc==SQLITE_DONE,2);
   if( rc==SQLITE_DONE ){
-    pc = pOp->p2 - 1;
     rc = SQLITE_OK;
+    goto jump_to_p2;
   }
   break;
 }
@@ -73976,13 +76864,29 @@ case OP_VBegin: {
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
 
 #ifndef SQLITE_OMIT_VIRTUALTABLE
-/* Opcode: VCreate P1 * * P4 *
+/* Opcode: VCreate P1 P2 * * *
 **
-** P4 is the name of a virtual table in database P1. Call the xCreate method
-** for that table.
+** P2 is a register that holds the name of a virtual table in database 
+** P1. Call the xCreate method for that table.
 */
 case OP_VCreate: {
-  rc = sqlite3VtabCallCreate(db, pOp->p1, pOp->p4.z, &p->zErrMsg);
+  Mem sMem;          /* For storing the record being decoded */
+  const char *zTab;  /* Name of the virtual table */
+
+  memset(&sMem, 0, sizeof(sMem));
+  sMem.db = db;
+  /* Because P2 is always a static string, it is impossible for the
+  ** sqlite3VdbeMemCopy() to fail */
+  assert( (aMem[pOp->p2].flags & MEM_Str)!=0 );
+  assert( (aMem[pOp->p2].flags & MEM_Static)!=0 );
+  rc = sqlite3VdbeMemCopy(&sMem, &aMem[pOp->p2]);
+  assert( rc==SQLITE_OK );
+  zTab = (const char*)sqlite3_value_text(&sMem);
+  assert( zTab || db->mallocFailed );
+  if( zTab ){
+    rc = sqlite3VtabCallCreate(db, pOp->p1, zTab, &p->zErrMsg);
+  }
+  sqlite3VdbeMemRelease(&sMem);
   break;
 }
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -73994,9 +76898,9 @@ case OP_VCreate: {
 ** of that table.
 */
 case OP_VDestroy: {
-  p->inVtabMethod = 2;
+  db->nVDestroy++;
   rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z);
-  p->inVtabMethod = 0;
+  db->nVDestroy--;
   break;
 }
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -74012,14 +76916,17 @@ case OP_VOpen: {
   VdbeCursor *pCur;
   sqlite3_vtab_cursor *pVtabCursor;
   sqlite3_vtab *pVtab;
-  sqlite3_module *pModule;
+  const sqlite3_module *pModule;
 
   assert( p->bIsReader );
   pCur = 0;
   pVtabCursor = 0;
   pVtab = pOp->p4.pVtab->pVtab;
-  pModule = (sqlite3_module *)pVtab->pModule;
-  assert(pVtab && pModule);
+  if( pVtab==0 || NEVER(pVtab->pModule==0) ){
+    rc = SQLITE_LOCKED;
+    break;
+  }
+  pModule = pVtab->pModule;
   rc = pModule->xOpen(pVtab, &pVtabCursor);
   sqlite3VtabImportErrmsg(p, pVtab);
   if( SQLITE_OK==rc ){
@@ -74030,9 +76937,11 @@ case OP_VOpen: {
     pCur = allocateCursor(p, pOp->p1, 0, -1, 0);
     if( pCur ){
       pCur->pVtabCursor = pVtabCursor;
+      pVtab->nRef++;
     }else{
-      db->mallocFailed = 1;
+      assert( db->mallocFailed );
       pModule->xClose(pVtabCursor);
+      goto no_mem;
     }
   }
   break;
@@ -74088,27 +76997,19 @@ case OP_VFilter: {   /* jump */
   iQuery = (int)pQuery->u.i;
 
   /* Invoke the xFilter method */
-  {
-    res = 0;
-    apArg = p->apArg;
-    for(i = 0; i<nArg; i++){
-      apArg[i] = &pArgc[i+1];
-    }
-
-    p->inVtabMethod = 1;
-    rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
-    p->inVtabMethod = 0;
-    sqlite3VtabImportErrmsg(p, pVtab);
-    if( rc==SQLITE_OK ){
-      res = pModule->xEof(pVtabCursor);
-    }
-    VdbeBranchTaken(res!=0,2);
-    if( res ){
-      pc = pOp->p2 - 1;
-    }
+  res = 0;
+  apArg = p->apArg;
+  for(i = 0; i<nArg; i++){
+    apArg[i] = &pArgc[i+1];
+  }
+  rc = pModule->xFilter(pVtabCursor, iQuery, pOp->p4.z, nArg, apArg);
+  sqlite3VtabImportErrmsg(p, pVtab);
+  if( rc==SQLITE_OK ){
+    res = pModule->xEof(pVtabCursor);
   }
   pCur->nullRow = 0;
-
+  VdbeBranchTaken(res!=0,2);
+  if( res ) goto jump_to_p2;
   break;
 }
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
@@ -74140,27 +77041,14 @@ case OP_VColumn: {
   pModule = pVtab->pModule;
   assert( pModule->xColumn );
   memset(&sContext, 0, sizeof(sContext));
-
-  /* The output cell may already have a buffer allocated. Move
-  ** the current contents to sContext.s so in case the user-function 
-  ** can use the already allocated buffer instead of allocating a 
-  ** new one.
-  */
-  sqlite3VdbeMemMove(&sContext.s, pDest);
-  MemSetTypeFlag(&sContext.s, MEM_Null);
-
+  sContext.pOut = pDest;
+  MemSetTypeFlag(pDest, MEM_Null);
   rc = pModule->xColumn(pCur->pVtabCursor, &sContext, pOp->p2);
   sqlite3VtabImportErrmsg(p, pVtab);
   if( sContext.isError ){
     rc = sContext.isError;
   }
-
-  /* Copy the result of the function to the P3 register. We
-  ** do this regardless of whether or not an error occurred to ensure any
-  ** dynamic allocation in sContext.s (a Mem struct) is  released.
-  */
-  sqlite3VdbeChangeEncoding(&sContext.s, encoding);
-  sqlite3VdbeMemMove(pDest, &sContext.s);
+  sqlite3VdbeChangeEncoding(pDest, encoding);
   REGISTER_TRACE(pOp->p3, pDest);
   UPDATE_MAX_BLOBSIZE(pDest);
 
@@ -74200,9 +77088,7 @@ case OP_VNext: {   /* jump */
   ** data is available) and the error code returned when xColumn or
   ** some other method is next invoked on the save virtual table cursor.
   */
-  p->inVtabMethod = 1;
   rc = pModule->xNext(pCur->pVtabCursor);
-  p->inVtabMethod = 0;
   sqlite3VtabImportErrmsg(p, pVtab);
   if( rc==SQLITE_OK ){
     res = pModule->xEof(pCur->pVtabCursor);
@@ -74210,7 +77096,7 @@ case OP_VNext: {   /* jump */
   VdbeBranchTaken(!res,2);
   if( !res ){
     /* If there is data, jump to P2 */
-    pc = pOp->p2 - 1;
+    goto jump_to_p2_and_check_for_interrupt;
   }
   goto check_for_interrupt;
 }
@@ -74277,7 +77163,7 @@ case OP_VRename: {
 */
 case OP_VUpdate: {
   sqlite3_vtab *pVtab;
-  sqlite3_module *pModule;
+  const sqlite3_module *pModule;
   int nArg;
   int i;
   sqlite_int64 rowid;
@@ -74289,7 +77175,11 @@ case OP_VUpdate: {
   );
   assert( p->readOnly==0 );
   pVtab = pOp->p4.pVtab->pVtab;
-  pModule = (sqlite3_module *)pVtab->pModule;
+  if( pVtab==0 || NEVER(pVtab->pModule==0) ){
+    rc = SQLITE_LOCKED;
+    break;
+  }
+  pModule = pVtab->pModule;
   nArg = pOp->p2;
   assert( pOp->p4type==P4_VTAB );
   if( ALWAYS(pModule->xUpdate) ){
@@ -74329,7 +77219,8 @@ case OP_VUpdate: {
 **
 ** Write the current number of pages in database P1 to memory cell P2.
 */
-case OP_Pagecount: {            /* out2-prerelease */
+case OP_Pagecount: {            /* out2 */
+  pOut = out2Prerelease(p, pOp);
   pOut->u.i = sqlite3BtreeLastPage(db->aDb[pOp->p1].pBt);
   break;
 }
@@ -74345,10 +77236,11 @@ case OP_Pagecount: {            /* out2-prerelease */
 **
 ** Store the maximum page count after the change in register P2.
 */
-case OP_MaxPgcnt: {            /* out2-prerelease */
+case OP_MaxPgcnt: {            /* out2 */
   unsigned int newMax;
   Btree *pBt;
 
+  pOut = out2Prerelease(p, pOp);
   pBt = db->aDb[pOp->p1].pBt;
   newMax = 0;
   if( pOp->p3 ){
@@ -74377,9 +77269,6 @@ case OP_Init: {          /* jump */
   char *zTrace;
   char *z;
 
-  if( pOp->p2 ){
-    pc = pOp->p2 - 1;
-  }
 #ifndef SQLITE_OMIT_TRACE
   if( db->xTrace
    && !p->doingRerun
@@ -74407,6 +77296,7 @@ case OP_Init: {          /* jump */
   }
 #endif /* SQLITE_DEBUG */
 #endif /* SQLITE_OMIT_TRACE */
+  if( pOp->p2 ) goto jump_to_p2;
   break;
 }
 
@@ -74438,8 +77328,8 @@ default: {          /* This is really OP_Noop and OP_Explain */
 #ifdef VDBE_PROFILE
     {
       u64 endTime = sqlite3Hwtime();
-      if( endTime>start ) pOp->cycles += endTime - start;
-      pOp->cnt++;
+      if( endTime>start ) pOrigOp->cycles += endTime - start;
+      pOrigOp->cnt++;
     }
 #endif
 
@@ -74449,16 +77339,16 @@ default: {          /* This is really OP_Noop and OP_Explain */
     ** the evaluator loop.  So we can leave it out when NDEBUG is defined.
     */
 #ifndef NDEBUG
-    assert( pc>=-1 && pc<p->nOp );
+    assert( pOp>=&aOp[-1] && pOp<&aOp[p->nOp-1] );
 
 #ifdef SQLITE_DEBUG
     if( db->flags & SQLITE_VdbeTrace ){
       if( rc!=0 ) printf("rc=%d\n",rc);
-      if( pOp->opflags & (OPFLG_OUT2_PRERELEASE|OPFLG_OUT2) ){
-        registerTrace(pOp->p2, &aMem[pOp->p2]);
+      if( pOrigOp->opflags & (OPFLG_OUT2) ){
+        registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]);
       }
-      if( pOp->opflags & OPFLG_OUT3 ){
-        registerTrace(pOp->p3, &aMem[pOp->p3]);
+      if( pOrigOp->opflags & OPFLG_OUT3 ){
+        registerTrace(pOrigOp->p3, &aMem[pOrigOp->p3]);
       }
     }
 #endif  /* SQLITE_DEBUG */
@@ -74473,7 +77363,7 @@ vdbe_error_halt:
   p->rc = rc;
   testcase( sqlite3GlobalConfig.xLog!=0 );
   sqlite3_log(rc, "statement aborts at %d: [%s] %s", 
-                   pc, p->zSql, p->zErrMsg);
+                   (int)(pOp - aOp), p->zSql, p->zErrMsg);
   sqlite3VdbeHalt(p);
   if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
   rc = SQLITE_ERROR;
@@ -74636,7 +77526,7 @@ static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){
 /*
 ** Open a blob handle.
 */
-SQLITE_API int sqlite3_blob_open(
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
   sqlite3* db,            /* The database connection */
   const char *zDb,        /* The attached database containing the blob */
   const char *zTable,     /* The table containing the blob */
@@ -74685,8 +77575,18 @@ SQLITE_API int sqlite3_blob_open(
   Parse *pParse = 0;
   Incrblob *pBlob = 0;
 
-  flags = !!flags;                /* flags = (flags ? 1 : 0); */
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( ppBlob==0 ){
+    return SQLITE_MISUSE_BKPT;
+  }
+#endif
   *ppBlob = 0;
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !sqlite3SafetyCheckOk(db) || zTable==0 ){
+    return SQLITE_MISUSE_BKPT;
+  }
+#endif
+  flags = !!flags;                /* flags = (flags ? 1 : 0); */
 
   sqlite3_mutex_enter(db->mutex);
 
@@ -74850,7 +77750,7 @@ blob_open_out:
     if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt);
     sqlite3DbFree(db, pBlob);
   }
-  sqlite3Error(db, rc, (zErr ? "%s" : 0), zErr);
+  sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
   sqlite3DbFree(db, zErr);
   sqlite3ParserReset(pParse);
   sqlite3StackFree(db, pParse);
@@ -74863,7 +77763,7 @@ blob_open_out:
 ** Close a blob handle that was previously created using
 ** sqlite3_blob_open().
 */
-SQLITE_API int sqlite3_blob_close(sqlite3_blob *pBlob){
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *pBlob){
   Incrblob *p = (Incrblob *)pBlob;
   int rc;
   sqlite3 *db;
@@ -74900,10 +77800,9 @@ static int blobReadWrite(
   sqlite3_mutex_enter(db->mutex);
   v = (Vdbe*)p->pStmt;
 
-  if( n<0 || iOffset<0 || (iOffset+n)>p->nByte ){
+  if( n<0 || iOffset<0 || ((sqlite3_int64)iOffset+n)>p->nByte ){
     /* Request is out of range. Return a transient error. */
     rc = SQLITE_ERROR;
-    sqlite3Error(db, SQLITE_ERROR, 0);
   }else if( v==0 ){
     /* If there is no statement handle, then the blob-handle has
     ** already been invalidated. Return SQLITE_ABORT in this case.
@@ -74921,10 +77820,10 @@ static int blobReadWrite(
       sqlite3VdbeFinalize(v);
       p->pStmt = 0;
     }else{
-      db->errCode = rc;
       v->rc = rc;
     }
   }
+  sqlite3Error(db, rc);
   rc = sqlite3ApiExit(db, rc);
   sqlite3_mutex_leave(db->mutex);
   return rc;
@@ -74933,14 +77832,14 @@ static int blobReadWrite(
 /*
 ** Read data from a blob handle.
 */
-SQLITE_API int sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){
   return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreeData);
 }
 
 /*
 ** Write data to a blob handle.
 */
-SQLITE_API int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){
   return blobReadWrite(pBlob, (void *)z, n, iOffset, sqlite3BtreePutData);
 }
 
@@ -74950,7 +77849,7 @@ SQLITE_API int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int
 ** The Incrblob.nByte field is fixed for the lifetime of the Incrblob
 ** so no mutex is required for access.
 */
-SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *pBlob){
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *pBlob){
   Incrblob *p = (Incrblob *)pBlob;
   return (p && p->pStmt) ? p->nByte : 0;
 }
@@ -74965,7 +77864,7 @@ SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *pBlob){
 ** subsequent calls to sqlite3_blob_xxx() functions (except blob_close()) 
 ** immediately return SQLITE_ABORT.
 */
-SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
   int rc;
   Incrblob *p = (Incrblob *)pBlob;
   sqlite3 *db;
@@ -74983,7 +77882,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
     char *zErr;
     rc = blobSeekToRow(p, iRow, &zErr);
     if( rc!=SQLITE_OK ){
-      sqlite3Error(db, rc, (zErr ? "%s" : 0), zErr);
+      sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr);
       sqlite3DbFree(db, zErr);
     }
     assert( rc!=SQLITE_SCHEMA );
@@ -75000,7 +77899,7 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
 /************** End of vdbeblob.c ********************************************/
 /************** Begin file vdbesort.c ****************************************/
 /*
-** 2011 July 9
+** 2011-07-09
 **
 ** The author disclaims copyright to this source code.  In place of
 ** a legal notice, here is a blessing:
@@ -75011,42 +77910,203 @@ SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){
 **
 *************************************************************************
 ** This file contains code for the VdbeSorter object, used in concert with
-** a VdbeCursor to sort large numbers of keys (as may be required, for
-** example, by CREATE INDEX statements on tables too large to fit in main
-** memory).
+** a VdbeCursor to sort large numbers of keys for CREATE INDEX statements
+** or by SELECT statements with ORDER BY clauses that cannot be satisfied
+** using indexes and without LIMIT clauses.
+**
+** The VdbeSorter object implements a multi-threaded external merge sort
+** algorithm that is efficient even if the number of elements being sorted
+** exceeds the available memory.
+**
+** Here is the (internal, non-API) interface between this module and the
+** rest of the SQLite system:
+**
+**    sqlite3VdbeSorterInit()       Create a new VdbeSorter object.
+**
+**    sqlite3VdbeSorterWrite()      Add a single new row to the VdbeSorter
+**                                  object.  The row is a binary blob in the
+**                                  OP_MakeRecord format that contains both
+**                                  the ORDER BY key columns and result columns
+**                                  in the case of a SELECT w/ ORDER BY, or
+**                                  the complete record for an index entry
+**                                  in the case of a CREATE INDEX.
+**
+**    sqlite3VdbeSorterRewind()     Sort all content previously added.
+**                                  Position the read cursor on the
+**                                  first sorted element.
+**
+**    sqlite3VdbeSorterNext()       Advance the read cursor to the next sorted
+**                                  element.
+**
+**    sqlite3VdbeSorterRowkey()     Return the complete binary blob for the
+**                                  row currently under the read cursor.
+**
+**    sqlite3VdbeSorterCompare()    Compare the binary blob for the row
+**                                  currently under the read cursor against
+**                                  another binary blob X and report if
+**                                  X is strictly less than the read cursor.
+**                                  Used to enforce uniqueness in a
+**                                  CREATE UNIQUE INDEX statement.
+**
+**    sqlite3VdbeSorterClose()      Close the VdbeSorter object and reclaim
+**                                  all resources.
+**
+**    sqlite3VdbeSorterReset()      Refurbish the VdbeSorter for reuse.  This
+**                                  is like Close() followed by Init() only
+**                                  much faster.
+**
+** The interfaces above must be called in a particular order.  Write() can 
+** only occur in between Init()/Reset() and Rewind().  Next(), Rowkey(), and
+** Compare() can only occur in between Rewind() and Close()/Reset(). i.e.
+**
+**   Init()
+**   for each record: Write()
+**   Rewind()
+**     Rowkey()/Compare()
+**   Next() 
+**   Close()
+**
+** Algorithm:
+**
+** Records passed to the sorter via calls to Write() are initially held 
+** unsorted in main memory. Assuming the amount of memory used never exceeds
+** a threshold, when Rewind() is called the set of records is sorted using
+** an in-memory merge sort. In this case, no temporary files are required
+** and subsequent calls to Rowkey(), Next() and Compare() read records 
+** directly from main memory.
+**
+** If the amount of space used to store records in main memory exceeds the
+** threshold, then the set of records currently in memory are sorted and
+** written to a temporary file in "Packed Memory Array" (PMA) format.
+** A PMA created at this point is known as a "level-0 PMA". Higher levels
+** of PMAs may be created by merging existing PMAs together - for example
+** merging two or more level-0 PMAs together creates a level-1 PMA.
+**
+** The threshold for the amount of main memory to use before flushing 
+** records to a PMA is roughly the same as the limit configured for the
+** page-cache of the main database. Specifically, the threshold is set to 
+** the value returned by "PRAGMA main.page_size" multipled by 
+** that returned by "PRAGMA main.cache_size", in bytes.
+**
+** If the sorter is running in single-threaded mode, then all PMAs generated
+** are appended to a single temporary file. Or, if the sorter is running in
+** multi-threaded mode then up to (N+1) temporary files may be opened, where
+** N is the configured number of worker threads. In this case, instead of
+** sorting the records and writing the PMA to a temporary file itself, the
+** calling thread usually launches a worker thread to do so. Except, if
+** there are already N worker threads running, the main thread does the work
+** itself.
+**
+** The sorter is running in multi-threaded mode if (a) the library was built
+** with pre-processor symbol SQLITE_MAX_WORKER_THREADS set to a value greater
+** than zero, and (b) worker threads have been enabled at runtime by calling
+** "PRAGMA threads=N" with some value of N greater than 0.
+**
+** When Rewind() is called, any data remaining in memory is flushed to a 
+** final PMA. So at this point the data is stored in some number of sorted
+** PMAs within temporary files on disk.
+**
+** If there are fewer than SORTER_MAX_MERGE_COUNT PMAs in total and the
+** sorter is running in single-threaded mode, then these PMAs are merged
+** incrementally as keys are retreived from the sorter by the VDBE.  The
+** MergeEngine object, described in further detail below, performs this
+** merge.
+**
+** Or, if running in multi-threaded mode, then a background thread is
+** launched to merge the existing PMAs. Once the background thread has
+** merged T bytes of data into a single sorted PMA, the main thread 
+** begins reading keys from that PMA while the background thread proceeds
+** with merging the next T bytes of data. And so on.
+**
+** Parameter T is set to half the value of the memory threshold used 
+** by Write() above to determine when to create a new PMA.
+**
+** If there are more than SORTER_MAX_MERGE_COUNT PMAs in total when 
+** Rewind() is called, then a hierarchy of incremental-merges is used. 
+** First, T bytes of data from the first SORTER_MAX_MERGE_COUNT PMAs on 
+** disk are merged together. Then T bytes of data from the second set, and
+** so on, such that no operation ever merges more than SORTER_MAX_MERGE_COUNT
+** PMAs at a time. This done is to improve locality.
+**
+** If running in multi-threaded mode and there are more than
+** SORTER_MAX_MERGE_COUNT PMAs on disk when Rewind() is called, then more
+** than one background thread may be created. Specifically, there may be
+** one background thread for each temporary file on disk, and one background
+** thread to merge the output of each of the others to a single PMA for
+** the main thread to read from.
 */
 
+/* 
+** If SQLITE_DEBUG_SORTER_THREADS is defined, this module outputs various
+** messages to stderr that may be helpful in understanding the performance
+** characteristics of the sorter in multi-threaded mode.
+*/
+#if 0
+# define SQLITE_DEBUG_SORTER_THREADS 1
+#endif
+
+/*
+** Hard-coded maximum amount of data to accumulate in memory before flushing
+** to a level 0 PMA. The purpose of this limit is to prevent various integer
+** overflows. 512MiB.
+*/
+#define SQLITE_MAX_PMASZ    (1<<29)
 
+/*
+** Private objects used by the sorter
+*/
+typedef struct MergeEngine MergeEngine;     /* Merge PMAs together */
+typedef struct PmaReader PmaReader;         /* Incrementally read one PMA */
+typedef struct PmaWriter PmaWriter;         /* Incrementally write one PMA */
+typedef struct SorterRecord SorterRecord;   /* A record being sorted */
+typedef struct SortSubtask SortSubtask;     /* A sub-task in the sort process */
+typedef struct SorterFile SorterFile;       /* Temporary file object wrapper */
+typedef struct SorterList SorterList;       /* In-memory list of records */
+typedef struct IncrMerger IncrMerger;       /* Read & merge multiple PMAs */
 
-typedef struct VdbeSorterIter VdbeSorterIter;
-typedef struct SorterRecord SorterRecord;
-typedef struct FileWriter FileWriter;
+/*
+** A container for a temp file handle and the current amount of data 
+** stored in the file.
+*/
+struct SorterFile {
+  sqlite3_file *pFd;              /* File handle */
+  i64 iEof;                       /* Bytes of data stored in pFd */
+};
 
 /*
-** NOTES ON DATA STRUCTURE USED FOR N-WAY MERGES:
+** An in-memory list of objects to be sorted.
 **
-** As keys are added to the sorter, they are written to disk in a series
-** of sorted packed-memory-arrays (PMAs). The size of each PMA is roughly
-** the same as the cache-size allowed for temporary databases. In order
-** to allow the caller to extract keys from the sorter in sorted order,
-** all PMAs currently stored on disk must be merged together. This comment
-** describes the data structure used to do so. The structure supports 
-** merging any number of arrays in a single pass with no redundant comparison 
-** operations.
+** If aMemory==0 then each object is allocated separately and the objects
+** are connected using SorterRecord.u.pNext.  If aMemory!=0 then all objects
+** are stored in the aMemory[] bulk memory, one right after the other, and
+** are connected using SorterRecord.u.iNext.
+*/
+struct SorterList {
+  SorterRecord *pList;            /* Linked list of records */
+  u8 *aMemory;                    /* If non-NULL, bulk memory to hold pList */
+  int szPMA;                      /* Size of pList as PMA in bytes */
+};
+
+/*
+** The MergeEngine object is used to combine two or more smaller PMAs into
+** one big PMA using a merge operation.  Separate PMAs all need to be
+** combined into one big PMA in order to be able to step through the sorted
+** records in order.
 **
-** The aIter[] array contains an iterator for each of the PMAs being merged.
-** An aIter[] iterator either points to a valid key or else is at EOF. For 
-** the purposes of the paragraphs below, we assume that the array is actually 
-** N elements in size, where N is the smallest power of 2 greater to or equal 
-** to the number of iterators being merged. The extra aIter[] elements are 
-** treated as if they are empty (always at EOF).
+** The aReadr[] array contains a PmaReader object for each of the PMAs being
+** merged.  An aReadr[] object either points to a valid key or else is at EOF.
+** ("EOF" means "End Of File".  When aReadr[] is at EOF there is no more data.)
+** For the purposes of the paragraphs below, we assume that the array is
+** actually N elements in size, where N is the smallest power of 2 greater
+** to or equal to the number of PMAs being merged. The extra aReadr[] elements
+** are treated as if they are empty (always at EOF).
 **
 ** The aTree[] array is also N elements in size. The value of N is stored in
-** the VdbeSorter.nTree variable.
+** the MergeEngine.nTree variable.
 **
 ** The final (N/2) elements of aTree[] contain the results of comparing
-** pairs of iterator keys together. Element i contains the result of 
-** comparing aIter[2*i-N] and aIter[2*i-N+1]. Whichever key is smaller, the
+** pairs of PMA keys together. Element i contains the result of 
+** comparing aReadr[2*i-N] and aReadr[2*i-N+1]. Whichever key is smaller, the
 ** aTree element is set to the index of it. 
 **
 ** For the purposes of this comparison, EOF is considered greater than any
@@ -75054,34 +78114,34 @@ typedef struct FileWriter FileWriter;
 ** values), it doesn't matter which index is stored.
 **
 ** The (N/4) elements of aTree[] that precede the final (N/2) described 
-** above contains the index of the smallest of each block of 4 iterators.
-** And so on. So that aTree[1] contains the index of the iterator that 
+** above contains the index of the smallest of each block of 4 PmaReaders
+** And so on. So that aTree[1] contains the index of the PmaReader that 
 ** currently points to the smallest key value. aTree[0] is unused.
 **
 ** Example:
 **
-**     aIter[0] -> Banana
-**     aIter[1] -> Feijoa
-**     aIter[2] -> Elderberry
-**     aIter[3] -> Currant
-**     aIter[4] -> Grapefruit
-**     aIter[5] -> Apple
-**     aIter[6] -> Durian
-**     aIter[7] -> EOF
+**     aReadr[0] -> Banana
+**     aReadr[1] -> Feijoa
+**     aReadr[2] -> Elderberry
+**     aReadr[3] -> Currant
+**     aReadr[4] -> Grapefruit
+**     aReadr[5] -> Apple
+**     aReadr[6] -> Durian
+**     aReadr[7] -> EOF
 **
 **     aTree[] = { X, 5   0, 5    0, 3, 5, 6 }
 **
 ** The current element is "Apple" (the value of the key indicated by 
-** iterator 5). When the Next() operation is invoked, iterator 5 will
+** PmaReader 5). When the Next() operation is invoked, PmaReader 5 will
 ** be advanced to the next key in its segment. Say the next key is
 ** "Eggplant":
 **
-**     aIter[5] -> Eggplant
+**     aReadr[5] -> Eggplant
 **
-** The contents of aTree[] are updated first by comparing the new iterator
-** 5 key to the current key of iterator 4 (still "Grapefruit"). The iterator
+** The contents of aTree[] are updated first by comparing the new PmaReader
+** 5 key to the current key of PmaReader 4 (still "Grapefruit"). The PmaReader
 ** 5 value is still smaller, so aTree[6] is set to 5. And so on up the tree.
-** The value of iterator 6 - "Durian" - is now smaller than that of iterator
+** The value of PmaReader 6 - "Durian" - is now smaller than that of PmaReader
 ** 5, so aTree[3] is set to 6. Key 0 is smaller than key 6 (Banana<Durian),
 ** so the value written into element 1 of the array is 0. As follows:
 **
@@ -75091,97 +78151,250 @@ typedef struct FileWriter FileWriter;
 ** key comparison operations are required, where N is the number of segments
 ** being merged (rounded up to the next power of 2).
 */
+struct MergeEngine {
+  int nTree;                 /* Used size of aTree/aReadr (power of 2) */
+  SortSubtask *pTask;        /* Used by this thread only */
+  int *aTree;                /* Current state of incremental merge */
+  PmaReader *aReadr;         /* Array of PmaReaders to merge data from */
+};
+
+/*
+** This object represents a single thread of control in a sort operation.
+** Exactly VdbeSorter.nTask instances of this object are allocated
+** as part of each VdbeSorter object. Instances are never allocated any
+** other way. VdbeSorter.nTask is set to the number of worker threads allowed
+** (see SQLITE_CONFIG_WORKER_THREADS) plus one (the main thread).  Thus for
+** single-threaded operation, there is exactly one instance of this object
+** and for multi-threaded operation there are two or more instances.
+**
+** Essentially, this structure contains all those fields of the VdbeSorter
+** structure for which each thread requires a separate instance. For example,
+** each thread requries its own UnpackedRecord object to unpack records in
+** as part of comparison operations.
+**
+** Before a background thread is launched, variable bDone is set to 0. Then, 
+** right before it exits, the thread itself sets bDone to 1. This is used for 
+** two purposes:
+**
+**   1. When flushing the contents of memory to a level-0 PMA on disk, to
+**      attempt to select a SortSubtask for which there is not already an
+**      active background thread (since doing so causes the main thread
+**      to block until it finishes).
+**
+**   2. If SQLITE_DEBUG_SORTER_THREADS is defined, to determine if a call
+**      to sqlite3ThreadJoin() is likely to block. Cases that are likely to
+**      block provoke debugging output.
+**
+** In both cases, the effects of the main thread seeing (bDone==0) even
+** after the thread has finished are not dire. So we don't worry about
+** memory barriers and such here.
+*/
+typedef int (*SorterCompare)(SortSubtask*,int*,const void*,int,const void*,int);
+struct SortSubtask {
+  SQLiteThread *pThread;          /* Background thread, if any */
+  int bDone;                      /* Set if thread is finished but not joined */
+  VdbeSorter *pSorter;            /* Sorter that owns this sub-task */
+  UnpackedRecord *pUnpacked;      /* Space to unpack a record */
+  SorterList list;                /* List for thread to write to a PMA */
+  int nPMA;                       /* Number of PMAs currently in file */
+  SorterCompare xCompare;         /* Compare function to use */
+  SorterFile file;                /* Temp file for level-0 PMAs */
+  SorterFile file2;               /* Space for other PMAs */
+};
+
+
+/*
+** Main sorter structure. A single instance of this is allocated for each 
+** sorter cursor created by the VDBE.
+**
+** mxKeysize:
+**   As records are added to the sorter by calls to sqlite3VdbeSorterWrite(),
+**   this variable is updated so as to be set to the size on disk of the
+**   largest record in the sorter.
+*/
 struct VdbeSorter {
-  i64 iWriteOff;                  /* Current write offset within file pTemp1 */
-  i64 iReadOff;                   /* Current read offset within file pTemp1 */
-  int nInMemory;                  /* Current size of pRecord list as PMA */
-  int nTree;                      /* Used size of aTree/aIter (power of 2) */
-  int nPMA;                       /* Number of PMAs stored in pTemp1 */
   int mnPmaSize;                  /* Minimum PMA size, in bytes */
   int mxPmaSize;                  /* Maximum PMA size, in bytes.  0==no limit */
-  VdbeSorterIter *aIter;          /* Array of iterators to merge */
-  int *aTree;                     /* Current state of incremental merge */
-  sqlite3_file *pTemp1;           /* PMA file 1 */
-  SorterRecord *pRecord;          /* Head of in-memory record list */
-  UnpackedRecord *pUnpacked;      /* Used to unpack keys */
+  int mxKeysize;                  /* Largest serialized key seen so far */
+  int pgsz;                       /* Main database page size */
+  PmaReader *pReader;             /* Readr data from here after Rewind() */
+  MergeEngine *pMerger;           /* Or here, if bUseThreads==0 */
+  sqlite3 *db;                    /* Database connection */
+  KeyInfo *pKeyInfo;              /* How to compare records */
+  UnpackedRecord *pUnpacked;      /* Used by VdbeSorterCompare() */
+  SorterList list;                /* List of in-memory records */
+  int iMemory;                    /* Offset of free space in list.aMemory */
+  int nMemory;                    /* Size of list.aMemory allocation in bytes */
+  u8 bUsePMA;                     /* True if one or more PMAs created */
+  u8 bUseThreads;                 /* True to use background threads */
+  u8 iPrev;                       /* Previous thread used to flush PMA */
+  u8 nTask;                       /* Size of aTask[] array */
+  u8 typeMask;
+  SortSubtask aTask[1];           /* One or more subtasks */
+};
+
+#define SORTER_TYPE_INTEGER 0x01
+#define SORTER_TYPE_TEXT    0x02
+
+/*
+** An instance of the following object is used to read records out of a
+** PMA, in sorted order.  The next key to be read is cached in nKey/aKey.
+** aKey might point into aMap or into aBuffer.  If neither of those locations
+** contain a contiguous representation of the key, then aAlloc is allocated
+** and the key is copied into aAlloc and aKey is made to poitn to aAlloc.
+**
+** pFd==0 at EOF.
+*/
+struct PmaReader {
+  i64 iReadOff;               /* Current read offset */
+  i64 iEof;                   /* 1 byte past EOF for this PmaReader */
+  int nAlloc;                 /* Bytes of space at aAlloc */
+  int nKey;                   /* Number of bytes in key */
+  sqlite3_file *pFd;          /* File handle we are reading from */
+  u8 *aAlloc;                 /* Space for aKey if aBuffer and pMap wont work */
+  u8 *aKey;                   /* Pointer to current key */
+  u8 *aBuffer;                /* Current read buffer */
+  int nBuffer;                /* Size of read buffer in bytes */
+  u8 *aMap;                   /* Pointer to mapping of entire file */
+  IncrMerger *pIncr;          /* Incremental merger */
 };
 
 /*
-** The following type is an iterator for a PMA. It caches the current key in 
-** variables nKey/aKey. If the iterator is at EOF, pFile==0.
-*/
-struct VdbeSorterIter {
-  i64 iReadOff;                   /* Current read offset */
-  i64 iEof;                       /* 1 byte past EOF for this iterator */
-  int nAlloc;                     /* Bytes of space at aAlloc */
-  int nKey;                       /* Number of bytes in key */
-  sqlite3_file *pFile;            /* File iterator is reading from */
-  u8 *aAlloc;                     /* Allocated space */
-  u8 *aKey;                       /* Pointer to current key */
-  u8 *aBuffer;                    /* Current read buffer */
-  int nBuffer;                    /* Size of read buffer in bytes */
+** Normally, a PmaReader object iterates through an existing PMA stored 
+** within a temp file. However, if the PmaReader.pIncr variable points to
+** an object of the following type, it may be used to iterate/merge through
+** multiple PMAs simultaneously.
+**
+** There are two types of IncrMerger object - single (bUseThread==0) and 
+** multi-threaded (bUseThread==1). 
+**
+** A multi-threaded IncrMerger object uses two temporary files - aFile[0] 
+** and aFile[1]. Neither file is allowed to grow to more than mxSz bytes in 
+** size. When the IncrMerger is initialized, it reads enough data from 
+** pMerger to populate aFile[0]. It then sets variables within the 
+** corresponding PmaReader object to read from that file and kicks off 
+** a background thread to populate aFile[1] with the next mxSz bytes of 
+** sorted record data from pMerger. 
+**
+** When the PmaReader reaches the end of aFile[0], it blocks until the
+** background thread has finished populating aFile[1]. It then exchanges
+** the contents of the aFile[0] and aFile[1] variables within this structure,
+** sets the PmaReader fields to read from the new aFile[0] and kicks off
+** another background thread to populate the new aFile[1]. And so on, until
+** the contents of pMerger are exhausted.
+**
+** A single-threaded IncrMerger does not open any temporary files of its
+** own. Instead, it has exclusive access to mxSz bytes of space beginning
+** at offset iStartOff of file pTask->file2. And instead of using a 
+** background thread to prepare data for the PmaReader, with a single
+** threaded IncrMerger the allocate part of pTask->file2 is "refilled" with
+** keys from pMerger by the calling thread whenever the PmaReader runs out
+** of data.
+*/
+struct IncrMerger {
+  SortSubtask *pTask;             /* Task that owns this merger */
+  MergeEngine *pMerger;           /* Merge engine thread reads data from */
+  i64 iStartOff;                  /* Offset to start writing file at */
+  int mxSz;                       /* Maximum bytes of data to store */
+  int bEof;                       /* Set to true when merge is finished */
+  int bUseThread;                 /* True to use a bg thread for this object */
+  SorterFile aFile[2];            /* aFile[0] for reading, [1] for writing */
 };
 
 /*
-** An instance of this structure is used to organize the stream of records
-** being written to files by the merge-sort code into aligned, page-sized
-** blocks.  Doing all I/O in aligned page-sized blocks helps I/O to go
-** faster on many operating systems.
+** An instance of this object is used for writing a PMA.
+**
+** The PMA is written one record at a time.  Each record is of an arbitrary
+** size.  But I/O is more efficient if it occurs in page-sized blocks where
+** each block is aligned on a page boundary.  This object caches writes to
+** the PMA so that aligned, page-size blocks are written.
 */
-struct FileWriter {
+struct PmaWriter {
   int eFWErr;                     /* Non-zero if in an error state */
   u8 *aBuffer;                    /* Pointer to write buffer */
   int nBuffer;                    /* Size of write buffer in bytes */
   int iBufStart;                  /* First byte of buffer to write */
   int iBufEnd;                    /* Last byte of buffer to write */
   i64 iWriteOff;                  /* Offset of start of buffer in file */
-  sqlite3_file *pFile;            /* File to write to */
+  sqlite3_file *pFd;              /* File handle to write to */
 };
 
 /*
-** A structure to store a single record. All in-memory records are connected
-** together into a linked list headed at VdbeSorter.pRecord using the 
-** SorterRecord.pNext pointer.
+** This object is the header on a single record while that record is being
+** held in memory and prior to being written out as part of a PMA.
+**
+** How the linked list is connected depends on how memory is being managed
+** by this module. If using a separate allocation for each in-memory record
+** (VdbeSorter.list.aMemory==0), then the list is always connected using the
+** SorterRecord.u.pNext pointers.
+**
+** Or, if using the single large allocation method (VdbeSorter.list.aMemory!=0),
+** then while records are being accumulated the list is linked using the
+** SorterRecord.u.iNext offset. This is because the aMemory[] array may
+** be sqlite3Realloc()ed while records are being accumulated. Once the VM
+** has finished passing records to the sorter, or when the in-memory buffer
+** is full, the list is sorted. As part of the sorting process, it is
+** converted to use the SorterRecord.u.pNext pointers. See function
+** vdbeSorterSort() for details.
 */
 struct SorterRecord {
-  void *pVal;
-  int nVal;
-  SorterRecord *pNext;
+  int nVal;                       /* Size of the record in bytes */
+  union {
+    SorterRecord *pNext;          /* Pointer to next record in list */
+    int iNext;                    /* Offset within aMemory of next record */
+  } u;
+  /* The data for the record immediately follows this header */
 };
 
-/* Minimum allowable value for the VdbeSorter.nWorking variable */
-#define SORTER_MIN_WORKING 10
+/* Return a pointer to the buffer containing the record data for SorterRecord
+** object p. Should be used as if:
+**
+**   void *SRVAL(SorterRecord *p) { return (void*)&p[1]; }
+*/
+#define SRVAL(p) ((void*)((SorterRecord*)(p) + 1))
+
 
-/* Maximum number of segments to merge in a single pass. */
+/* Maximum number of PMAs that a single MergeEngine can merge */
 #define SORTER_MAX_MERGE_COUNT 16
 
+static int vdbeIncrSwap(IncrMerger*);
+static void vdbeIncrFree(IncrMerger *);
+
 /*
-** Free all memory belonging to the VdbeSorterIter object passed as the second
+** Free all memory belonging to the PmaReader object passed as the
 ** argument. All structure fields are set to zero before returning.
 */
-static void vdbeSorterIterZero(sqlite3 *db, VdbeSorterIter *pIter){
-  sqlite3DbFree(db, pIter->aAlloc);
-  sqlite3DbFree(db, pIter->aBuffer);
-  memset(pIter, 0, sizeof(VdbeSorterIter));
+static void vdbePmaReaderClear(PmaReader *pReadr){
+  sqlite3_free(pReadr->aAlloc);
+  sqlite3_free(pReadr->aBuffer);
+  if( pReadr->aMap ) sqlite3OsUnfetch(pReadr->pFd, 0, pReadr->aMap);
+  vdbeIncrFree(pReadr->pIncr);
+  memset(pReadr, 0, sizeof(PmaReader));
 }
 
 /*
-** Read nByte bytes of data from the stream of data iterated by object p.
+** Read the next nByte bytes of data from the PMA p.
 ** If successful, set *ppOut to point to a buffer containing the data
 ** and return SQLITE_OK. Otherwise, if an error occurs, return an SQLite
 ** error code.
 **
-** The buffer indicated by *ppOut may only be considered valid until the
+** The buffer returned in *ppOut is only valid until the
 ** next call to this function.
 */
-static int vdbeSorterIterRead(
-  sqlite3 *db,                    /* Database handle (for malloc) */
-  VdbeSorterIter *p,              /* Iterator */
+static int vdbePmaReadBlob(
+  PmaReader *p,                   /* PmaReader from which to take the blob */
   int nByte,                      /* Bytes of data to read */
   u8 **ppOut                      /* OUT: Pointer to buffer containing data */
 ){
   int iBuf;                       /* Offset within buffer to read from */
   int nAvail;                     /* Bytes of data available in buffer */
+
+  if( p->aMap ){
+    *ppOut = &p->aMap[p->iReadOff];
+    p->iReadOff += nByte;
+    return SQLITE_OK;
+  }
+
   assert( p->aBuffer );
 
   /* If there is no more data to be read from the buffer, read the next 
@@ -75200,8 +78413,8 @@ static int vdbeSorterIterRead(
     }
     assert( nRead>0 );
 
-    /* Read data from the file. Return early if an error occurs. */
-    rc = sqlite3OsRead(p->pFile, p->aBuffer, nRead, p->iReadOff);
+    /* Readr data from the file. Return early if an error occurs. */
+    rc = sqlite3OsRead(p->pFd, p->aBuffer, nRead, p->iReadOff);
     assert( rc!=SQLITE_IOERR_SHORT_READ );
     if( rc!=SQLITE_OK ) return rc;
   }
@@ -75221,11 +78434,13 @@ static int vdbeSorterIterRead(
 
     /* Extend the p->aAlloc[] allocation if required. */
     if( p->nAlloc<nByte ){
-      int nNew = p->nAlloc*2;
+      u8 *aNew;
+      int nNew = MAX(128, p->nAlloc*2);
       while( nByte>nNew ) nNew = nNew*2;
-      p->aAlloc = sqlite3DbReallocOrFree(db, p->aAlloc, nNew);
-      if( !p->aAlloc ) return SQLITE_NOMEM;
+      aNew = sqlite3Realloc(p->aAlloc, nNew);
+      if( !aNew ) return SQLITE_NOMEM;
       p->nAlloc = nNew;
+      p->aAlloc = aNew;
     }
 
     /* Copy as much data as is available in the buffer into the start of
@@ -75237,13 +78452,13 @@ static int vdbeSorterIterRead(
     /* The following loop copies up to p->nBuffer bytes per iteration into
     ** the p->aAlloc[] buffer.  */
     while( nRem>0 ){
-      int rc;                     /* vdbeSorterIterRead() return code */
+      int rc;                     /* vdbePmaReadBlob() return code */
       int nCopy;                  /* Number of bytes to copy */
       u8 *aNext;                  /* Pointer to buffer to copy data from */
 
       nCopy = nRem;
       if( nRem>p->nBuffer ) nCopy = p->nBuffer;
-      rc = vdbeSorterIterRead(db, p, nCopy, &aNext);
+      rc = vdbePmaReadBlob(p, nCopy, &aNext);
       if( rc!=SQLITE_OK ) return rc;
       assert( aNext!=p->aAlloc );
       memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy);
@@ -75260,234 +78475,444 @@ static int vdbeSorterIterRead(
 ** Read a varint from the stream of data accessed by p. Set *pnOut to
 ** the value read.
 */
-static int vdbeSorterIterVarint(sqlite3 *db, VdbeSorterIter *p, u64 *pnOut){
+static int vdbePmaReadVarint(PmaReader *p, u64 *pnOut){
   int iBuf;
 
-  iBuf = p->iReadOff % p->nBuffer;
-  if( iBuf && (p->nBuffer-iBuf)>=9 ){
-    p->iReadOff += sqlite3GetVarint(&p->aBuffer[iBuf], pnOut);
+  if( p->aMap ){
+    p->iReadOff += sqlite3GetVarint(&p->aMap[p->iReadOff], pnOut);
   }else{
-    u8 aVarint[16], *a;
-    int i = 0, rc;
-    do{
-      rc = vdbeSorterIterRead(db, p, 1, &a);
-      if( rc ) return rc;
-      aVarint[(i++)&0xf] = a[0];
-    }while( (a[0]&0x80)!=0 );
-    sqlite3GetVarint(aVarint, pnOut);
+    iBuf = p->iReadOff % p->nBuffer;
+    if( iBuf && (p->nBuffer-iBuf)>=9 ){
+      p->iReadOff += sqlite3GetVarint(&p->aBuffer[iBuf], pnOut);
+    }else{
+      u8 aVarint[16], *a;
+      int i = 0, rc;
+      do{
+        rc = vdbePmaReadBlob(p, 1, &a);
+        if( rc ) return rc;
+        aVarint[(i++)&0xf] = a[0];
+      }while( (a[0]&0x80)!=0 );
+      sqlite3GetVarint(aVarint, pnOut);
+    }
   }
 
   return SQLITE_OK;
 }
 
+/*
+** Attempt to memory map file pFile. If successful, set *pp to point to the
+** new mapping and return SQLITE_OK. If the mapping is not attempted 
+** (because the file is too large or the VFS layer is configured not to use
+** mmap), return SQLITE_OK and set *pp to NULL.
+**
+** Or, if an error occurs, return an SQLite error code. The final value of
+** *pp is undefined in this case.
+*/
+static int vdbeSorterMapFile(SortSubtask *pTask, SorterFile *pFile, u8 **pp){
+  int rc = SQLITE_OK;
+  if( pFile->iEof<=(i64)(pTask->pSorter->db->nMaxSorterMmap) ){
+    sqlite3_file *pFd = pFile->pFd;
+    if( pFd->pMethods->iVersion>=3 ){
+      rc = sqlite3OsFetch(pFd, 0, (int)pFile->iEof, (void**)pp);
+      testcase( rc!=SQLITE_OK );
+    }
+  }
+  return rc;
+}
 
 /*
-** Advance iterator pIter to the next key in its PMA. Return SQLITE_OK if
-** no error occurs, or an SQLite error code if one does.
+** Attach PmaReader pReadr to file pFile (if it is not already attached to
+** that file) and seek it to offset iOff within the file.  Return SQLITE_OK 
+** if successful, or an SQLite error code if an error occurs.
 */
-static int vdbeSorterIterNext(
-  sqlite3 *db,                    /* Database handle (for sqlite3DbMalloc() ) */
-  VdbeSorterIter *pIter           /* Iterator to advance */
+static int vdbePmaReaderSeek(
+  SortSubtask *pTask,             /* Task context */
+  PmaReader *pReadr,              /* Reader whose cursor is to be moved */
+  SorterFile *pFile,              /* Sorter file to read from */
+  i64 iOff                        /* Offset in pFile */
 ){
-  int rc;                         /* Return Code */
+  int rc = SQLITE_OK;
+
+  assert( pReadr->pIncr==0 || pReadr->pIncr->bEof==0 );
+
+  if( sqlite3FaultSim(201) ) return SQLITE_IOERR_READ;
+  if( pReadr->aMap ){
+    sqlite3OsUnfetch(pReadr->pFd, 0, pReadr->aMap);
+    pReadr->aMap = 0;
+  }
+  pReadr->iReadOff = iOff;
+  pReadr->iEof = pFile->iEof;
+  pReadr->pFd = pFile->pFd;
+
+  rc = vdbeSorterMapFile(pTask, pFile, &pReadr->aMap);
+  if( rc==SQLITE_OK && pReadr->aMap==0 ){
+    int pgsz = pTask->pSorter->pgsz;
+    int iBuf = pReadr->iReadOff % pgsz;
+    if( pReadr->aBuffer==0 ){
+      pReadr->aBuffer = (u8*)sqlite3Malloc(pgsz);
+      if( pReadr->aBuffer==0 ) rc = SQLITE_NOMEM;
+      pReadr->nBuffer = pgsz;
+    }
+    if( rc==SQLITE_OK && iBuf ){
+      int nRead = pgsz - iBuf;
+      if( (pReadr->iReadOff + nRead) > pReadr->iEof ){
+        nRead = (int)(pReadr->iEof - pReadr->iReadOff);
+      }
+      rc = sqlite3OsRead(
+          pReadr->pFd, &pReadr->aBuffer[iBuf], nRead, pReadr->iReadOff
+      );
+      testcase( rc!=SQLITE_OK );
+    }
+  }
+
+  return rc;
+}
+
+/*
+** Advance PmaReader pReadr to the next key in its PMA. Return SQLITE_OK if
+** no error occurs, or an SQLite error code if one does.
+*/
+static int vdbePmaReaderNext(PmaReader *pReadr){
+  int rc = SQLITE_OK;             /* Return Code */
   u64 nRec = 0;                   /* Size of record in bytes */
 
-  if( pIter->iReadOff>=pIter->iEof ){
-    /* This is an EOF condition */
-    vdbeSorterIterZero(db, pIter);
-    return SQLITE_OK;
+
+  if( pReadr->iReadOff>=pReadr->iEof ){
+    IncrMerger *pIncr = pReadr->pIncr;
+    int bEof = 1;
+    if( pIncr ){
+      rc = vdbeIncrSwap(pIncr);
+      if( rc==SQLITE_OK && pIncr->bEof==0 ){
+        rc = vdbePmaReaderSeek(
+            pIncr->pTask, pReadr, &pIncr->aFile[0], pIncr->iStartOff
+        );
+        bEof = 0;
+      }
+    }
+
+    if( bEof ){
+      /* This is an EOF condition */
+      vdbePmaReaderClear(pReadr);
+      testcase( rc!=SQLITE_OK );
+      return rc;
+    }
   }
 
-  rc = vdbeSorterIterVarint(db, pIter, &nRec);
   if( rc==SQLITE_OK ){
-    pIter->nKey = (int)nRec;
-    rc = vdbeSorterIterRead(db, pIter, (int)nRec, &pIter->aKey);
+    rc = vdbePmaReadVarint(pReadr, &nRec);
+  }
+  if( rc==SQLITE_OK ){
+    pReadr->nKey = (int)nRec;
+    rc = vdbePmaReadBlob(pReadr, (int)nRec, &pReadr->aKey);
+    testcase( rc!=SQLITE_OK );
   }
 
   return rc;
 }
 
 /*
-** Initialize iterator pIter to scan through the PMA stored in file pFile
+** Initialize PmaReader pReadr to scan through the PMA stored in file pFile
 ** starting at offset iStart and ending at offset iEof-1. This function 
-** leaves the iterator pointing to the first key in the PMA (or EOF if the 
+** leaves the PmaReader pointing to the first key in the PMA (or EOF if the 
 ** PMA is empty).
+**
+** If the pnByte parameter is NULL, then it is assumed that the file 
+** contains a single PMA, and that that PMA omits the initial length varint.
 */
-static int vdbeSorterIterInit(
-  sqlite3 *db,                    /* Database handle */
-  const VdbeSorter *pSorter,      /* Sorter object */
+static int vdbePmaReaderInit(
+  SortSubtask *pTask,             /* Task context */
+  SorterFile *pFile,              /* Sorter file to read from */
   i64 iStart,                     /* Start offset in pFile */
-  VdbeSorterIter *pIter,          /* Iterator to populate */
+  PmaReader *pReadr,              /* PmaReader to populate */
   i64 *pnByte                     /* IN/OUT: Increment this value by PMA size */
 ){
-  int rc = SQLITE_OK;
-  int nBuf;
-
-  nBuf = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
-
-  assert( pSorter->iWriteOff>iStart );
-  assert( pIter->aAlloc==0 );
-  assert( pIter->aBuffer==0 );
-  pIter->pFile = pSorter->pTemp1;
-  pIter->iReadOff = iStart;
-  pIter->nAlloc = 128;
-  pIter->aAlloc = (u8 *)sqlite3DbMallocRaw(db, pIter->nAlloc);
-  pIter->nBuffer = nBuf;
-  pIter->aBuffer = (u8 *)sqlite3DbMallocRaw(db, nBuf);
+  int rc;
 
-  if( !pIter->aBuffer ){
-    rc = SQLITE_NOMEM;
-  }else{
-    int iBuf;
+  assert( pFile->iEof>iStart );
+  assert( pReadr->aAlloc==0 && pReadr->nAlloc==0 );
+  assert( pReadr->aBuffer==0 );
+  assert( pReadr->aMap==0 );
 
-    iBuf = iStart % nBuf;
-    if( iBuf ){
-      int nRead = nBuf - iBuf;
-      if( (iStart + nRead) > pSorter->iWriteOff ){
-        nRead = (int)(pSorter->iWriteOff - iStart);
-      }
-      rc = sqlite3OsRead(
-          pSorter->pTemp1, &pIter->aBuffer[iBuf], nRead, iStart
-      );
-    }
-
-    if( rc==SQLITE_OK ){
-      u64 nByte;                       /* Size of PMA in bytes */
-      pIter->iEof = pSorter->iWriteOff;
-      rc = vdbeSorterIterVarint(db, pIter, &nByte);
-      pIter->iEof = pIter->iReadOff + nByte;
-      *pnByte += nByte;
-    }
+  rc = vdbePmaReaderSeek(pTask, pReadr, pFile, iStart);
+  if( rc==SQLITE_OK ){
+    u64 nByte;                    /* Size of PMA in bytes */
+    rc = vdbePmaReadVarint(pReadr, &nByte);
+    pReadr->iEof = pReadr->iReadOff + nByte;
+    *pnByte += nByte;
   }
 
   if( rc==SQLITE_OK ){
-    rc = vdbeSorterIterNext(db, pIter);
+    rc = vdbePmaReaderNext(pReadr);
   }
   return rc;
 }
 
+/*
+** A version of vdbeSorterCompare() that assumes that it has already been
+** determined that the first field of key1 is equal to the first field of 
+** key2.
+*/
+static int vdbeSorterCompareTail(
+  SortSubtask *pTask,             /* Subtask context (for pKeyInfo) */
+  int *pbKey2Cached,              /* True if pTask->pUnpacked is pKey2 */
+  const void *pKey1, int nKey1,   /* Left side of comparison */
+  const void *pKey2, int nKey2    /* Right side of comparison */
+){
+  UnpackedRecord *r2 = pTask->pUnpacked;
+  if( *pbKey2Cached==0 ){
+    sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2);
+    *pbKey2Cached = 1;
+  }
+  return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, r2, 1);
+}
 
 /*
 ** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2, 
-** size nKey2 bytes).  Argument pKeyInfo supplies the collation functions
-** used by the comparison. If an error occurs, return an SQLite error code.
-** Otherwise, return SQLITE_OK and set *pRes to a negative, zero or positive
-** value, depending on whether key1 is smaller, equal to or larger than key2.
-**
-** If the bOmitRowid argument is non-zero, assume both keys end in a rowid
-** field. For the purposes of the comparison, ignore it. Also, if bOmitRowid
-** is true and key1 contains even a single NULL value, it is considered to
-** be less than key2. Even if key2 also contains NULL values.
-**
-** If pKey2 is passed a NULL pointer, then it is assumed that the pCsr->aSpace
-** has been allocated and contains an unpacked record that is used as key2.
-*/
-static void vdbeSorterCompare(
-  const VdbeCursor *pCsr,         /* Cursor object (for pKeyInfo) */
-  int nKeyCol,                    /* Num of columns. 0 means "all" */
+** size nKey2 bytes). Use (pTask->pKeyInfo) for the collation sequences
+** used by the comparison. Return the result of the comparison.
+**
+** If IN/OUT parameter *pbKey2Cached is true when this function is called,
+** it is assumed that (pTask->pUnpacked) contains the unpacked version
+** of key2. If it is false, (pTask->pUnpacked) is populated with the unpacked
+** version of key2 and *pbKey2Cached set to true before returning.
+**
+** If an OOM error is encountered, (pTask->pUnpacked->error_rc) is set
+** to SQLITE_NOMEM.
+*/
+static int vdbeSorterCompare(
+  SortSubtask *pTask,             /* Subtask context (for pKeyInfo) */
+  int *pbKey2Cached,              /* True if pTask->pUnpacked is pKey2 */
   const void *pKey1, int nKey1,   /* Left side of comparison */
-  const void *pKey2, int nKey2,   /* Right side of comparison */
-  int *pRes                       /* OUT: Result of comparison */
+  const void *pKey2, int nKey2    /* Right side of comparison */
 ){
-  KeyInfo *pKeyInfo = pCsr->pKeyInfo;
-  VdbeSorter *pSorter = pCsr->pSorter;
-  UnpackedRecord *r2 = pSorter->pUnpacked;
-  int i;
+  UnpackedRecord *r2 = pTask->pUnpacked;
+  if( !*pbKey2Cached ){
+    sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2);
+    *pbKey2Cached = 1;
+  }
+  return sqlite3VdbeRecordCompare(nKey1, pKey1, r2);
+}
 
-  if( pKey2 ){
-    sqlite3VdbeRecordUnpack(pKeyInfo, nKey2, pKey2, r2);
+/*
+** A specially optimized version of vdbeSorterCompare() that assumes that
+** the first field of each key is a TEXT value and that the collation
+** sequence to compare them with is BINARY.
+*/
+static int vdbeSorterCompareText(
+  SortSubtask *pTask,             /* Subtask context (for pKeyInfo) */
+  int *pbKey2Cached,              /* True if pTask->pUnpacked is pKey2 */
+  const void *pKey1, int nKey1,   /* Left side of comparison */
+  const void *pKey2, int nKey2    /* Right side of comparison */
+){
+  const u8 * const p1 = (const u8 * const)pKey1;
+  const u8 * const p2 = (const u8 * const)pKey2;
+  const u8 * const v1 = &p1[ p1[0] ];   /* Pointer to value 1 */
+  const u8 * const v2 = &p2[ p2[0] ];   /* Pointer to value 2 */
+
+  int n1;
+  int n2;
+  int res;
+
+  getVarint32(&p1[1], n1); n1 = (n1 - 13) / 2;
+  getVarint32(&p2[1], n2); n2 = (n2 - 13) / 2;
+  res = memcmp(v1, v2, MIN(n1, n2));
+  if( res==0 ){
+    res = n1 - n2;
   }
 
-  if( nKeyCol ){
-    r2->nField = nKeyCol;
-    for(i=0; i<nKeyCol; i++){
-      if( r2->aMem[i].flags & MEM_Null ){
-        *pRes = -1;
-        return;
-      }
+  if( res==0 ){
+    if( pTask->pSorter->pKeyInfo->nField>1 ){
+      res = vdbeSorterCompareTail(
+          pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
+      );
+    }
+  }else{
+    if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
+      res = res * -1;
     }
-    assert( r2->default_rc==0 );
   }
 
-  *pRes = sqlite3VdbeRecordCompare(nKey1, pKey1, r2, 0);
+  return res;
 }
 
 /*
-** This function is called to compare two iterator keys when merging 
-** multiple b-tree segments. Parameter iOut is the index of the aTree[] 
-** value to recalculate.
+** A specially optimized version of vdbeSorterCompare() that assumes that
+** the first field of each key is an INTEGER value.
 */
-static int vdbeSorterDoCompare(const VdbeCursor *pCsr, int iOut){
-  VdbeSorter *pSorter = pCsr->pSorter;
-  int i1;
-  int i2;
-  int iRes;
-  VdbeSorterIter *p1;
-  VdbeSorterIter *p2;
-
-  assert( iOut<pSorter->nTree && iOut>0 );
+static int vdbeSorterCompareInt(
+  SortSubtask *pTask,             /* Subtask context (for pKeyInfo) */
+  int *pbKey2Cached,              /* True if pTask->pUnpacked is pKey2 */
+  const void *pKey1, int nKey1,   /* Left side of comparison */
+  const void *pKey2, int nKey2    /* Right side of comparison */
+){
+  const u8 * const p1 = (const u8 * const)pKey1;
+  const u8 * const p2 = (const u8 * const)pKey2;
+  const int s1 = p1[1];                 /* Left hand serial type */
+  const int s2 = p2[1];                 /* Right hand serial type */
+  const u8 * const v1 = &p1[ p1[0] ];   /* Pointer to value 1 */
+  const u8 * const v2 = &p2[ p2[0] ];   /* Pointer to value 2 */
+  int res;                              /* Return value */
+
+  assert( (s1>0 && s1<7) || s1==8 || s1==9 );
+  assert( (s2>0 && s2<7) || s2==8 || s2==9 );
+
+  if( s1>7 && s2>7 ){
+    res = s1 - s2;
+  }else{
+    if( s1==s2 ){
+      if( (*v1 ^ *v2) & 0x80 ){
+        /* The two values have different signs */
+        res = (*v1 & 0x80) ? -1 : +1;
+      }else{
+        /* The two values have the same sign. Compare using memcmp(). */
+        static const u8 aLen[] = {0, 1, 2, 3, 4, 6, 8 };
+        int i;
+        res = 0;
+        for(i=0; i<aLen[s1]; i++){
+          if( (res = v1[i] - v2[i]) ) break;
+        }
+      }
+    }else{
+      if( s2>7 ){
+        res = +1;
+      }else if( s1>7 ){
+        res = -1;
+      }else{
+        res = s1 - s2;
+      }
+      assert( res!=0 );
 
-  if( iOut>=(pSorter->nTree/2) ){
-    i1 = (iOut - pSorter->nTree/2) * 2;
-    i2 = i1 + 1;
-  }else{
-    i1 = pSorter->aTree[iOut*2];
-    i2 = pSorter->aTree[iOut*2+1];
+      if( res>0 ){
+        if( *v1 & 0x80 ) res = -1;
+      }else{
+        if( *v2 & 0x80 ) res = +1;
+      }
+    }
   }
 
-  p1 = &pSorter->aIter[i1];
-  p2 = &pSorter->aIter[i2];
-
-  if( p1->pFile==0 ){
-    iRes = i2;
-  }else if( p2->pFile==0 ){
-    iRes = i1;
-  }else{
-    int res;
-    assert( pCsr->pSorter->pUnpacked!=0 );  /* allocated in vdbeSorterMerge() */
-    vdbeSorterCompare(
-        pCsr, 0, p1->aKey, p1->nKey, p2->aKey, p2->nKey, &res
-    );
-    if( res<=0 ){
-      iRes = i1;
-    }else{
-      iRes = i2;
+  if( res==0 ){
+    if( pTask->pSorter->pKeyInfo->nField>1 ){
+      res = vdbeSorterCompareTail(
+          pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2
+      );
     }
+  }else if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){
+    res = res * -1;
   }
 
-  pSorter->aTree[iOut] = iRes;
-  return SQLITE_OK;
+  return res;
 }
 
 /*
 ** Initialize the temporary index cursor just opened as a sorter cursor.
+**
+** Usually, the sorter module uses the value of (pCsr->pKeyInfo->nField)
+** to determine the number of fields that should be compared from the
+** records being sorted. However, if the value passed as argument nField
+** is non-zero and the sorter is able to guarantee a stable sort, nField
+** is used instead. This is used when sorting records for a CREATE INDEX
+** statement. In this case, keys are always delivered to the sorter in
+** order of the primary key, which happens to be make up the final part 
+** of the records being sorted. So if the sort is stable, there is never
+** any reason to compare PK fields and they can be ignored for a small
+** performance boost.
+**
+** The sorter can guarantee a stable sort when running in single-threaded
+** mode, but not in multi-threaded mode.
+**
+** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
 */
-SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *db, VdbeCursor *pCsr){
+SQLITE_PRIVATE int sqlite3VdbeSorterInit(
+  sqlite3 *db,                    /* Database connection (for malloc()) */
+  int nField,                     /* Number of key fields in each record */
+  VdbeCursor *pCsr                /* Cursor that holds the new sorter */
+){
   int pgsz;                       /* Page size of main database */
+  int i;                          /* Used to iterate through aTask[] */
   int mxCache;                    /* Cache size */
   VdbeSorter *pSorter;            /* The new sorter */
-  char *d;                        /* Dummy */
+  KeyInfo *pKeyInfo;              /* Copy of pCsr->pKeyInfo with db==0 */
+  int szKeyInfo;                  /* Size of pCsr->pKeyInfo in bytes */
+  int sz;                         /* Size of pSorter in bytes */
+  int rc = SQLITE_OK;
+#if SQLITE_MAX_WORKER_THREADS==0
+# define nWorker 0
+#else
+  int nWorker;
+#endif
+
+  /* Initialize the upper limit on the number of worker threads */
+#if SQLITE_MAX_WORKER_THREADS>0
+  if( sqlite3TempInMemory(db) || sqlite3GlobalConfig.bCoreMutex==0 ){
+    nWorker = 0;
+  }else{
+    nWorker = db->aLimit[SQLITE_LIMIT_WORKER_THREADS];
+  }
+#endif
+
+  /* Do not allow the total number of threads (main thread + all workers)
+  ** to exceed the maximum merge count */
+#if SQLITE_MAX_WORKER_THREADS>=SORTER_MAX_MERGE_COUNT
+  if( nWorker>=SORTER_MAX_MERGE_COUNT ){
+    nWorker = SORTER_MAX_MERGE_COUNT-1;
+  }
+#endif
 
   assert( pCsr->pKeyInfo && pCsr->pBt==0 );
-  pCsr->pSorter = pSorter = sqlite3DbMallocZero(db, sizeof(VdbeSorter));
+  szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nField-1)*sizeof(CollSeq*);
+  sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask);
+
+  pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo);
+  pCsr->pSorter = pSorter;
   if( pSorter==0 ){
-    return SQLITE_NOMEM;
-  }
-  
-  pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pCsr->pKeyInfo, 0, 0, &d);
-  if( pSorter->pUnpacked==0 ) return SQLITE_NOMEM;
-  assert( pSorter->pUnpacked==(UnpackedRecord *)d );
+    rc = SQLITE_NOMEM;
+  }else{
+    pSorter->pKeyInfo = pKeyInfo = (KeyInfo*)((u8*)pSorter + sz);
+    memcpy(pKeyInfo, pCsr->pKeyInfo, szKeyInfo);
+    pKeyInfo->db = 0;
+    if( nField && nWorker==0 ){
+      pKeyInfo->nXField += (pKeyInfo->nField - nField);
+      pKeyInfo->nField = nField;
+    }
+    pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
+    pSorter->nTask = nWorker + 1;
+    pSorter->iPrev = nWorker-1;
+    pSorter->bUseThreads = (pSorter->nTask>1);
+    pSorter->db = db;
+    for(i=0; i<pSorter->nTask; i++){
+      SortSubtask *pTask = &pSorter->aTask[i];
+      pTask->pSorter = pSorter;
+    }
+
+    if( !sqlite3TempInMemory(db) ){
+      u32 szPma = sqlite3GlobalConfig.szPma;
+      pSorter->mnPmaSize = szPma * pgsz;
+      mxCache = db->aDb[0].pSchema->cache_size;
+      if( mxCache<(int)szPma ) mxCache = (int)szPma;
+      pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_PMASZ);
+
+      /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of
+      ** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary
+      ** large heap allocations.
+      */
+      if( sqlite3GlobalConfig.pScratch==0 ){
+        assert( pSorter->iMemory==0 );
+        pSorter->nMemory = pgsz;
+        pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz);
+        if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM;
+      }
+    }
 
-  if( !sqlite3TempInMemory(db) ){
-    pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
-    pSorter->mnPmaSize = SORTER_MIN_WORKING * pgsz;
-    mxCache = db->aDb[0].pSchema->cache_size;
-    if( mxCache<SORTER_MIN_WORKING ) mxCache = SORTER_MIN_WORKING;
-    pSorter->mxPmaSize = mxCache * pgsz;
+    if( (pKeyInfo->nField+pKeyInfo->nXField)<13 
+     && (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl)
+    ){
+      pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT;
+    }
   }
 
-  return SQLITE_OK;
+  return rc;
 }
+#undef nWorker   /* Defined at the top of this function */
 
 /*
 ** Free the list of sorted records starting at pRecord.
@@ -75496,37 +78921,227 @@ static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){
   SorterRecord *p;
   SorterRecord *pNext;
   for(p=pRecord; p; p=pNext){
-    pNext = p->pNext;
+    pNext = p->u.pNext;
     sqlite3DbFree(db, p);
   }
 }
 
 /*
-** Reset a sorting cursor back to its original empty state.
+** Free all resources owned by the object indicated by argument pTask. All 
+** fields of *pTask are zeroed before returning.
 */
-SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *db, VdbeSorter *pSorter){
-  if( pSorter->aIter ){
-    int i;
-    for(i=0; i<pSorter->nTree; i++){
-      vdbeSorterIterZero(db, &pSorter->aIter[i]);
+static void vdbeSortSubtaskCleanup(sqlite3 *db, SortSubtask *pTask){
+  sqlite3DbFree(db, pTask->pUnpacked);
+#if SQLITE_MAX_WORKER_THREADS>0
+  /* pTask->list.aMemory can only be non-zero if it was handed memory
+  ** from the main thread.  That only occurs SQLITE_MAX_WORKER_THREADS>0 */
+  if( pTask->list.aMemory ){
+    sqlite3_free(pTask->list.aMemory);
+  }else
+#endif
+  {
+    assert( pTask->list.aMemory==0 );
+    vdbeSorterRecordFree(0, pTask->list.pList);
+  }
+  if( pTask->file.pFd ){
+    sqlite3OsCloseFree(pTask->file.pFd);
+  }
+  if( pTask->file2.pFd ){
+    sqlite3OsCloseFree(pTask->file2.pFd);
+  }
+  memset(pTask, 0, sizeof(SortSubtask));
+}
+
+#ifdef SQLITE_DEBUG_SORTER_THREADS
+static void vdbeSorterWorkDebug(SortSubtask *pTask, const char *zEvent){
+  i64 t;
+  int iTask = (pTask - pTask->pSorter->aTask);
+  sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t);
+  fprintf(stderr, "%lld:%d %s\n", t, iTask, zEvent);
+}
+static void vdbeSorterRewindDebug(const char *zEvent){
+  i64 t;
+  sqlite3OsCurrentTimeInt64(sqlite3_vfs_find(0), &t);
+  fprintf(stderr, "%lld:X %s\n", t, zEvent);
+}
+static void vdbeSorterPopulateDebug(
+  SortSubtask *pTask,
+  const char *zEvent
+){
+  i64 t;
+  int iTask = (pTask - pTask->pSorter->aTask);
+  sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t);
+  fprintf(stderr, "%lld:bg%d %s\n", t, iTask, zEvent);
+}
+static void vdbeSorterBlockDebug(
+  SortSubtask *pTask,
+  int bBlocked,
+  const char *zEvent
+){
+  if( bBlocked ){
+    i64 t;
+    sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t);
+    fprintf(stderr, "%lld:main %s\n", t, zEvent);
+  }
+}
+#else
+# define vdbeSorterWorkDebug(x,y)
+# define vdbeSorterRewindDebug(y)
+# define vdbeSorterPopulateDebug(x,y)
+# define vdbeSorterBlockDebug(x,y,z)
+#endif
+
+#if SQLITE_MAX_WORKER_THREADS>0
+/*
+** Join thread pTask->thread.
+*/
+static int vdbeSorterJoinThread(SortSubtask *pTask){
+  int rc = SQLITE_OK;
+  if( pTask->pThread ){
+#ifdef SQLITE_DEBUG_SORTER_THREADS
+    int bDone = pTask->bDone;
+#endif
+    void *pRet = SQLITE_INT_TO_PTR(SQLITE_ERROR);
+    vdbeSorterBlockDebug(pTask, !bDone, "enter");
+    (void)sqlite3ThreadJoin(pTask->pThread, &pRet);
+    vdbeSorterBlockDebug(pTask, !bDone, "exit");
+    rc = SQLITE_PTR_TO_INT(pRet);
+    assert( pTask->bDone==1 );
+    pTask->bDone = 0;
+    pTask->pThread = 0;
+  }
+  return rc;
+}
+
+/*
+** Launch a background thread to run xTask(pIn).
+*/
+static int vdbeSorterCreateThread(
+  SortSubtask *pTask,             /* Thread will use this task object */
+  void *(*xTask)(void*),          /* Routine to run in a separate thread */
+  void *pIn                       /* Argument passed into xTask() */
+){
+  assert( pTask->pThread==0 && pTask->bDone==0 );
+  return sqlite3ThreadCreate(&pTask->pThread, xTask, pIn);
+}
+
+/*
+** Join all outstanding threads launched by SorterWrite() to create 
+** level-0 PMAs.
+*/
+static int vdbeSorterJoinAll(VdbeSorter *pSorter, int rcin){
+  int rc = rcin;
+  int i;
+
+  /* This function is always called by the main user thread.
+  **
+  ** If this function is being called after SorterRewind() has been called, 
+  ** it is possible that thread pSorter->aTask[pSorter->nTask-1].pThread
+  ** is currently attempt to join one of the other threads. To avoid a race
+  ** condition where this thread also attempts to join the same object, join 
+  ** thread pSorter->aTask[pSorter->nTask-1].pThread first. */
+  for(i=pSorter->nTask-1; i>=0; i--){
+    SortSubtask *pTask = &pSorter->aTask[i];
+    int rc2 = vdbeSorterJoinThread(pTask);
+    if( rc==SQLITE_OK ) rc = rc2;
+  }
+  return rc;
+}
+#else
+# define vdbeSorterJoinAll(x,rcin) (rcin)
+# define vdbeSorterJoinThread(pTask) SQLITE_OK
+#endif
+
+/*
+** Allocate a new MergeEngine object capable of handling up to
+** nReader PmaReader inputs.
+**
+** nReader is automatically rounded up to the next power of two.
+** nReader may not exceed SORTER_MAX_MERGE_COUNT even after rounding up.
+*/
+static MergeEngine *vdbeMergeEngineNew(int nReader){
+  int N = 2;                      /* Smallest power of two >= nReader */
+  int nByte;                      /* Total bytes of space to allocate */
+  MergeEngine *pNew;              /* Pointer to allocated object to return */
+
+  assert( nReader<=SORTER_MAX_MERGE_COUNT );
+
+  while( N<nReader ) N += N;
+  nByte = sizeof(MergeEngine) + N * (sizeof(int) + sizeof(PmaReader));
+
+  pNew = sqlite3FaultSim(100) ? 0 : (MergeEngine*)sqlite3MallocZero(nByte);
+  if( pNew ){
+    pNew->nTree = N;
+    pNew->pTask = 0;
+    pNew->aReadr = (PmaReader*)&pNew[1];
+    pNew->aTree = (int*)&pNew->aReadr[N];
+  }
+  return pNew;
+}
+
+/*
+** Free the MergeEngine object passed as the only argument.
+*/
+static void vdbeMergeEngineFree(MergeEngine *pMerger){
+  int i;
+  if( pMerger ){
+    for(i=0; i<pMerger->nTree; i++){
+      vdbePmaReaderClear(&pMerger->aReadr[i]);
     }
-    sqlite3DbFree(db, pSorter->aIter);
-    pSorter->aIter = 0;
   }
-  if( pSorter->pTemp1 ){
-    sqlite3OsCloseFree(pSorter->pTemp1);
-    pSorter->pTemp1 = 0;
+  sqlite3_free(pMerger);
+}
+
+/*
+** Free all resources associated with the IncrMerger object indicated by
+** the first argument.
+*/
+static void vdbeIncrFree(IncrMerger *pIncr){
+  if( pIncr ){
+#if SQLITE_MAX_WORKER_THREADS>0
+    if( pIncr->bUseThread ){
+      vdbeSorterJoinThread(pIncr->pTask);
+      if( pIncr->aFile[0].pFd ) sqlite3OsCloseFree(pIncr->aFile[0].pFd);
+      if( pIncr->aFile[1].pFd ) sqlite3OsCloseFree(pIncr->aFile[1].pFd);
+    }
+#endif
+    vdbeMergeEngineFree(pIncr->pMerger);
+    sqlite3_free(pIncr);
   }
-  vdbeSorterRecordFree(db, pSorter->pRecord);
-  pSorter->pRecord = 0;
-  pSorter->iWriteOff = 0;
-  pSorter->iReadOff = 0;
-  pSorter->nInMemory = 0;
-  pSorter->nTree = 0;
-  pSorter->nPMA = 0;
-  pSorter->aTree = 0;
 }
 
+/*
+** Reset a sorting cursor back to its original empty state.
+*/
+SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *db, VdbeSorter *pSorter){
+  int i;
+  (void)vdbeSorterJoinAll(pSorter, SQLITE_OK);
+  assert( pSorter->bUseThreads || pSorter->pReader==0 );
+#if SQLITE_MAX_WORKER_THREADS>0
+  if( pSorter->pReader ){
+    vdbePmaReaderClear(pSorter->pReader);
+    sqlite3DbFree(db, pSorter->pReader);
+    pSorter->pReader = 0;
+  }
+#endif
+  vdbeMergeEngineFree(pSorter->pMerger);
+  pSorter->pMerger = 0;
+  for(i=0; i<pSorter->nTask; i++){
+    SortSubtask *pTask = &pSorter->aTask[i];
+    vdbeSortSubtaskCleanup(db, pTask);
+    pTask->pSorter = pSorter;
+  }
+  if( pSorter->list.aMemory==0 ){
+    vdbeSorterRecordFree(0, pSorter->list.pList);
+  }
+  pSorter->list.pList = 0;
+  pSorter->list.szPMA = 0;
+  pSorter->bUsePMA = 0;
+  pSorter->iMemory = 0;
+  pSorter->mxKeysize = 0;
+  sqlite3DbFree(db, pSorter->pUnpacked);
+  pSorter->pUnpacked = 0;
+}
 
 /*
 ** Free any cursor components allocated by sqlite3VdbeSorterXXX routines.
@@ -75535,54 +79150,112 @@ SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){
   VdbeSorter *pSorter = pCsr->pSorter;
   if( pSorter ){
     sqlite3VdbeSorterReset(db, pSorter);
-    sqlite3DbFree(db, pSorter->pUnpacked);
+    sqlite3_free(pSorter->list.aMemory);
     sqlite3DbFree(db, pSorter);
     pCsr->pSorter = 0;
   }
 }
 
+#if SQLITE_MAX_MMAP_SIZE>0
+/*
+** The first argument is a file-handle open on a temporary file. The file
+** is guaranteed to be nByte bytes or smaller in size. This function
+** attempts to extend the file to nByte bytes in size and to ensure that
+** the VFS has memory mapped it.
+**
+** Whether or not the file does end up memory mapped of course depends on
+** the specific VFS implementation.
+*/
+static void vdbeSorterExtendFile(sqlite3 *db, sqlite3_file *pFd, i64 nByte){
+  if( nByte<=(i64)(db->nMaxSorterMmap) && pFd->pMethods->iVersion>=3 ){
+    void *p = 0;
+    int chunksize = 4*1024;
+    sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_CHUNK_SIZE, &chunksize);
+    sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_SIZE_HINT, &nByte);
+    sqlite3OsFetch(pFd, 0, (int)nByte, &p);
+    sqlite3OsUnfetch(pFd, 0, p);
+  }
+}
+#else
+# define vdbeSorterExtendFile(x,y,z)
+#endif
+
 /*
 ** Allocate space for a file-handle and open a temporary file. If successful,
-** set *ppFile to point to the malloc'd file-handle and return SQLITE_OK.
-** Otherwise, set *ppFile to 0 and return an SQLite error code.
+** set *ppFd to point to the malloc'd file-handle and return SQLITE_OK.
+** Otherwise, set *ppFd to 0 and return an SQLite error code.
 */
-static int vdbeSorterOpenTempFile(sqlite3 *db, sqlite3_file **ppFile){
-  int dummy;
-  return sqlite3OsOpenMalloc(db->pVfs, 0, ppFile,
+static int vdbeSorterOpenTempFile(
+  sqlite3 *db,                    /* Database handle doing sort */
+  i64 nExtend,                    /* Attempt to extend file to this size */
+  sqlite3_file **ppFd
+){
+  int rc;
+  if( sqlite3FaultSim(202) ) return SQLITE_IOERR_ACCESS;
+  rc = sqlite3OsOpenMalloc(db->pVfs, 0, ppFd,
       SQLITE_OPEN_TEMP_JOURNAL |
       SQLITE_OPEN_READWRITE    | SQLITE_OPEN_CREATE |
-      SQLITE_OPEN_EXCLUSIVE    | SQLITE_OPEN_DELETEONCLOSE, &dummy
+      SQLITE_OPEN_EXCLUSIVE    | SQLITE_OPEN_DELETEONCLOSE, &rc
   );
+  if( rc==SQLITE_OK ){
+    i64 max = SQLITE_MAX_MMAP_SIZE;
+    sqlite3OsFileControlHint(*ppFd, SQLITE_FCNTL_MMAP_SIZE, (void*)&max);
+    if( nExtend>0 ){
+      vdbeSorterExtendFile(db, *ppFd, nExtend);
+    }
+  }
+  return rc;
 }
 
 /*
+** If it has not already been allocated, allocate the UnpackedRecord 
+** structure at pTask->pUnpacked. Return SQLITE_OK if successful (or 
+** if no allocation was required), or SQLITE_NOMEM otherwise.
+*/
+static int vdbeSortAllocUnpacked(SortSubtask *pTask){
+  if( pTask->pUnpacked==0 ){
+    char *pFree;
+    pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord(
+        pTask->pSorter->pKeyInfo, 0, 0, &pFree
+    );
+    assert( pTask->pUnpacked==(UnpackedRecord*)pFree );
+    if( pFree==0 ) return SQLITE_NOMEM;
+    pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nField;
+    pTask->pUnpacked->errCode = 0;
+  }
+  return SQLITE_OK;
+}
+
+
+/*
 ** Merge the two sorted lists p1 and p2 into a single list.
 ** Set *ppOut to the head of the new list.
 */
 static void vdbeSorterMerge(
-  const VdbeCursor *pCsr,         /* For pKeyInfo */
+  SortSubtask *pTask,             /* Calling thread context */
   SorterRecord *p1,               /* First list to merge */
   SorterRecord *p2,               /* Second list to merge */
   SorterRecord **ppOut            /* OUT: Head of merged list */
 ){
   SorterRecord *pFinal = 0;
   SorterRecord **pp = &pFinal;
-  void *pVal2 = p2 ? p2->pVal : 0;
+  int bCached = 0;
 
   while( p1 && p2 ){
     int res;
-    vdbeSorterCompare(pCsr, 0, p1->pVal, p1->nVal, pVal2, p2->nVal, &res);
+    res = pTask->xCompare(
+        pTask, &bCached, SRVAL(p1), p1->nVal, SRVAL(p2), p2->nVal
+    );
+
     if( res<=0 ){
       *pp = p1;
-      pp = &p1->pNext;
-      p1 = p1->pNext;
-      pVal2 = 0;
+      pp = &p1->u.pNext;
+      p1 = p1->u.pNext;
     }else{
       *pp = p2;
-       pp = &p2->pNext;
-      p2 = p2->pNext;
-      if( p2==0 ) break;
-      pVal2 = p2->pVal;
+      pp = &p2->u.pNext;
+      p2 = p2->u.pNext;
+      bCached = 0;
     }
   }
   *pp = p1 ? p1 : p2;
@@ -75590,27 +79263,56 @@ static void vdbeSorterMerge(
 }
 
 /*
-** Sort the linked list of records headed at pCsr->pRecord. Return SQLITE_OK
-** if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if an error
-** occurs.
+** Return the SorterCompare function to compare values collected by the
+** sorter object passed as the only argument.
+*/
+static SorterCompare vdbeSorterGetCompare(VdbeSorter *p){
+  if( p->typeMask==SORTER_TYPE_INTEGER ){
+    return vdbeSorterCompareInt;
+  }else if( p->typeMask==SORTER_TYPE_TEXT ){
+    return vdbeSorterCompareText; 
+  }
+  return vdbeSorterCompare;
+}
+
+/*
+** Sort the linked list of records headed at pTask->pList. Return 
+** SQLITE_OK if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if 
+** an error occurs.
 */
-static int vdbeSorterSort(const VdbeCursor *pCsr){
+static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){
   int i;
   SorterRecord **aSlot;
   SorterRecord *p;
-  VdbeSorter *pSorter = pCsr->pSorter;
+  int rc;
+
+  rc = vdbeSortAllocUnpacked(pTask);
+  if( rc!=SQLITE_OK ) return rc;
+
+  p = pList->pList;
+  pTask->xCompare = vdbeSorterGetCompare(pTask->pSorter);
 
   aSlot = (SorterRecord **)sqlite3MallocZero(64 * sizeof(SorterRecord *));
   if( !aSlot ){
     return SQLITE_NOMEM;
   }
 
-  p = pSorter->pRecord;
   while( p ){
-    SorterRecord *pNext = p->pNext;
-    p->pNext = 0;
+    SorterRecord *pNext;
+    if( pList->aMemory ){
+      if( (u8*)p==pList->aMemory ){
+        pNext = 0;
+      }else{
+        assert( p->u.iNext<sqlite3MallocSize(pList->aMemory) );
+        pNext = (SorterRecord*)&pList->aMemory[p->u.iNext];
+      }
+    }else{
+      pNext = p->u.pNext;
+    }
+
+    p->u.pNext = 0;
     for(i=0; aSlot[i]; i++){
-      vdbeSorterMerge(pCsr, p, aSlot[i], &p);
+      vdbeSorterMerge(pTask, p, aSlot[i], &p);
       aSlot[i] = 0;
     }
     aSlot[i] = p;
@@ -75619,42 +79321,43 @@ static int vdbeSorterSort(const VdbeCursor *pCsr){
 
   p = 0;
   for(i=0; i<64; i++){
-    vdbeSorterMerge(pCsr, p, aSlot[i], &p);
+    vdbeSorterMerge(pTask, p, aSlot[i], &p);
   }
-  pSorter->pRecord = p;
+  pList->pList = p;
 
   sqlite3_free(aSlot);
-  return SQLITE_OK;
+  assert( pTask->pUnpacked->errCode==SQLITE_OK 
+       || pTask->pUnpacked->errCode==SQLITE_NOMEM 
+  );
+  return pTask->pUnpacked->errCode;
 }
 
 /*
-** Initialize a file-writer object.
+** Initialize a PMA-writer object.
 */
-static void fileWriterInit(
-  sqlite3 *db,                    /* Database (for malloc) */
-  sqlite3_file *pFile,            /* File to write to */
-  FileWriter *p,                  /* Object to populate */
-  i64 iStart                      /* Offset of pFile to begin writing at */
+static void vdbePmaWriterInit(
+  sqlite3_file *pFd,              /* File handle to write to */
+  PmaWriter *p,                   /* Object to populate */
+  int nBuf,                       /* Buffer size */
+  i64 iStart                      /* Offset of pFd to begin writing at */
 ){
-  int nBuf = sqlite3BtreeGetPageSize(db->aDb[0].pBt);
-
-  memset(p, 0, sizeof(FileWriter));
-  p->aBuffer = (u8 *)sqlite3DbMallocRaw(db, nBuf);
+  memset(p, 0, sizeof(PmaWriter));
+  p->aBuffer = (u8*)sqlite3Malloc(nBuf);
   if( !p->aBuffer ){
     p->eFWErr = SQLITE_NOMEM;
   }else{
     p->iBufEnd = p->iBufStart = (iStart % nBuf);
     p->iWriteOff = iStart - p->iBufStart;
     p->nBuffer = nBuf;
-    p->pFile = pFile;
+    p->pFd = pFd;
   }
 }
 
 /*
-** Write nData bytes of data to the file-write object. Return SQLITE_OK
+** Write nData bytes of data to the PMA. Return SQLITE_OK
 ** if successful, or an SQLite error code if an error occurs.
 */
-static void fileWriterWrite(FileWriter *p, u8 *pData, int nData){
+static void vdbePmaWriteBlob(PmaWriter *p, u8 *pData, int nData){
   int nRem = nData;
   while( nRem>0 && p->eFWErr==0 ){
     int nCopy = nRem;
@@ -75665,7 +79368,7 @@ static void fileWriterWrite(FileWriter *p, u8 *pData, int nData){
     memcpy(&p->aBuffer[p->iBufEnd], &pData[nData-nRem], nCopy);
     p->iBufEnd += nCopy;
     if( p->iBufEnd==p->nBuffer ){
-      p->eFWErr = sqlite3OsWrite(p->pFile, 
+      p->eFWErr = sqlite3OsWrite(p->pFd, 
           &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, 
           p->iWriteOff + p->iBufStart
       );
@@ -75679,43 +79382,44 @@ static void fileWriterWrite(FileWriter *p, u8 *pData, int nData){
 }
 
 /*
-** Flush any buffered data to disk and clean up the file-writer object.
-** The results of using the file-writer after this call are undefined.
+** Flush any buffered data to disk and clean up the PMA-writer object.
+** The results of using the PMA-writer after this call are undefined.
 ** Return SQLITE_OK if flushing the buffered data succeeds or is not 
 ** required. Otherwise, return an SQLite error code.
 **
 ** Before returning, set *piEof to the offset immediately following the
 ** last byte written to the file.
 */
-static int fileWriterFinish(sqlite3 *db, FileWriter *p, i64 *piEof){
+static int vdbePmaWriterFinish(PmaWriter *p, i64 *piEof){
   int rc;
   if( p->eFWErr==0 && ALWAYS(p->aBuffer) && p->iBufEnd>p->iBufStart ){
-    p->eFWErr = sqlite3OsWrite(p->pFile, 
+    p->eFWErr = sqlite3OsWrite(p->pFd, 
         &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, 
         p->iWriteOff + p->iBufStart
     );
   }
   *piEof = (p->iWriteOff + p->iBufEnd);
-  sqlite3DbFree(db, p->aBuffer);
+  sqlite3_free(p->aBuffer);
   rc = p->eFWErr;
-  memset(p, 0, sizeof(FileWriter));
+  memset(p, 0, sizeof(PmaWriter));
   return rc;
 }
 
 /*
-** Write value iVal encoded as a varint to the file-write object. Return 
+** Write value iVal encoded as a varint to the PMA. Return 
 ** SQLITE_OK if successful, or an SQLite error code if an error occurs.
 */
-static void fileWriterWriteVarint(FileWriter *p, u64 iVal){
+static void vdbePmaWriteVarint(PmaWriter *p, u64 iVal){
   int nByte; 
   u8 aByte[10];
   nByte = sqlite3PutVarint(aByte, iVal);
-  fileWriterWrite(p, aByte, nByte);
+  vdbePmaWriteBlob(p, aByte, nByte);
 }
 
 /*
-** Write the current contents of the in-memory linked-list to a PMA. Return
-** SQLITE_OK if successful, or an SQLite error code otherwise.
+** Write the current contents of in-memory linked-list pList to a level-0
+** PMA in the temp file belonging to sub-task pTask. Return SQLITE_OK if 
+** successful, or an SQLite error code otherwise.
 **
 ** The format of a PMA is:
 **
@@ -75726,76 +79430,255 @@ static void fileWriterWriteVarint(FileWriter *p, u64 iVal){
 **       Each record consists of a varint followed by a blob of data (the 
 **       key). The varint is the number of bytes in the blob of data.
 */
-static int vdbeSorterListToPMA(sqlite3 *db, const VdbeCursor *pCsr){
+static int vdbeSorterListToPMA(SortSubtask *pTask, SorterList *pList){
+  sqlite3 *db = pTask->pSorter->db;
   int rc = SQLITE_OK;             /* Return code */
-  VdbeSorter *pSorter = pCsr->pSorter;
-  FileWriter writer;
+  PmaWriter writer;               /* Object used to write to the file */
 
-  memset(&writer, 0, sizeof(FileWriter));
+#ifdef SQLITE_DEBUG
+  /* Set iSz to the expected size of file pTask->file after writing the PMA. 
+  ** This is used by an assert() statement at the end of this function.  */
+  i64 iSz = pList->szPMA + sqlite3VarintLen(pList->szPMA) + pTask->file.iEof;
+#endif
 
-  if( pSorter->nInMemory==0 ){
-    assert( pSorter->pRecord==0 );
-    return rc;
+  vdbeSorterWorkDebug(pTask, "enter");
+  memset(&writer, 0, sizeof(PmaWriter));
+  assert( pList->szPMA>0 );
+
+  /* If the first temporary PMA file has not been opened, open it now. */
+  if( pTask->file.pFd==0 ){
+    rc = vdbeSorterOpenTempFile(db, 0, &pTask->file.pFd);
+    assert( rc!=SQLITE_OK || pTask->file.pFd );
+    assert( pTask->file.iEof==0 );
+    assert( pTask->nPMA==0 );
   }
 
-  rc = vdbeSorterSort(pCsr);
+  /* Try to get the file to memory map */
+  if( rc==SQLITE_OK ){
+    vdbeSorterExtendFile(db, pTask->file.pFd, pTask->file.iEof+pList->szPMA+9);
+  }
 
-  /* If the first temporary PMA file has not been opened, open it now. */
-  if( rc==SQLITE_OK && pSorter->pTemp1==0 ){
-    rc = vdbeSorterOpenTempFile(db, &pSorter->pTemp1);
-    assert( rc!=SQLITE_OK || pSorter->pTemp1 );
-    assert( pSorter->iWriteOff==0 );
-    assert( pSorter->nPMA==0 );
+  /* Sort the list */
+  if( rc==SQLITE_OK ){
+    rc = vdbeSorterSort(pTask, pList);
   }
 
   if( rc==SQLITE_OK ){
     SorterRecord *p;
     SorterRecord *pNext = 0;
 
-    fileWriterInit(db, pSorter->pTemp1, &writer, pSorter->iWriteOff);
-    pSorter->nPMA++;
-    fileWriterWriteVarint(&writer, pSorter->nInMemory);
-    for(p=pSorter->pRecord; p; p=pNext){
-      pNext = p->pNext;
-      fileWriterWriteVarint(&writer, p->nVal);
-      fileWriterWrite(&writer, p->pVal, p->nVal);
-      sqlite3DbFree(db, p);
+    vdbePmaWriterInit(pTask->file.pFd, &writer, pTask->pSorter->pgsz,
+                      pTask->file.iEof);
+    pTask->nPMA++;
+    vdbePmaWriteVarint(&writer, pList->szPMA);
+    for(p=pList->pList; p; p=pNext){
+      pNext = p->u.pNext;
+      vdbePmaWriteVarint(&writer, p->nVal);
+      vdbePmaWriteBlob(&writer, SRVAL(p), p->nVal);
+      if( pList->aMemory==0 ) sqlite3_free(p);
     }
-    pSorter->pRecord = p;
-    rc = fileWriterFinish(db, &writer, &pSorter->iWriteOff);
+    pList->pList = p;
+    rc = vdbePmaWriterFinish(&writer, &pTask->file.iEof);
   }
 
+  vdbeSorterWorkDebug(pTask, "exit");
+  assert( rc!=SQLITE_OK || pList->pList==0 );
+  assert( rc!=SQLITE_OK || pTask->file.iEof==iSz );
   return rc;
 }
 
 /*
+** Advance the MergeEngine to its next entry.
+** Set *pbEof to true there is no next entry because
+** the MergeEngine has reached the end of all its inputs.
+**
+** Return SQLITE_OK if successful or an error code if an error occurs.
+*/
+static int vdbeMergeEngineStep(
+  MergeEngine *pMerger,      /* The merge engine to advance to the next row */
+  int *pbEof                 /* Set TRUE at EOF.  Set false for more content */
+){
+  int rc;
+  int iPrev = pMerger->aTree[1];/* Index of PmaReader to advance */
+  SortSubtask *pTask = pMerger->pTask;
+
+  /* Advance the current PmaReader */
+  rc = vdbePmaReaderNext(&pMerger->aReadr[iPrev]);
+
+  /* Update contents of aTree[] */
+  if( rc==SQLITE_OK ){
+    int i;                      /* Index of aTree[] to recalculate */
+    PmaReader *pReadr1;         /* First PmaReader to compare */
+    PmaReader *pReadr2;         /* Second PmaReader to compare */
+    int bCached = 0;
+
+    /* Find the first two PmaReaders to compare. The one that was just
+    ** advanced (iPrev) and the one next to it in the array.  */
+    pReadr1 = &pMerger->aReadr[(iPrev & 0xFFFE)];
+    pReadr2 = &pMerger->aReadr[(iPrev | 0x0001)];
+
+    for(i=(pMerger->nTree+iPrev)/2; i>0; i=i/2){
+      /* Compare pReadr1 and pReadr2. Store the result in variable iRes. */
+      int iRes;
+      if( pReadr1->pFd==0 ){
+        iRes = +1;
+      }else if( pReadr2->pFd==0 ){
+        iRes = -1;
+      }else{
+        iRes = pTask->xCompare(pTask, &bCached,
+            pReadr1->aKey, pReadr1->nKey, pReadr2->aKey, pReadr2->nKey
+        );
+      }
+
+      /* If pReadr1 contained the smaller value, set aTree[i] to its index.
+      ** Then set pReadr2 to the next PmaReader to compare to pReadr1. In this
+      ** case there is no cache of pReadr2 in pTask->pUnpacked, so set
+      ** pKey2 to point to the record belonging to pReadr2.
+      **
+      ** Alternatively, if pReadr2 contains the smaller of the two values,
+      ** set aTree[i] to its index and update pReadr1. If vdbeSorterCompare()
+      ** was actually called above, then pTask->pUnpacked now contains
+      ** a value equivalent to pReadr2. So set pKey2 to NULL to prevent
+      ** vdbeSorterCompare() from decoding pReadr2 again.
+      **
+      ** If the two values were equal, then the value from the oldest
+      ** PMA should be considered smaller. The VdbeSorter.aReadr[] array
+      ** is sorted from oldest to newest, so pReadr1 contains older values
+      ** than pReadr2 iff (pReadr1<pReadr2).  */
+      if( iRes<0 || (iRes==0 && pReadr1<pReadr2) ){
+        pMerger->aTree[i] = (int)(pReadr1 - pMerger->aReadr);
+        pReadr2 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ];
+        bCached = 0;
+      }else{
+        if( pReadr1->pFd ) bCached = 0;
+        pMerger->aTree[i] = (int)(pReadr2 - pMerger->aReadr);
+        pReadr1 = &pMerger->aReadr[ pMerger->aTree[i ^ 0x0001] ];
+      }
+    }
+    *pbEof = (pMerger->aReadr[pMerger->aTree[1]].pFd==0);
+  }
+
+  return (rc==SQLITE_OK ? pTask->pUnpacked->errCode : rc);
+}
+
+#if SQLITE_MAX_WORKER_THREADS>0
+/*
+** The main routine for background threads that write level-0 PMAs.
+*/
+static void *vdbeSorterFlushThread(void *pCtx){
+  SortSubtask *pTask = (SortSubtask*)pCtx;
+  int rc;                         /* Return code */
+  assert( pTask->bDone==0 );
+  rc = vdbeSorterListToPMA(pTask, &pTask->list);
+  pTask->bDone = 1;
+  return SQLITE_INT_TO_PTR(rc);
+}
+#endif /* SQLITE_MAX_WORKER_THREADS>0 */
+
+/*
+** Flush the current contents of VdbeSorter.list to a new PMA, possibly
+** using a background thread.
+*/
+static int vdbeSorterFlushPMA(VdbeSorter *pSorter){
+#if SQLITE_MAX_WORKER_THREADS==0
+  pSorter->bUsePMA = 1;
+  return vdbeSorterListToPMA(&pSorter->aTask[0], &pSorter->list);
+#else
+  int rc = SQLITE_OK;
+  int i;
+  SortSubtask *pTask = 0;    /* Thread context used to create new PMA */
+  int nWorker = (pSorter->nTask-1);
+
+  /* Set the flag to indicate that at least one PMA has been written. 
+  ** Or will be, anyhow.  */
+  pSorter->bUsePMA = 1;
+
+  /* Select a sub-task to sort and flush the current list of in-memory
+  ** records to disk. If the sorter is running in multi-threaded mode,
+  ** round-robin between the first (pSorter->nTask-1) tasks. Except, if
+  ** the background thread from a sub-tasks previous turn is still running,
+  ** skip it. If the first (pSorter->nTask-1) sub-tasks are all still busy,
+  ** fall back to using the final sub-task. The first (pSorter->nTask-1)
+  ** sub-tasks are prefered as they use background threads - the final 
+  ** sub-task uses the main thread. */
+  for(i=0; i<nWorker; i++){
+    int iTest = (pSorter->iPrev + i + 1) % nWorker;
+    pTask = &pSorter->aTask[iTest];
+    if( pTask->bDone ){
+      rc = vdbeSorterJoinThread(pTask);
+    }
+    if( rc!=SQLITE_OK || pTask->pThread==0 ) break;
+  }
+
+  if( rc==SQLITE_OK ){
+    if( i==nWorker ){
+      /* Use the foreground thread for this operation */
+      rc = vdbeSorterListToPMA(&pSorter->aTask[nWorker], &pSorter->list);
+    }else{
+      /* Launch a background thread for this operation */
+      u8 *aMem = pTask->list.aMemory;
+      void *pCtx = (void*)pTask;
+
+      assert( pTask->pThread==0 && pTask->bDone==0 );
+      assert( pTask->list.pList==0 );
+      assert( pTask->list.aMemory==0 || pSorter->list.aMemory!=0 );
+
+      pSorter->iPrev = (u8)(pTask - pSorter->aTask);
+      pTask->list = pSorter->list;
+      pSorter->list.pList = 0;
+      pSorter->list.szPMA = 0;
+      if( aMem ){
+        pSorter->list.aMemory = aMem;
+        pSorter->nMemory = sqlite3MallocSize(aMem);
+      }else if( pSorter->list.aMemory ){
+        pSorter->list.aMemory = sqlite3Malloc(pSorter->nMemory);
+        if( !pSorter->list.aMemory ) return SQLITE_NOMEM;
+      }
+
+      rc = vdbeSorterCreateThread(pTask, vdbeSorterFlushThread, pCtx);
+    }
+  }
+
+  return rc;
+#endif /* SQLITE_MAX_WORKER_THREADS!=0 */
+}
+
+/*
 ** Add a record to the sorter.
 */
 SQLITE_PRIVATE int sqlite3VdbeSorterWrite(
-  sqlite3 *db,                    /* Database handle */
-  const VdbeCursor *pCsr,               /* Sorter cursor */
+  const VdbeCursor *pCsr,         /* Sorter cursor */
   Mem *pVal                       /* Memory cell containing record */
 ){
   VdbeSorter *pSorter = pCsr->pSorter;
   int rc = SQLITE_OK;             /* Return Code */
   SorterRecord *pNew;             /* New list element */
 
-  assert( pSorter );
-  pSorter->nInMemory += sqlite3VarintLen(pVal->n) + pVal->n;
+  int bFlush;                     /* True to flush contents of memory to PMA */
+  int nReq;                       /* Bytes of memory required */
+  int nPMA;                       /* Bytes of PMA space required */
+  int t;                          /* serial type of first record field */
 
-  pNew = (SorterRecord *)sqlite3DbMallocRaw(db, pVal->n + sizeof(SorterRecord));
-  if( pNew==0 ){
-    rc = SQLITE_NOMEM;
+  getVarint32((const u8*)&pVal->z[1], t);
+  if( t>0 && t<10 && t!=7 ){
+    pSorter->typeMask &= SORTER_TYPE_INTEGER;
+  }else if( t>10 && (t & 0x01) ){
+    pSorter->typeMask &= SORTER_TYPE_TEXT;
   }else{
-    pNew->pVal = (void *)&pNew[1];
-    memcpy(pNew->pVal, pVal->z, pVal->n);
-    pNew->nVal = pVal->n;
-    pNew->pNext = pSorter->pRecord;
-    pSorter->pRecord = pNew;
+    pSorter->typeMask = 0;
   }
 
-  /* See if the contents of the sorter should now be written out. They
-  ** are written out when either of the following are true:
+  assert( pSorter );
+
+  /* Figure out whether or not the current contents of memory should be
+  ** flushed to a PMA before continuing. If so, do so.
+  **
+  ** If using the single large allocation mode (pSorter->aMemory!=0), then
+  ** flush the contents of memory to a new PMA if (a) at least one value is
+  ** already in memory and (b) the new value will not fit in memory.
+  ** 
+  ** Or, if using separate allocations for each record, flush the contents
+  ** of memory to a PMA if either of the following are true:
   **
   **   * The total memory allocated for the in-memory list is greater 
   **     than (page-size * cache-size), or
@@ -75803,161 +79686,809 @@ SQLITE_PRIVATE int sqlite3VdbeSorterWrite(
   **   * The total memory allocated for the in-memory list is greater 
   **     than (page-size * 10) and sqlite3HeapNearlyFull() returns true.
   */
-  if( rc==SQLITE_OK && pSorter->mxPmaSize>0 && (
-        (pSorter->nInMemory>pSorter->mxPmaSize)
-     || (pSorter->nInMemory>pSorter->mnPmaSize && sqlite3HeapNearlyFull())
-  )){
-#ifdef SQLITE_DEBUG
-    i64 nExpect = pSorter->iWriteOff
-                + sqlite3VarintLen(pSorter->nInMemory)
-                + pSorter->nInMemory;
+  nReq = pVal->n + sizeof(SorterRecord);
+  nPMA = pVal->n + sqlite3VarintLen(pVal->n);
+  if( pSorter->mxPmaSize ){
+    if( pSorter->list.aMemory ){
+      bFlush = pSorter->iMemory && (pSorter->iMemory+nReq) > pSorter->mxPmaSize;
+    }else{
+      bFlush = (
+          (pSorter->list.szPMA > pSorter->mxPmaSize)
+       || (pSorter->list.szPMA > pSorter->mnPmaSize && sqlite3HeapNearlyFull())
+      );
+    }
+    if( bFlush ){
+      rc = vdbeSorterFlushPMA(pSorter);
+      pSorter->list.szPMA = 0;
+      pSorter->iMemory = 0;
+      assert( rc!=SQLITE_OK || pSorter->list.pList==0 );
+    }
+  }
+
+  pSorter->list.szPMA += nPMA;
+  if( nPMA>pSorter->mxKeysize ){
+    pSorter->mxKeysize = nPMA;
+  }
+
+  if( pSorter->list.aMemory ){
+    int nMin = pSorter->iMemory + nReq;
+
+    if( nMin>pSorter->nMemory ){
+      u8 *aNew;
+      int nNew = pSorter->nMemory * 2;
+      while( nNew < nMin ) nNew = nNew*2;
+      if( nNew > pSorter->mxPmaSize ) nNew = pSorter->mxPmaSize;
+      if( nNew < nMin ) nNew = nMin;
+
+      aNew = sqlite3Realloc(pSorter->list.aMemory, nNew);
+      if( !aNew ) return SQLITE_NOMEM;
+      pSorter->list.pList = (SorterRecord*)(
+          aNew + ((u8*)pSorter->list.pList - pSorter->list.aMemory)
+      );
+      pSorter->list.aMemory = aNew;
+      pSorter->nMemory = nNew;
+    }
+
+    pNew = (SorterRecord*)&pSorter->list.aMemory[pSorter->iMemory];
+    pSorter->iMemory += ROUND8(nReq);
+    pNew->u.iNext = (int)((u8*)(pSorter->list.pList) - pSorter->list.aMemory);
+  }else{
+    pNew = (SorterRecord *)sqlite3Malloc(nReq);
+    if( pNew==0 ){
+      return SQLITE_NOMEM;
+    }
+    pNew->u.pNext = pSorter->list.pList;
+  }
+
+  memcpy(SRVAL(pNew), pVal->z, pVal->n);
+  pNew->nVal = pVal->n;
+  pSorter->list.pList = pNew;
+
+  return rc;
+}
+
+/*
+** Read keys from pIncr->pMerger and populate pIncr->aFile[1]. The format
+** of the data stored in aFile[1] is the same as that used by regular PMAs,
+** except that the number-of-bytes varint is omitted from the start.
+*/
+static int vdbeIncrPopulate(IncrMerger *pIncr){
+  int rc = SQLITE_OK;
+  int rc2;
+  i64 iStart = pIncr->iStartOff;
+  SorterFile *pOut = &pIncr->aFile[1];
+  SortSubtask *pTask = pIncr->pTask;
+  MergeEngine *pMerger = pIncr->pMerger;
+  PmaWriter writer;
+  assert( pIncr->bEof==0 );
+
+  vdbeSorterPopulateDebug(pTask, "enter");
+
+  vdbePmaWriterInit(pOut->pFd, &writer, pTask->pSorter->pgsz, iStart);
+  while( rc==SQLITE_OK ){
+    int dummy;
+    PmaReader *pReader = &pMerger->aReadr[ pMerger->aTree[1] ];
+    int nKey = pReader->nKey;
+    i64 iEof = writer.iWriteOff + writer.iBufEnd;
+
+    /* Check if the output file is full or if the input has been exhausted.
+    ** In either case exit the loop. */
+    if( pReader->pFd==0 ) break;
+    if( (iEof + nKey + sqlite3VarintLen(nKey))>(iStart + pIncr->mxSz) ) break;
+
+    /* Write the next key to the output. */
+    vdbePmaWriteVarint(&writer, nKey);
+    vdbePmaWriteBlob(&writer, pReader->aKey, nKey);
+    assert( pIncr->pMerger->pTask==pTask );
+    rc = vdbeMergeEngineStep(pIncr->pMerger, &dummy);
+  }
+
+  rc2 = vdbePmaWriterFinish(&writer, &pOut->iEof);
+  if( rc==SQLITE_OK ) rc = rc2;
+  vdbeSorterPopulateDebug(pTask, "exit");
+  return rc;
+}
+
+#if SQLITE_MAX_WORKER_THREADS>0
+/*
+** The main routine for background threads that populate aFile[1] of
+** multi-threaded IncrMerger objects.
+*/
+static void *vdbeIncrPopulateThread(void *pCtx){
+  IncrMerger *pIncr = (IncrMerger*)pCtx;
+  void *pRet = SQLITE_INT_TO_PTR( vdbeIncrPopulate(pIncr) );
+  pIncr->pTask->bDone = 1;
+  return pRet;
+}
+
+/*
+** Launch a background thread to populate aFile[1] of pIncr.
+*/
+static int vdbeIncrBgPopulate(IncrMerger *pIncr){
+  void *p = (void*)pIncr;
+  assert( pIncr->bUseThread );
+  return vdbeSorterCreateThread(pIncr->pTask, vdbeIncrPopulateThread, p);
+}
+#endif
+
+/*
+** This function is called when the PmaReader corresponding to pIncr has
+** finished reading the contents of aFile[0]. Its purpose is to "refill"
+** aFile[0] such that the PmaReader should start rereading it from the
+** beginning.
+**
+** For single-threaded objects, this is accomplished by literally reading 
+** keys from pIncr->pMerger and repopulating aFile[0]. 
+**
+** For multi-threaded objects, all that is required is to wait until the 
+** background thread is finished (if it is not already) and then swap 
+** aFile[0] and aFile[1] in place. If the contents of pMerger have not
+** been exhausted, this function also launches a new background thread
+** to populate the new aFile[1].
+**
+** SQLITE_OK is returned on success, or an SQLite error code otherwise.
+*/
+static int vdbeIncrSwap(IncrMerger *pIncr){
+  int rc = SQLITE_OK;
+
+#if SQLITE_MAX_WORKER_THREADS>0
+  if( pIncr->bUseThread ){
+    rc = vdbeSorterJoinThread(pIncr->pTask);
+
+    if( rc==SQLITE_OK ){
+      SorterFile f0 = pIncr->aFile[0];
+      pIncr->aFile[0] = pIncr->aFile[1];
+      pIncr->aFile[1] = f0;
+    }
+
+    if( rc==SQLITE_OK ){
+      if( pIncr->aFile[0].iEof==pIncr->iStartOff ){
+        pIncr->bEof = 1;
+      }else{
+        rc = vdbeIncrBgPopulate(pIncr);
+      }
+    }
+  }else
 #endif
-    rc = vdbeSorterListToPMA(db, pCsr);
-    pSorter->nInMemory = 0;
-    assert( rc!=SQLITE_OK || (nExpect==pSorter->iWriteOff) );
+  {
+    rc = vdbeIncrPopulate(pIncr);
+    pIncr->aFile[0] = pIncr->aFile[1];
+    if( pIncr->aFile[0].iEof==pIncr->iStartOff ){
+      pIncr->bEof = 1;
+    }
   }
 
   return rc;
 }
 
 /*
-** Helper function for sqlite3VdbeSorterRewind(). 
+** Allocate and return a new IncrMerger object to read data from pMerger.
+**
+** If an OOM condition is encountered, return NULL. In this case free the
+** pMerger argument before returning.
 */
-static int vdbeSorterInitMerge(
-  sqlite3 *db,                    /* Database handle */
-  const VdbeCursor *pCsr,         /* Cursor handle for this sorter */
-  i64 *pnByte                     /* Sum of bytes in all opened PMAs */
+static int vdbeIncrMergerNew(
+  SortSubtask *pTask,     /* The thread that will be using the new IncrMerger */
+  MergeEngine *pMerger,   /* The MergeEngine that the IncrMerger will control */
+  IncrMerger **ppOut      /* Write the new IncrMerger here */
+){
+  int rc = SQLITE_OK;
+  IncrMerger *pIncr = *ppOut = (IncrMerger*)
+       (sqlite3FaultSim(100) ? 0 : sqlite3MallocZero(sizeof(*pIncr)));
+  if( pIncr ){
+    pIncr->pMerger = pMerger;
+    pIncr->pTask = pTask;
+    pIncr->mxSz = MAX(pTask->pSorter->mxKeysize+9,pTask->pSorter->mxPmaSize/2);
+    pTask->file2.iEof += pIncr->mxSz;
+  }else{
+    vdbeMergeEngineFree(pMerger);
+    rc = SQLITE_NOMEM;
+  }
+  return rc;
+}
+
+#if SQLITE_MAX_WORKER_THREADS>0
+/*
+** Set the "use-threads" flag on object pIncr.
+*/
+static void vdbeIncrMergerSetThreads(IncrMerger *pIncr){
+  pIncr->bUseThread = 1;
+  pIncr->pTask->file2.iEof -= pIncr->mxSz;
+}
+#endif /* SQLITE_MAX_WORKER_THREADS>0 */
+
+
+
+/*
+** Recompute pMerger->aTree[iOut] by comparing the next keys on the
+** two PmaReaders that feed that entry.  Neither of the PmaReaders
+** are advanced.  This routine merely does the comparison.
+*/
+static void vdbeMergeEngineCompare(
+  MergeEngine *pMerger,  /* Merge engine containing PmaReaders to compare */
+  int iOut               /* Store the result in pMerger->aTree[iOut] */
+){
+  int i1;
+  int i2;
+  int iRes;
+  PmaReader *p1;
+  PmaReader *p2;
+
+  assert( iOut<pMerger->nTree && iOut>0 );
+
+  if( iOut>=(pMerger->nTree/2) ){
+    i1 = (iOut - pMerger->nTree/2) * 2;
+    i2 = i1 + 1;
+  }else{
+    i1 = pMerger->aTree[iOut*2];
+    i2 = pMerger->aTree[iOut*2+1];
+  }
+
+  p1 = &pMerger->aReadr[i1];
+  p2 = &pMerger->aReadr[i2];
+
+  if( p1->pFd==0 ){
+    iRes = i2;
+  }else if( p2->pFd==0 ){
+    iRes = i1;
+  }else{
+    SortSubtask *pTask = pMerger->pTask;
+    int bCached = 0;
+    int res;
+    assert( pTask->pUnpacked!=0 );  /* from vdbeSortSubtaskMain() */
+    res = pTask->xCompare(
+        pTask, &bCached, p1->aKey, p1->nKey, p2->aKey, p2->nKey
+    );
+    if( res<=0 ){
+      iRes = i1;
+    }else{
+      iRes = i2;
+    }
+  }
+
+  pMerger->aTree[iOut] = iRes;
+}
+
+/*
+** Allowed values for the eMode parameter to vdbeMergeEngineInit()
+** and vdbePmaReaderIncrMergeInit().
+**
+** Only INCRINIT_NORMAL is valid in single-threaded builds (when
+** SQLITE_MAX_WORKER_THREADS==0).  The other values are only used
+** when there exists one or more separate worker threads.
+*/
+#define INCRINIT_NORMAL 0
+#define INCRINIT_TASK   1
+#define INCRINIT_ROOT   2
+
+/* 
+** Forward reference required as the vdbeIncrMergeInit() and
+** vdbePmaReaderIncrInit() routines are called mutually recursively when
+** building a merge tree.
+*/
+static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode);
+
+/*
+** Initialize the MergeEngine object passed as the second argument. Once this
+** function returns, the first key of merged data may be read from the 
+** MergeEngine object in the usual fashion.
+**
+** If argument eMode is INCRINIT_ROOT, then it is assumed that any IncrMerge
+** objects attached to the PmaReader objects that the merger reads from have
+** already been populated, but that they have not yet populated aFile[0] and
+** set the PmaReader objects up to read from it. In this case all that is
+** required is to call vdbePmaReaderNext() on each PmaReader to point it at
+** its first key.
+**
+** Otherwise, if eMode is any value other than INCRINIT_ROOT, then use 
+** vdbePmaReaderIncrMergeInit() to initialize each PmaReader that feeds data 
+** to pMerger.
+**
+** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
+*/
+static int vdbeMergeEngineInit(
+  SortSubtask *pTask,             /* Thread that will run pMerger */
+  MergeEngine *pMerger,           /* MergeEngine to initialize */
+  int eMode                       /* One of the INCRINIT_XXX constants */
 ){
-  VdbeSorter *pSorter = pCsr->pSorter;
   int rc = SQLITE_OK;             /* Return code */
-  int i;                          /* Used to iterator through aIter[] */
-  i64 nByte = 0;                  /* Total bytes in all opened PMAs */
+  int i;                          /* For looping over PmaReader objects */
+  int nTree = pMerger->nTree;
+
+  /* eMode is always INCRINIT_NORMAL in single-threaded mode */
+  assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL );
+
+  /* Verify that the MergeEngine is assigned to a single thread */
+  assert( pMerger->pTask==0 );
+  pMerger->pTask = pTask;
+
+  for(i=0; i<nTree; i++){
+    if( SQLITE_MAX_WORKER_THREADS>0 && eMode==INCRINIT_ROOT ){
+      /* PmaReaders should be normally initialized in order, as if they are
+      ** reading from the same temp file this makes for more linear file IO.
+      ** However, in the INCRINIT_ROOT case, if PmaReader aReadr[nTask-1] is
+      ** in use it will block the vdbePmaReaderNext() call while it uses
+      ** the main thread to fill its buffer. So calling PmaReaderNext()
+      ** on this PmaReader before any of the multi-threaded PmaReaders takes
+      ** better advantage of multi-processor hardware. */
+      rc = vdbePmaReaderNext(&pMerger->aReadr[nTree-i-1]);
+    }else{
+      rc = vdbePmaReaderIncrInit(&pMerger->aReadr[i], INCRINIT_NORMAL);
+    }
+    if( rc!=SQLITE_OK ) return rc;
+  }
 
-  /* Initialize the iterators. */
-  for(i=0; i<SORTER_MAX_MERGE_COUNT; i++){
-    VdbeSorterIter *pIter = &pSorter->aIter[i];
-    rc = vdbeSorterIterInit(db, pSorter, pSorter->iReadOff, pIter, &nByte);
-    pSorter->iReadOff = pIter->iEof;
-    assert( rc!=SQLITE_OK || pSorter->iReadOff<=pSorter->iWriteOff );
-    if( rc!=SQLITE_OK || pSorter->iReadOff>=pSorter->iWriteOff ) break;
+  for(i=pMerger->nTree-1; i>0; i--){
+    vdbeMergeEngineCompare(pMerger, i);
   }
+  return pTask->pUnpacked->errCode;
+}
 
-  /* Initialize the aTree[] array. */
-  for(i=pSorter->nTree-1; rc==SQLITE_OK && i>0; i--){
-    rc = vdbeSorterDoCompare(pCsr, i);
+/*
+** The PmaReader passed as the first argument is guaranteed to be an
+** incremental-reader (pReadr->pIncr!=0). This function serves to open
+** and/or initialize the temp file related fields of the IncrMerge
+** object at (pReadr->pIncr).
+**
+** If argument eMode is set to INCRINIT_NORMAL, then all PmaReaders
+** in the sub-tree headed by pReadr are also initialized. Data is then 
+** loaded into the buffers belonging to pReadr and it is set to point to 
+** the first key in its range.
+**
+** If argument eMode is set to INCRINIT_TASK, then pReadr is guaranteed
+** to be a multi-threaded PmaReader and this function is being called in a
+** background thread. In this case all PmaReaders in the sub-tree are 
+** initialized as for INCRINIT_NORMAL and the aFile[1] buffer belonging to
+** pReadr is populated. However, pReadr itself is not set up to point
+** to its first key. A call to vdbePmaReaderNext() is still required to do
+** that. 
+**
+** The reason this function does not call vdbePmaReaderNext() immediately 
+** in the INCRINIT_TASK case is that vdbePmaReaderNext() assumes that it has
+** to block on thread (pTask->thread) before accessing aFile[1]. But, since
+** this entire function is being run by thread (pTask->thread), that will
+** lead to the current background thread attempting to join itself.
+**
+** Finally, if argument eMode is set to INCRINIT_ROOT, it may be assumed
+** that pReadr->pIncr is a multi-threaded IncrMerge objects, and that all
+** child-trees have already been initialized using IncrInit(INCRINIT_TASK).
+** In this case vdbePmaReaderNext() is called on all child PmaReaders and
+** the current PmaReader set to point to the first key in its range.
+**
+** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
+*/
+static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){
+  int rc = SQLITE_OK;
+  IncrMerger *pIncr = pReadr->pIncr;
+  SortSubtask *pTask = pIncr->pTask;
+  sqlite3 *db = pTask->pSorter->db;
+
+  /* eMode is always INCRINIT_NORMAL in single-threaded mode */
+  assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL );
+
+  rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode);
+
+  /* Set up the required files for pIncr. A multi-theaded IncrMerge object
+  ** requires two temp files to itself, whereas a single-threaded object
+  ** only requires a region of pTask->file2. */
+  if( rc==SQLITE_OK ){
+    int mxSz = pIncr->mxSz;
+#if SQLITE_MAX_WORKER_THREADS>0
+    if( pIncr->bUseThread ){
+      rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[0].pFd);
+      if( rc==SQLITE_OK ){
+        rc = vdbeSorterOpenTempFile(db, mxSz, &pIncr->aFile[1].pFd);
+      }
+    }else
+#endif
+    /*if( !pIncr->bUseThread )*/{
+      if( pTask->file2.pFd==0 ){
+        assert( pTask->file2.iEof>0 );
+        rc = vdbeSorterOpenTempFile(db, pTask->file2.iEof, &pTask->file2.pFd);
+        pTask->file2.iEof = 0;
+      }
+      if( rc==SQLITE_OK ){
+        pIncr->aFile[1].pFd = pTask->file2.pFd;
+        pIncr->iStartOff = pTask->file2.iEof;
+        pTask->file2.iEof += mxSz;
+      }
+    }
+  }
+
+#if SQLITE_MAX_WORKER_THREADS>0
+  if( rc==SQLITE_OK && pIncr->bUseThread ){
+    /* Use the current thread to populate aFile[1], even though this
+    ** PmaReader is multi-threaded. If this is an INCRINIT_TASK object,
+    ** then this function is already running in background thread 
+    ** pIncr->pTask->thread. 
+    **
+    ** If this is the INCRINIT_ROOT object, then it is running in the 
+    ** main VDBE thread. But that is Ok, as that thread cannot return
+    ** control to the VDBE or proceed with anything useful until the 
+    ** first results are ready from this merger object anyway.
+    */
+    assert( eMode==INCRINIT_ROOT || eMode==INCRINIT_TASK );
+    rc = vdbeIncrPopulate(pIncr);
+  }
+#endif
+
+  if( rc==SQLITE_OK && (SQLITE_MAX_WORKER_THREADS==0 || eMode!=INCRINIT_TASK) ){
+    rc = vdbePmaReaderNext(pReadr);
   }
 
-  *pnByte = nByte;
   return rc;
 }
 
+#if SQLITE_MAX_WORKER_THREADS>0
 /*
-** Once the sorter has been populated, this function is called to prepare
-** for iterating through its contents in sorted order.
+** The main routine for vdbePmaReaderIncrMergeInit() operations run in 
+** background threads.
 */
-SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){
-  VdbeSorter *pSorter = pCsr->pSorter;
-  int rc;                         /* Return code */
-  sqlite3_file *pTemp2 = 0;       /* Second temp file to use */
-  i64 iWrite2 = 0;                /* Write offset for pTemp2 */
-  int nIter;                      /* Number of iterators used */
-  int nByte;                      /* Bytes of space required for aIter/aTree */
-  int N = 2;                      /* Power of 2 >= nIter */
+static void *vdbePmaReaderBgIncrInit(void *pCtx){
+  PmaReader *pReader = (PmaReader*)pCtx;
+  void *pRet = SQLITE_INT_TO_PTR(
+                  vdbePmaReaderIncrMergeInit(pReader,INCRINIT_TASK)
+               );
+  pReader->pIncr->pTask->bDone = 1;
+  return pRet;
+}
+#endif
 
-  assert( pSorter );
+/*
+** If the PmaReader passed as the first argument is not an incremental-reader
+** (if pReadr->pIncr==0), then this function is a no-op. Otherwise, it invokes
+** the vdbePmaReaderIncrMergeInit() function with the parameters passed to
+** this routine to initialize the incremental merge.
+** 
+** If the IncrMerger object is multi-threaded (IncrMerger.bUseThread==1), 
+** then a background thread is launched to call vdbePmaReaderIncrMergeInit().
+** Or, if the IncrMerger is single threaded, the same function is called
+** using the current thread.
+*/
+static int vdbePmaReaderIncrInit(PmaReader *pReadr, int eMode){
+  IncrMerger *pIncr = pReadr->pIncr;   /* Incremental merger */
+  int rc = SQLITE_OK;                  /* Return code */
+  if( pIncr ){
+#if SQLITE_MAX_WORKER_THREADS>0
+    assert( pIncr->bUseThread==0 || eMode==INCRINIT_TASK );
+    if( pIncr->bUseThread ){
+      void *pCtx = (void*)pReadr;
+      rc = vdbeSorterCreateThread(pIncr->pTask, vdbePmaReaderBgIncrInit, pCtx);
+    }else
+#endif
+    {
+      rc = vdbePmaReaderIncrMergeInit(pReadr, eMode);
+    }
+  }
+  return rc;
+}
 
-  /* If no data has been written to disk, then do not do so now. Instead,
-  ** sort the VdbeSorter.pRecord list. The vdbe layer will read data directly
-  ** from the in-memory list.  */
-  if( pSorter->nPMA==0 ){
-    *pbEof = !pSorter->pRecord;
-    assert( pSorter->aTree==0 );
-    return vdbeSorterSort(pCsr);
+/*
+** Allocate a new MergeEngine object to merge the contents of nPMA level-0
+** PMAs from pTask->file. If no error occurs, set *ppOut to point to
+** the new object and return SQLITE_OK. Or, if an error does occur, set *ppOut
+** to NULL and return an SQLite error code.
+**
+** When this function is called, *piOffset is set to the offset of the
+** first PMA to read from pTask->file. Assuming no error occurs, it is 
+** set to the offset immediately following the last byte of the last
+** PMA before returning. If an error does occur, then the final value of
+** *piOffset is undefined.
+*/
+static int vdbeMergeEngineLevel0(
+  SortSubtask *pTask,             /* Sorter task to read from */
+  int nPMA,                       /* Number of PMAs to read */
+  i64 *piOffset,                  /* IN/OUT: Readr offset in pTask->file */
+  MergeEngine **ppOut             /* OUT: New merge-engine */
+){
+  MergeEngine *pNew;              /* Merge engine to return */
+  i64 iOff = *piOffset;
+  int i;
+  int rc = SQLITE_OK;
+
+  *ppOut = pNew = vdbeMergeEngineNew(nPMA);
+  if( pNew==0 ) rc = SQLITE_NOMEM;
+
+  for(i=0; i<nPMA && rc==SQLITE_OK; i++){
+    i64 nDummy;
+    PmaReader *pReadr = &pNew->aReadr[i];
+    rc = vdbePmaReaderInit(pTask, &pTask->file, iOff, pReadr, &nDummy);
+    iOff = pReadr->iEof;
   }
 
-  /* Write the current in-memory list to a PMA. */
-  rc = vdbeSorterListToPMA(db, pCsr);
-  if( rc!=SQLITE_OK ) return rc;
+  if( rc!=SQLITE_OK ){
+    vdbeMergeEngineFree(pNew);
+    *ppOut = 0;
+  }
+  *piOffset = iOff;
+  return rc;
+}
 
-  /* Allocate space for aIter[] and aTree[]. */
-  nIter = pSorter->nPMA;
-  if( nIter>SORTER_MAX_MERGE_COUNT ) nIter = SORTER_MAX_MERGE_COUNT;
-  assert( nIter>0 );
-  while( N<nIter ) N += N;
-  nByte = N * (sizeof(int) + sizeof(VdbeSorterIter));
-  pSorter->aIter = (VdbeSorterIter *)sqlite3DbMallocZero(db, nByte);
-  if( !pSorter->aIter ) return SQLITE_NOMEM;
-  pSorter->aTree = (int *)&pSorter->aIter[N];
-  pSorter->nTree = N;
+/*
+** Return the depth of a tree comprising nPMA PMAs, assuming a fanout of
+** SORTER_MAX_MERGE_COUNT. The returned value does not include leaf nodes.
+**
+** i.e.
+**
+**   nPMA<=16    -> TreeDepth() == 0
+**   nPMA<=256   -> TreeDepth() == 1
+**   nPMA<=65536 -> TreeDepth() == 2
+*/
+static int vdbeSorterTreeDepth(int nPMA){
+  int nDepth = 0;
+  i64 nDiv = SORTER_MAX_MERGE_COUNT;
+  while( nDiv < (i64)nPMA ){
+    nDiv = nDiv * SORTER_MAX_MERGE_COUNT;
+    nDepth++;
+  }
+  return nDepth;
+}
 
-  do {
-    int iNew;                     /* Index of new, merged, PMA */
+/*
+** pRoot is the root of an incremental merge-tree with depth nDepth (according
+** to vdbeSorterTreeDepth()). pLeaf is the iSeq'th leaf to be added to the
+** tree, counting from zero. This function adds pLeaf to the tree.
+**
+** If successful, SQLITE_OK is returned. If an error occurs, an SQLite error
+** code is returned and pLeaf is freed.
+*/
+static int vdbeSorterAddToTree(
+  SortSubtask *pTask,             /* Task context */
+  int nDepth,                     /* Depth of tree according to TreeDepth() */
+  int iSeq,                       /* Sequence number of leaf within tree */
+  MergeEngine *pRoot,             /* Root of tree */
+  MergeEngine *pLeaf              /* Leaf to add to tree */
+){
+  int rc = SQLITE_OK;
+  int nDiv = 1;
+  int i;
+  MergeEngine *p = pRoot;
+  IncrMerger *pIncr;
 
-    for(iNew=0; 
-        rc==SQLITE_OK && iNew*SORTER_MAX_MERGE_COUNT<pSorter->nPMA; 
-        iNew++
-    ){
-      int rc2;                    /* Return code from fileWriterFinish() */
-      FileWriter writer;          /* Object used to write to disk */
-      i64 nWrite;                 /* Number of bytes in new PMA */
+  rc = vdbeIncrMergerNew(pTask, pLeaf, &pIncr);
 
-      memset(&writer, 0, sizeof(FileWriter));
+  for(i=1; i<nDepth; i++){
+    nDiv = nDiv * SORTER_MAX_MERGE_COUNT;
+  }
 
-      /* If there are SORTER_MAX_MERGE_COUNT or less PMAs in file pTemp1,
-      ** initialize an iterator for each of them and break out of the loop.
-      ** These iterators will be incrementally merged as the VDBE layer calls
-      ** sqlite3VdbeSorterNext().
-      **
-      ** Otherwise, if pTemp1 contains more than SORTER_MAX_MERGE_COUNT PMAs,
-      ** initialize interators for SORTER_MAX_MERGE_COUNT of them. These PMAs
-      ** are merged into a single PMA that is written to file pTemp2.
-      */
-      rc = vdbeSorterInitMerge(db, pCsr, &nWrite);
-      assert( rc!=SQLITE_OK || pSorter->aIter[ pSorter->aTree[1] ].pFile );
-      if( rc!=SQLITE_OK || pSorter->nPMA<=SORTER_MAX_MERGE_COUNT ){
-        break;
+  for(i=1; i<nDepth && rc==SQLITE_OK; i++){
+    int iIter = (iSeq / nDiv) % SORTER_MAX_MERGE_COUNT;
+    PmaReader *pReadr = &p->aReadr[iIter];
+
+    if( pReadr->pIncr==0 ){
+      MergeEngine *pNew = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT);
+      if( pNew==0 ){
+        rc = SQLITE_NOMEM;
+      }else{
+        rc = vdbeIncrMergerNew(pTask, pNew, &pReadr->pIncr);
       }
+    }
+    if( rc==SQLITE_OK ){
+      p = pReadr->pIncr->pMerger;
+      nDiv = nDiv / SORTER_MAX_MERGE_COUNT;
+    }
+  }
 
-      /* Open the second temp file, if it is not already open. */
-      if( pTemp2==0 ){
-        assert( iWrite2==0 );
-        rc = vdbeSorterOpenTempFile(db, &pTemp2);
+  if( rc==SQLITE_OK ){
+    p->aReadr[iSeq % SORTER_MAX_MERGE_COUNT].pIncr = pIncr;
+  }else{
+    vdbeIncrFree(pIncr);
+  }
+  return rc;
+}
+
+/*
+** This function is called as part of a SorterRewind() operation on a sorter
+** that has already written two or more level-0 PMAs to one or more temp
+** files. It builds a tree of MergeEngine/IncrMerger/PmaReader objects that 
+** can be used to incrementally merge all PMAs on disk.
+**
+** If successful, SQLITE_OK is returned and *ppOut set to point to the
+** MergeEngine object at the root of the tree before returning. Or, if an
+** error occurs, an SQLite error code is returned and the final value 
+** of *ppOut is undefined.
+*/
+static int vdbeSorterMergeTreeBuild(
+  VdbeSorter *pSorter,       /* The VDBE cursor that implements the sort */
+  MergeEngine **ppOut        /* Write the MergeEngine here */
+){
+  MergeEngine *pMain = 0;
+  int rc = SQLITE_OK;
+  int iTask;
+
+#if SQLITE_MAX_WORKER_THREADS>0
+  /* If the sorter uses more than one task, then create the top-level 
+  ** MergeEngine here. This MergeEngine will read data from exactly 
+  ** one PmaReader per sub-task.  */
+  assert( pSorter->bUseThreads || pSorter->nTask==1 );
+  if( pSorter->nTask>1 ){
+    pMain = vdbeMergeEngineNew(pSorter->nTask);
+    if( pMain==0 ) rc = SQLITE_NOMEM;
+  }
+#endif
+
+  for(iTask=0; rc==SQLITE_OK && iTask<pSorter->nTask; iTask++){
+    SortSubtask *pTask = &pSorter->aTask[iTask];
+    assert( pTask->nPMA>0 || SQLITE_MAX_WORKER_THREADS>0 );
+    if( SQLITE_MAX_WORKER_THREADS==0 || pTask->nPMA ){
+      MergeEngine *pRoot = 0;     /* Root node of tree for this task */
+      int nDepth = vdbeSorterTreeDepth(pTask->nPMA);
+      i64 iReadOff = 0;
+
+      if( pTask->nPMA<=SORTER_MAX_MERGE_COUNT ){
+        rc = vdbeMergeEngineLevel0(pTask, pTask->nPMA, &iReadOff, &pRoot);
+      }else{
+        int i;
+        int iSeq = 0;
+        pRoot = vdbeMergeEngineNew(SORTER_MAX_MERGE_COUNT);
+        if( pRoot==0 ) rc = SQLITE_NOMEM;
+        for(i=0; i<pTask->nPMA && rc==SQLITE_OK; i += SORTER_MAX_MERGE_COUNT){
+          MergeEngine *pMerger = 0; /* New level-0 PMA merger */
+          int nReader;              /* Number of level-0 PMAs to merge */
+
+          nReader = MIN(pTask->nPMA - i, SORTER_MAX_MERGE_COUNT);
+          rc = vdbeMergeEngineLevel0(pTask, nReader, &iReadOff, &pMerger);
+          if( rc==SQLITE_OK ){
+            rc = vdbeSorterAddToTree(pTask, nDepth, iSeq++, pRoot, pMerger);
+          }
+        }
       }
 
       if( rc==SQLITE_OK ){
-        int bEof = 0;
-        fileWriterInit(db, pTemp2, &writer, iWrite2);
-        fileWriterWriteVarint(&writer, nWrite);
-        while( rc==SQLITE_OK && bEof==0 ){
-          VdbeSorterIter *pIter = &pSorter->aIter[ pSorter->aTree[1] ];
-          assert( pIter->pFile );
+#if SQLITE_MAX_WORKER_THREADS>0
+        if( pMain!=0 ){
+          rc = vdbeIncrMergerNew(pTask, pRoot, &pMain->aReadr[iTask].pIncr);
+        }else
+#endif
+        {
+          assert( pMain==0 );
+          pMain = pRoot;
+        }
+      }else{
+        vdbeMergeEngineFree(pRoot);
+      }
+    }
+  }
+
+  if( rc!=SQLITE_OK ){
+    vdbeMergeEngineFree(pMain);
+    pMain = 0;
+  }
+  *ppOut = pMain;
+  return rc;
+}
+
+/*
+** This function is called as part of an sqlite3VdbeSorterRewind() operation
+** on a sorter that has written two or more PMAs to temporary files. It sets
+** up either VdbeSorter.pMerger (for single threaded sorters) or pReader
+** (for multi-threaded sorters) so that it can be used to iterate through
+** all records stored in the sorter.
+**
+** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
+*/
+static int vdbeSorterSetupMerge(VdbeSorter *pSorter){
+  int rc;                         /* Return code */
+  SortSubtask *pTask0 = &pSorter->aTask[0];
+  MergeEngine *pMain = 0;
+#if SQLITE_MAX_WORKER_THREADS
+  sqlite3 *db = pTask0->pSorter->db;
+  int i;
+  SorterCompare xCompare = vdbeSorterGetCompare(pSorter);
+  for(i=0; i<pSorter->nTask; i++){
+    pSorter->aTask[i].xCompare = xCompare;
+  }
+#endif
 
-          fileWriterWriteVarint(&writer, pIter->nKey);
-          fileWriterWrite(&writer, pIter->aKey, pIter->nKey);
-          rc = sqlite3VdbeSorterNext(db, pCsr, &bEof);
+  rc = vdbeSorterMergeTreeBuild(pSorter, &pMain);
+  if( rc==SQLITE_OK ){
+#if SQLITE_MAX_WORKER_THREADS
+    assert( pSorter->bUseThreads==0 || pSorter->nTask>1 );
+    if( pSorter->bUseThreads ){
+      int iTask;
+      PmaReader *pReadr = 0;
+      SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1];
+      rc = vdbeSortAllocUnpacked(pLast);
+      if( rc==SQLITE_OK ){
+        pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader));
+        pSorter->pReader = pReadr;
+        if( pReadr==0 ) rc = SQLITE_NOMEM;
+      }
+      if( rc==SQLITE_OK ){
+        rc = vdbeIncrMergerNew(pLast, pMain, &pReadr->pIncr);
+        if( rc==SQLITE_OK ){
+          vdbeIncrMergerSetThreads(pReadr->pIncr);
+          for(iTask=0; iTask<(pSorter->nTask-1); iTask++){
+            IncrMerger *pIncr;
+            if( (pIncr = pMain->aReadr[iTask].pIncr) ){
+              vdbeIncrMergerSetThreads(pIncr);
+              assert( pIncr->pTask!=pLast );
+            }
+          }
+          for(iTask=0; rc==SQLITE_OK && iTask<pSorter->nTask; iTask++){
+            /* Check that:
+            **   
+            **   a) The incremental merge object is configured to use the
+            **      right task, and
+            **   b) If it is using task (nTask-1), it is configured to run
+            **      in single-threaded mode. This is important, as the
+            **      root merge (INCRINIT_ROOT) will be using the same task
+            **      object.
+            */
+            PmaReader *p = &pMain->aReadr[iTask];
+            assert( p->pIncr==0 || (
+                (p->pIncr->pTask==&pSorter->aTask[iTask])             /* a */
+             && (iTask!=pSorter->nTask-1 || p->pIncr->bUseThread==0)  /* b */
+            ));
+            rc = vdbePmaReaderIncrInit(p, INCRINIT_TASK);
+          }
         }
-        rc2 = fileWriterFinish(db, &writer, &iWrite2);
-        if( rc==SQLITE_OK ) rc = rc2;
+        pMain = 0;
       }
+      if( rc==SQLITE_OK ){
+        rc = vdbePmaReaderIncrMergeInit(pReadr, INCRINIT_ROOT);
+      }
+    }else
+#endif
+    {
+      rc = vdbeMergeEngineInit(pTask0, pMain, INCRINIT_NORMAL);
+      pSorter->pMerger = pMain;
+      pMain = 0;
     }
+  }
 
-    if( pSorter->nPMA<=SORTER_MAX_MERGE_COUNT ){
-      break;
+  if( rc!=SQLITE_OK ){
+    vdbeMergeEngineFree(pMain);
+  }
+  return rc;
+}
+
+
+/*
+** Once the sorter has been populated by calls to sqlite3VdbeSorterWrite,
+** this function is called to prepare for iterating through the records
+** in sorted order.
+*/
+SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *pCsr, int *pbEof){
+  VdbeSorter *pSorter = pCsr->pSorter;
+  int rc = SQLITE_OK;             /* Return code */
+
+  assert( pSorter );
+
+  /* If no data has been written to disk, then do not do so now. Instead,
+  ** sort the VdbeSorter.pRecord list. The vdbe layer will read data directly
+  ** from the in-memory list.  */
+  if( pSorter->bUsePMA==0 ){
+    if( pSorter->list.pList ){
+      *pbEof = 0;
+      rc = vdbeSorterSort(&pSorter->aTask[0], &pSorter->list);
     }else{
-      sqlite3_file *pTmp = pSorter->pTemp1;
-      pSorter->nPMA = iNew;
-      pSorter->pTemp1 = pTemp2;
-      pTemp2 = pTmp;
-      pSorter->iWriteOff = iWrite2;
-      pSorter->iReadOff = 0;
-      iWrite2 = 0;
+      *pbEof = 1;
     }
-  }while( rc==SQLITE_OK );
+    return rc;
+  }
+
+  /* Write the current in-memory list to a PMA. When the VdbeSorterWrite() 
+  ** function flushes the contents of memory to disk, it immediately always
+  ** creates a new list consisting of a single key immediately afterwards.
+  ** So the list is never empty at this point.  */
+  assert( pSorter->list.pList );
+  rc = vdbeSorterFlushPMA(pSorter);
+
+  /* Join all threads */
+  rc = vdbeSorterJoinAll(pSorter, rc);
 
-  if( pTemp2 ){
-    sqlite3OsCloseFree(pTemp2);
+  vdbeSorterRewindDebug("rewind");
+
+  /* Assuming no errors have occurred, set up a merger structure to 
+  ** incrementally read and merge all remaining PMAs.  */
+  assert( pSorter->pReader==0 );
+  if( rc==SQLITE_OK ){
+    rc = vdbeSorterSetupMerge(pSorter);
+    *pbEof = 0;
   }
-  *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0);
+
+  vdbeSorterRewindDebug("rewinddone");
   return rc;
 }
 
@@ -75968,63 +80499,28 @@ SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr, in
   VdbeSorter *pSorter = pCsr->pSorter;
   int rc;                         /* Return code */
 
-  if( pSorter->aTree ){
-    int iPrev = pSorter->aTree[1];/* Index of iterator to advance */
-    rc = vdbeSorterIterNext(db, &pSorter->aIter[iPrev]);
-    if( rc==SQLITE_OK ){
-      int i;                      /* Index of aTree[] to recalculate */
-      VdbeSorterIter *pIter1;     /* First iterator to compare */
-      VdbeSorterIter *pIter2;     /* Second iterator to compare */
-      u8 *pKey2;                  /* To pIter2->aKey, or 0 if record cached */
-
-      /* Find the first two iterators to compare. The one that was just
-      ** advanced (iPrev) and the one next to it in the array.  */
-      pIter1 = &pSorter->aIter[(iPrev & 0xFFFE)];
-      pIter2 = &pSorter->aIter[(iPrev | 0x0001)];
-      pKey2 = pIter2->aKey;
-
-      for(i=(pSorter->nTree+iPrev)/2; i>0; i=i/2){
-        /* Compare pIter1 and pIter2. Store the result in variable iRes. */
-        int iRes;
-        if( pIter1->pFile==0 ){
-          iRes = +1;
-        }else if( pIter2->pFile==0 ){
-          iRes = -1;
-        }else{
-          vdbeSorterCompare(pCsr, 0, 
-              pIter1->aKey, pIter1->nKey, pKey2, pIter2->nKey, &iRes
-          );
-        }
-
-        /* If pIter1 contained the smaller value, set aTree[i] to its index.
-        ** Then set pIter2 to the next iterator to compare to pIter1. In this
-        ** case there is no cache of pIter2 in pSorter->pUnpacked, so set
-        ** pKey2 to point to the record belonging to pIter2.
-        **
-        ** Alternatively, if pIter2 contains the smaller of the two values,
-        ** set aTree[i] to its index and update pIter1. If vdbeSorterCompare()
-        ** was actually called above, then pSorter->pUnpacked now contains
-        ** a value equivalent to pIter2. So set pKey2 to NULL to prevent
-        ** vdbeSorterCompare() from decoding pIter2 again.  */
-        if( iRes<=0 ){
-          pSorter->aTree[i] = (int)(pIter1 - pSorter->aIter);
-          pIter2 = &pSorter->aIter[ pSorter->aTree[i ^ 0x0001] ];
-          pKey2 = pIter2->aKey;
-        }else{
-          if( pIter1->pFile ) pKey2 = 0;
-          pSorter->aTree[i] = (int)(pIter2 - pSorter->aIter);
-          pIter1 = &pSorter->aIter[ pSorter->aTree[i ^ 0x0001] ];
-        }
-
-      }
-      *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0);
+  assert( pSorter->bUsePMA || (pSorter->pReader==0 && pSorter->pMerger==0) );
+  if( pSorter->bUsePMA ){
+    assert( pSorter->pReader==0 || pSorter->pMerger==0 );
+    assert( pSorter->bUseThreads==0 || pSorter->pReader );
+    assert( pSorter->bUseThreads==1 || pSorter->pMerger );
+#if SQLITE_MAX_WORKER_THREADS>0
+    if( pSorter->bUseThreads ){
+      rc = vdbePmaReaderNext(pSorter->pReader);
+      *pbEof = (pSorter->pReader->pFd==0);
+    }else
+#endif
+    /*if( !pSorter->bUseThreads )*/ {
+      assert( pSorter->pMerger!=0 );
+      assert( pSorter->pMerger->pTask==(&pSorter->aTask[0]) );
+      rc = vdbeMergeEngineStep(pSorter->pMerger, pbEof);
     }
   }else{
-    SorterRecord *pFree = pSorter->pRecord;
-    pSorter->pRecord = pFree->pNext;
-    pFree->pNext = 0;
-    vdbeSorterRecordFree(db, pFree);
-    *pbEof = !pSorter->pRecord;
+    SorterRecord *pFree = pSorter->list.pList;
+    pSorter->list.pList = pFree->u.pNext;
+    pFree->u.pNext = 0;
+    if( pSorter->list.aMemory==0 ) vdbeSorterRecordFree(db, pFree);
+    *pbEof = !pSorter->list.pList;
     rc = SQLITE_OK;
   }
   return rc;
@@ -76039,14 +80535,21 @@ static void *vdbeSorterRowkey(
   int *pnKey                      /* OUT: Size of current key in bytes */
 ){
   void *pKey;
-  if( pSorter->aTree ){
-    VdbeSorterIter *pIter;
-    pIter = &pSorter->aIter[ pSorter->aTree[1] ];
-    *pnKey = pIter->nKey;
-    pKey = pIter->aKey;
+  if( pSorter->bUsePMA ){
+    PmaReader *pReader;
+#if SQLITE_MAX_WORKER_THREADS>0
+    if( pSorter->bUseThreads ){
+      pReader = pSorter->pReader;
+    }else
+#endif
+    /*if( !pSorter->bUseThreads )*/{
+      pReader = &pSorter->pMerger->aReadr[pSorter->pMerger->aTree[1]];
+    }
+    *pnKey = pReader->nKey;
+    pKey = pReader->aKey;
   }else{
-    *pnKey = pSorter->pRecord->nVal;
-    pKey = pSorter->pRecord->pVal;
+    *pnKey = pSorter->list.pList->nVal;
+    pKey = SRVAL(pSorter->list.pList);
   }
   return pKey;
 }
@@ -76059,7 +80562,7 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){
   void *pKey; int nKey;           /* Sorter key to copy into pOut */
 
   pKey = vdbeSorterRowkey(pSorter, &nKey);
-  if( sqlite3VdbeMemGrow(pOut, nKey, 0) ){
+  if( sqlite3VdbeMemClearAndResize(pOut, nKey) ){
     return SQLITE_NOMEM;
   }
   pOut->n = nKey;
@@ -76074,22 +80577,48 @@ SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){
 ** passed as the first argument currently points to. For the purposes of
 ** the comparison, ignore the rowid field at the end of each record.
 **
+** If the sorter cursor key contains any NULL values, consider it to be
+** less than pVal. Even if pVal also contains NULL values.
+**
 ** If an error occurs, return an SQLite error code (i.e. SQLITE_NOMEM).
 ** Otherwise, set *pRes to a negative, zero or positive value if the
 ** key in pVal is smaller than, equal to or larger than the current sorter
 ** key.
+**
+** This routine forms the core of the OP_SorterCompare opcode, which in
+** turn is used to verify uniqueness when constructing a UNIQUE INDEX.
 */
 SQLITE_PRIVATE int sqlite3VdbeSorterCompare(
   const VdbeCursor *pCsr,         /* Sorter cursor */
   Mem *pVal,                      /* Value to compare to current sorter key */
-  int nKeyCol,                    /* Only compare this many fields */
+  int nKeyCol,                    /* Compare this many columns */
   int *pRes                       /* OUT: Result of comparison */
 ){
   VdbeSorter *pSorter = pCsr->pSorter;
+  UnpackedRecord *r2 = pSorter->pUnpacked;
+  KeyInfo *pKeyInfo = pCsr->pKeyInfo;
+  int i;
   void *pKey; int nKey;           /* Sorter key to compare pVal with */
 
+  if( r2==0 ){
+    char *p;
+    r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo,0,0,&p);
+    assert( pSorter->pUnpacked==(UnpackedRecord*)p );
+    if( r2==0 ) return SQLITE_NOMEM;
+    r2->nField = nKeyCol;
+  }
+  assert( r2->nField==nKeyCol );
+
   pKey = vdbeSorterRowkey(pSorter, &nKey);
-  vdbeSorterCompare(pCsr, nKeyCol, pVal->z, pVal->n, pKey, nKey, pRes);
+  sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, r2);
+  for(i=0; i<nKeyCol; i++){
+    if( r2->aMem[i].flags & MEM_Null ){
+      *pRes = -1;
+      return SQLITE_OK;
+    }
+  }
+
+  *pRes = sqlite3VdbeRecordCompare(pVal->n, pVal->z, r2);
   return SQLITE_OK;
 }
 
@@ -76380,7 +80909,7 @@ typedef struct FileChunk FileChunk;
 **
 ** The size chosen is a little less than a power of two.  That way,
 ** the FileChunk object will have a size that almost exactly fills
-** a power-of-two allocation.  This mimimizes wasted space in power-of-two
+** a power-of-two allocation.  This minimizes wasted space in power-of-two
 ** memory allocators.
 */
 #define JOURNAL_CHUNKSIZE ((int)(1024-sizeof(FileChunk*)))
@@ -76630,7 +81159,7 @@ SQLITE_PRIVATE int sqlite3MemJournalSize(void){
 
 /*
 ** Walk an expression tree.  Invoke the callback once for each node
-** of the expression, while decending.  (In other words, the callback
+** of the expression, while descending.  (In other words, the callback
 ** is invoked before visiting children.)
 **
 ** The return value from the callback should be one of the WRC_*
@@ -76795,7 +81324,7 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){
 ** is a helper function - a callback for the tree walker.
 */
 static int incrAggDepth(Walker *pWalker, Expr *pExpr){
-  if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.i;
+  if( pExpr->op==TK_AGG_FUNCTION ) pExpr->op2 += pWalker->u.n;
   return WRC_Continue;
 }
 static void incrAggFunctionDepth(Expr *pExpr, int N){
@@ -76803,7 +81332,7 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){
     Walker w;
     memset(&w, 0, sizeof(w));
     w.xExprCallback = incrAggDepth;
-    w.u.i = N;
+    w.u.n = N;
     sqlite3WalkExpr(&w, pExpr);
   }
 }
@@ -76846,7 +81375,7 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){
 **     SELECT a+b, c+d FROM t1 ORDER BY (a+b) COLLATE nocase;
 **
 ** The nSubquery parameter specifies how many levels of subquery the
-** alias is removed from the original expression.  The usually value is
+** alias is removed from the original expression.  The usual value is
 ** zero but it might be more if the alias is contained within a subquery
 ** of the original expression.  The Expr.op2 field of TK_AGG_FUNCTION
 ** structures must be increased by the nSubquery amount.
@@ -76866,7 +81395,6 @@ static void resolveAlias(
   assert( iCol>=0 && iCol<pEList->nExpr );
   pOrig = pEList->a[iCol].pExpr;
   assert( pOrig!=0 );
-  assert( pOrig->flags & EP_Resolved );
   db = pParse->db;
   pDup = sqlite3ExprDup(db, pOrig, 0);
   if( pDup==0 ) return;
@@ -77014,9 +81542,10 @@ static int lookupName(
     testcase( pNC->ncFlags & NC_PartIdx );
     testcase( pNC->ncFlags & NC_IsCheck );
     if( (pNC->ncFlags & (NC_PartIdx|NC_IsCheck))!=0 ){
-      /* Silently ignore database qualifiers inside CHECK constraints and partial
-      ** indices.  Do not raise errors because that might break legacy and
-      ** because it does not hurt anything to just ignore the database name. */
+      /* Silently ignore database qualifiers inside CHECK constraints and
+      ** partial indices.  Do not raise errors because that might break
+      ** legacy and because it does not hurt anything to just ignore the
+      ** database name. */
       zDb = 0;
     }else{
       for(i=0; i<db->nDb; i++){
@@ -77087,6 +81616,11 @@ static int lookupName(
       if( pMatch ){
         pExpr->iTable = pMatch->iCursor;
         pExpr->pTab = pMatch->pTab;
+        /* RIGHT JOIN not (yet) supported */
+        assert( (pMatch->jointype & JT_RIGHT)==0 );
+        if( (pMatch->jointype & JT_LEFT)!=0 ){
+          ExprSetProperty(pExpr, EP_CanBeNull);
+        }
         pSchema = pExpr->pTab->pSchema;
       }
     } /* if( pSrcList ) */
@@ -77351,7 +81885,7 @@ static int exprProbability(Expr *p){
   sqlite3AtoF(p->u.zToken, &r, sqlite3Strlen30(p->u.zToken), SQLITE_UTF8);
   assert( r>=0.0 );
   if( r>1.0 ) return -1;
-  return (int)(r*1000.0);
+  return (int)(r*134217728.0);
 }
 
 /*
@@ -77404,7 +81938,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
       pExpr->affinity = SQLITE_AFF_INTEGER;
       break;
     }
-#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) */
+#endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT)
+          && !defined(SQLITE_OMIT_SUBQUERY) */
 
     /* A lone identifier is the name of a column.
     */
@@ -77469,26 +82004,25 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
           if( n==2 ){
             pExpr->iTable = exprProbability(pList->a[1].pExpr);
             if( pExpr->iTable<0 ){
-              sqlite3ErrorMsg(pParse, "second argument to likelihood() must be a "
-                                      "constant between 0.0 and 1.0");
+              sqlite3ErrorMsg(pParse,
+                "second argument to likelihood() must be a "
+                "constant between 0.0 and 1.0");
               pNC->nErr++;
             }
           }else{
-            /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is equivalent to
-            ** likelihood(X, 0.0625).
-            ** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is short-hand for
-            ** likelihood(X,0.0625).
-            ** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand for
-            ** likelihood(X,0.9375).
-            ** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent to
-            ** likelihood(X,0.9375). */
+            /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is
+            ** equivalent to likelihood(X, 0.0625).
+            ** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is
+            ** short-hand for likelihood(X,0.0625).
+            ** EVIDENCE-OF: R-36850-34127 The likely(X) function is short-hand
+            ** for likelihood(X,0.9375).
+            ** EVIDENCE-OF: R-53436-40973 The likely(X) function is equivalent
+            ** to likelihood(X,0.9375). */
             /* TUNING: unlikely() probability is 0.0625.  likely() is 0.9375 */
-            pExpr->iTable = pDef->zName[0]=='u' ? 62 : 938;
+            pExpr->iTable = pDef->zName[0]=='u' ? 8388608 : 125829120;
           }             
         }
-      }
 #ifndef SQLITE_OMIT_AUTHORIZATION
-      if( pDef ){
         auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0, pDef->zName, 0);
         if( auth!=SQLITE_OK ){
           if( auth==SQLITE_DENY ){
@@ -77499,9 +82033,11 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
           pExpr->op = TK_NULL;
           return WRC_Prune;
         }
-        if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ) ExprSetProperty(pExpr,EP_Constant);
-      }
 #endif
+        if( pDef->funcFlags & SQLITE_FUNC_CONSTANT ){
+          ExprSetProperty(pExpr,EP_ConstFunc);
+        }
+      }
       if( is_agg && (pNC->ncFlags & NC_AllowAgg)==0 ){
         sqlite3ErrorMsg(pParse, "misuse of aggregate function %.*s()", nId,zId);
         pNC->nErr++;
@@ -77524,7 +82060,13 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
           pExpr->op2++;
           pNC2 = pNC2->pNext;
         }
-        if( pNC2 ) pNC2->ncFlags |= NC_HasAgg;
+        assert( pDef!=0 );
+        if( pNC2 ){
+          assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
+          testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
+          pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX);
+
+        }
         pNC->ncFlags |= NC_AllowAgg;
       }
       /* FIX ME:  Compute pExpr->affinity based on the expected return
@@ -77746,9 +82288,11 @@ static int resolveCompoundOrderBy(
         if( pItem->pExpr==pE ){
           pItem->pExpr = pNew;
         }else{
-          assert( pItem->pExpr->op==TK_COLLATE );
-          assert( pItem->pExpr->pLeft==pE );
-          pItem->pExpr->pLeft = pNew;
+          Expr *pParent = pItem->pExpr;
+          assert( pParent->op==TK_COLLATE );
+          while( pParent->pLeft->op==TK_COLLATE ) pParent = pParent->pLeft;
+          assert( pParent->pLeft==pE );
+          pParent->pLeft = pNew;
         }
         sqlite3ExprDelete(db, pE);
         pItem->u.x.iOrderByCol = (u16)iCol;
@@ -77805,7 +82349,8 @@ SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(
         resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
         return 1;
       }
-      resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr, zType,0);
+      resolveAlias(pParse, pEList, pItem->u.x.iOrderByCol-1, pItem->pExpr,
+                   zType,0);
     }
   }
   return 0;
@@ -77885,7 +82430,7 @@ static int resolveOrderGroupBy(
 }
 
 /*
-** Resolve names in the SELECT statement p and all of its descendents.
+** Resolve names in the SELECT statement p and all of its descendants.
 */
 static int resolveSelectStep(Walker *pWalker, Select *p){
   NameContext *pOuterNC;  /* Context that contains this SELECT */
@@ -77938,6 +82483,20 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
         sqlite3ResolveExprNames(&sNC, p->pOffset) ){
       return WRC_Abort;
     }
+
+    /* If the SF_Converted flags is set, then this Select object was
+    ** was created by the convertCompoundSelectToSubquery() function.
+    ** In this case the ORDER BY clause (p->pOrderBy) should be resolved
+    ** as if it were part of the sub-query, not the parent. This block
+    ** moves the pOrderBy down to the sub-query. It will be moved back
+    ** after the names have been resolved.  */
+    if( p->selFlags & SF_Converted ){
+      Select *pSub = p->pSrc->a[0].pSelect;
+      assert( p->pSrc->nSrc==1 && p->pOrderBy );
+      assert( pSub->pPrior && pSub->pOrderBy==0 );
+      pSub->pOrderBy = p->pOrderBy;
+      p->pOrderBy = 0;
+    }
   
     /* Recursively resolve names in all subqueries
     */
@@ -77989,7 +82548,8 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
     assert( (p->selFlags & SF_Aggregate)==0 );
     pGroupBy = p->pGroupBy;
     if( pGroupBy || (sNC.ncFlags & NC_HasAgg)!=0 ){
-      p->selFlags |= SF_Aggregate;
+      assert( NC_MinMaxAgg==SF_MinMaxAgg );
+      p->selFlags |= SF_Aggregate | (sNC.ncFlags&NC_MinMaxAgg);
     }else{
       sNC.ncFlags &= ~NC_AllowAgg;
     }
@@ -78019,12 +82579,30 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
     sNC.pNext = 0;
     sNC.ncFlags |= NC_AllowAgg;
 
+    /* If this is a converted compound query, move the ORDER BY clause from 
+    ** the sub-query back to the parent query. At this point each term
+    ** within the ORDER BY clause has been transformed to an integer value.
+    ** These integers will be replaced by copies of the corresponding result
+    ** set expressions by the call to resolveOrderGroupBy() below.  */
+    if( p->selFlags & SF_Converted ){
+      Select *pSub = p->pSrc->a[0].pSelect;
+      p->pOrderBy = pSub->pOrderBy;
+      pSub->pOrderBy = 0;
+    }
+
     /* Process the ORDER BY clause for singleton SELECT statements.
     ** The ORDER BY clause for compounds SELECT statements is handled
     ** below, after all of the result-sets for all of the elements of
     ** the compound have been resolved.
+    **
+    ** If there is an ORDER BY clause on a term of a compound-select other
+    ** than the right-most term, then that is a syntax error.  But the error
+    ** is not detected until much later, and so we need to go ahead and
+    ** resolve those symbols on the incorrect ORDER BY for consistency.
     */
-    if( !isCompound && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER") ){
+    if( isCompound<=nCompound  /* Defer right-most ORDER BY of a compound */
+     && resolveOrderGroupBy(&sNC, p, p->pOrderBy, "ORDER")
+    ){
       return WRC_Abort;
     }
     if( db->mallocFailed ){
@@ -78117,7 +82695,7 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames(
   NameContext *pNC,       /* Namespace to resolve expressions in. */
   Expr *pExpr             /* The expression to be analyzed. */
 ){
-  u8 savedHasAgg;
+  u16 savedHasAgg;
   Walker w;
 
   if( pExpr==0 ) return 0;
@@ -78130,8 +82708,8 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames(
     pParse->nHeight += pExpr->nHeight;
   }
 #endif
-  savedHasAgg = pNC->ncFlags & NC_HasAgg;
-  pNC->ncFlags &= ~NC_HasAgg;
+  savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg);
+  pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg);
   memset(&w, 0, sizeof(w));
   w.xExprCallback = resolveExprStep;
   w.xSelectCallback = resolveSelectStep;
@@ -78146,9 +82724,8 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames(
   }
   if( pNC->ncFlags & NC_HasAgg ){
     ExprSetProperty(pExpr, EP_Agg);
-  }else if( savedHasAgg ){
-    pNC->ncFlags |= NC_HasAgg;
   }
+  pNC->ncFlags |= savedHasAgg;
   return ExprHasProperty(pExpr, EP_Error);
 }
 
@@ -78248,7 +82825,7 @@ SQLITE_PRIVATE void sqlite3ResolveSelfReference(
 ** affinity of that column is returned. Otherwise, 0x00 is returned,
 ** indicating no affinity for the expression.
 **
-** i.e. the WHERE clause expresssions in the following statements all
+** i.e. the WHERE clause expressions in the following statements all
 ** have an affinity:
 **
 ** CREATE TABLE t1(a);
@@ -78295,10 +82872,11 @@ SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
 SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(
   Parse *pParse,           /* Parsing context */
   Expr *pExpr,             /* Add the "COLLATE" clause to this expression */
-  const Token *pCollName   /* Name of collating sequence */
+  const Token *pCollName,  /* Name of collating sequence */
+  int dequote              /* True to dequote pCollName */
 ){
   if( pCollName->n>0 ){
-    Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, 1);
+    Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote);
     if( pNew ){
       pNew->pLeft = pExpr;
       pNew->flags |= EP_Collate|EP_Skip;
@@ -78312,7 +82890,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, con
   assert( zC!=0 );
   s.z = zC;
   s.n = sqlite3Strlen30(s.z);
-  return sqlite3ExprAddCollateToken(pParse, pExpr, &s);
+  return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0);
 }
 
 /*
@@ -78358,9 +82936,9 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
       pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
       break;
     }
-    if( p->pTab!=0
-     && (op==TK_AGG_COLUMN || op==TK_COLUMN
+    if( (op==TK_AGG_COLUMN || op==TK_COLUMN
           || op==TK_REGISTER || op==TK_TRIGGER)
+     && p->pTab!=0
     ){
       /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally
       ** a TK_COLUMN but was previously evaluated and cached in a register */
@@ -78372,10 +82950,25 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
       break;
     }
     if( p->flags & EP_Collate ){
-      if( ALWAYS(p->pLeft) && (p->pLeft->flags & EP_Collate)!=0 ){
+      if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){
         p = p->pLeft;
       }else{
-        p = p->pRight;
+        Expr *pNext  = p->pRight;
+        /* The Expr.x union is never used at the same time as Expr.pRight */
+        assert( p->x.pList==0 || p->pRight==0 );
+        /* p->flags holds EP_Collate and p->pLeft->flags does not.  And
+        ** p->x.pSelect cannot.  So if p->x.pLeft exists, it must hold at
+        ** least one EP_Collate. Thus the following two ALWAYS. */
+        if( p->x.pList!=0 && ALWAYS(!ExprHasProperty(p, EP_xIsSelect)) ){
+          int i;
+          for(i=0; ALWAYS(i<p->x.pList->nExpr); i++){
+            if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){
+              pNext = p->x.pList->a[i].pExpr;
+              break;
+            }
+          }
+        }
+        p = pNext;
       }
     }else{
       break;
@@ -78581,6 +83174,9 @@ static void heightOfSelect(Select *p, int *pnHeight){
 ** Expr.pSelect member has a height of 1. Any other expression
 ** has a height equal to the maximum height of any other 
 ** referenced Expr plus one.
+**
+** Also propagate EP_Propagate flags up from Expr.x.pList to Expr.flags,
+** if appropriate.
 */
 static void exprSetHeight(Expr *p){
   int nHeight = 0;
@@ -78588,8 +83184,9 @@ static void exprSetHeight(Expr *p){
   heightOfExpr(p->pRight, &nHeight);
   if( ExprHasProperty(p, EP_xIsSelect) ){
     heightOfSelect(p->x.pSelect, &nHeight);
-  }else{
+  }else if( p->x.pList ){
     heightOfExprList(p->x.pList, &nHeight);
+    p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
   }
   p->nHeight = nHeight + 1;
 }
@@ -78598,8 +83195,12 @@ static void exprSetHeight(Expr *p){
 ** Set the Expr.nHeight variable using the exprSetHeight() function. If
 ** the height is greater than the maximum allowed expression depth,
 ** leave an error in pParse.
+**
+** Also propagate all EP_Propagate flags from the Expr.x.pList into
+** Expr.flags. 
 */
-SQLITE_PRIVATE void sqlite3ExprSetHeight(Parse *pParse, Expr *p){
+SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
+  if( pParse->nErr ) return;
   exprSetHeight(p);
   sqlite3ExprCheckHeight(pParse, p->nHeight);
 }
@@ -78613,8 +83214,17 @@ SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *p){
   heightOfSelect(p, &nHeight);
   return nHeight;
 }
-#else
-  #define exprSetHeight(y)
+#else /* ABOVE:  Height enforcement enabled.  BELOW: Height enforcement off */
+/*
+** Propagate all EP_Propagate flags from the Expr.x.pList into
+** Expr.flags. 
+*/
+SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
+  if( p && p->x.pList && !ExprHasProperty(p, EP_xIsSelect) ){
+    p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
+  }
+}
+#define exprSetHeight(y)
 #endif /* SQLITE_MAX_EXPR_DEPTH>0 */
 
 /*
@@ -78716,18 +83326,18 @@ SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(
   }else{
     if( pRight ){
       pRoot->pRight = pRight;
-      pRoot->flags |= EP_Collate & pRight->flags;
+      pRoot->flags |= EP_Propagate & pRight->flags;
     }
     if( pLeft ){
       pRoot->pLeft = pLeft;
-      pRoot->flags |= EP_Collate & pLeft->flags;
+      pRoot->flags |= EP_Propagate & pLeft->flags;
     }
     exprSetHeight(pRoot);
   }
 }
 
 /*
-** Allocate a Expr node which joins as many as two subtrees.
+** Allocate an Expr node which joins as many as two subtrees.
 **
 ** One or both of the subtrees can be NULL.  Return a pointer to the new
 ** Expr node.  Or, if an OOM error occurs, set pParse->db->mallocFailed,
@@ -78741,7 +83351,7 @@ SQLITE_PRIVATE Expr *sqlite3PExpr(
   const Token *pToken     /* Argument token */
 ){
   Expr *p;
-  if( op==TK_AND && pLeft && pRight ){
+  if( op==TK_AND && pLeft && pRight && pParse->nErr==0 ){
     /* Take advantage of short-circuit false optimization for AND */
     p = sqlite3ExprAnd(pParse->db, pLeft, pRight);
   }else{
@@ -78820,7 +83430,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *
   }
   pNew->x.pList = pList;
   assert( !ExprHasProperty(pNew, EP_xIsSelect) );
-  sqlite3ExprSetHeight(pParse, pNew);
+  sqlite3ExprSetHeightAndFlags(pParse, pNew);
   return pNew;
 }
 
@@ -78837,7 +83447,7 @@ SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse *pParse, ExprList *pList, Token *
 **
 ** Wildcards of the form ":aaa", "@aaa", or "$aaa" are assigned the same number
 ** as the previous instance of the same wildcard.  Or if this is the first
-** instance of the wildcard, the next sequenial variable number is
+** instance of the wildcard, the next sequential variable number is
 ** assigned.
 */
 SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr){
@@ -78972,7 +83582,7 @@ static int exprStructSize(Expr *p){
 ** During expression analysis, extra information is computed and moved into
 ** later parts of teh Expr object and that extra information might get chopped
 ** off if the expression is reduced.  Note also that it does not work to
-** make a EXPRDUP_REDUCE copy of a reduced expression.  It is only legal
+** make an EXPRDUP_REDUCE copy of a reduced expression.  It is only legal
 ** to reduce a pristine expression tree from the parser.  The implementation
 ** of dupedExprStructSize() contain multiple assert() statements that attempt
 ** to enforce this constraint.
@@ -79041,7 +83651,7 @@ static int dupedExprSize(Expr *p, int flags){
 ** is not NULL then *pzBuffer is assumed to point to a buffer large enough 
 ** to store the copy of expression p, the copies of p->u.zToken
 ** (if applicable), and the copies of the p->pLeft and p->pRight expressions,
-** if any. Before returning, *pzBuffer is set to the first byte passed the
+** if any. Before returning, *pzBuffer is set to the first byte past the
 ** portion of the buffer copied into by this function.
 */
 static Expr *exprDup(sqlite3 *db, Expr *p, int flags, u8 **pzBuffer){
@@ -79295,6 +83905,7 @@ SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
   pNew->addrOpenEphm[1] = -1;
   pNew->nSelectRow = p->nSelectRow;
   pNew->pWith = withDup(db, p->pWith);
+  sqlite3SelectSetName(pNew, p->zSelName);
   return pNew;
 }
 #else
@@ -79435,37 +84046,67 @@ SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){
 }
 
 /*
-** These routines are Walker callbacks.  Walker.u.pi is a pointer
-** to an integer.  These routines are checking an expression to see
-** if it is a constant.  Set *Walker.u.pi to 0 if the expression is
-** not constant.
+** Return the bitwise-OR of all Expr.flags fields in the given
+** ExprList.
+*/
+SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList *pList){
+  int i;
+  u32 m = 0;
+  if( pList ){
+    for(i=0; i<pList->nExpr; i++){
+       Expr *pExpr = pList->a[i].pExpr;
+       if( ALWAYS(pExpr) ) m |= pExpr->flags;
+    }
+  }
+  return m;
+}
+
+/*
+** These routines are Walker callbacks used to check expressions to
+** see if they are "constant" for some definition of constant.  The
+** Walker.eCode value determines the type of "constant" we are looking
+** for.
 **
 ** These callback routines are used to implement the following:
 **
-**     sqlite3ExprIsConstant()
-**     sqlite3ExprIsConstantNotJoin()
-**     sqlite3ExprIsConstantOrFunction()
+**     sqlite3ExprIsConstant()                  pWalker->eCode==1
+**     sqlite3ExprIsConstantNotJoin()           pWalker->eCode==2
+**     sqlite3ExprRefOneTableOnly()             pWalker->eCode==3
+**     sqlite3ExprIsConstantOrFunction()        pWalker->eCode==4 or 5
 **
+** In all cases, the callbacks set Walker.eCode=0 and abort if the expression
+** is found to not be a constant.
+**
+** The sqlite3ExprIsConstantOrFunction() is used for evaluating expressions
+** in a CREATE TABLE statement.  The Walker.eCode value is 5 when parsing
+** an existing schema and 4 when processing a new statement.  A bound
+** parameter raises an error for new statements, but is silently converted
+** to NULL for existing schemas.  This allows sqlite_master tables that 
+** contain a bound parameter because they were generated by older versions
+** of SQLite to be parsed by newer versions of SQLite without raising a
+** malformed schema error.
 */
 static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
 
-  /* If pWalker->u.i is 3 then any term of the expression that comes from
-  ** the ON or USING clauses of a join disqualifies the expression
+  /* If pWalker->eCode is 2 then any term of the expression that comes from
+  ** the ON or USING clauses of a left join disqualifies the expression
   ** from being considered constant. */
-  if( pWalker->u.i==3 && ExprHasProperty(pExpr, EP_FromJoin) ){
-    pWalker->u.i = 0;
+  if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_FromJoin) ){
+    pWalker->eCode = 0;
     return WRC_Abort;
   }
 
   switch( pExpr->op ){
     /* Consider functions to be constant if all their arguments are constant
-    ** and either pWalker->u.i==2 or the function as the SQLITE_FUNC_CONST
-    ** flag. */
+    ** and either pWalker->eCode==4 or 5 or the function has the
+    ** SQLITE_FUNC_CONST flag. */
     case TK_FUNCTION:
-      if( pWalker->u.i==2 || ExprHasProperty(pExpr,EP_Constant) ){
+      if( pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc) ){
         return WRC_Continue;
+      }else{
+        pWalker->eCode = 0;
+        return WRC_Abort;
       }
-      /* Fall through */
     case TK_ID:
     case TK_COLUMN:
     case TK_AGG_FUNCTION:
@@ -79474,8 +84115,25 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
       testcase( pExpr->op==TK_COLUMN );
       testcase( pExpr->op==TK_AGG_FUNCTION );
       testcase( pExpr->op==TK_AGG_COLUMN );
-      pWalker->u.i = 0;
-      return WRC_Abort;
+      if( pWalker->eCode==3 && pExpr->iTable==pWalker->u.iCur ){
+        return WRC_Continue;
+      }else{
+        pWalker->eCode = 0;
+        return WRC_Abort;
+      }
+    case TK_VARIABLE:
+      if( pWalker->eCode==5 ){
+        /* Silently convert bound parameters that appear inside of CREATE
+        ** statements into a NULL when parsing the CREATE statement text out
+        ** of the sqlite_master table */
+        pExpr->op = TK_NULL;
+      }else if( pWalker->eCode==4 ){
+        /* A bound parameter in a CREATE statement that originates from
+        ** sqlite3_prepare() causes an error */
+        pWalker->eCode = 0;
+        return WRC_Abort;
+      }
+      /* Fall through */
     default:
       testcase( pExpr->op==TK_SELECT ); /* selectNodeIsConstant will disallow */
       testcase( pExpr->op==TK_EXISTS ); /* selectNodeIsConstant will disallow */
@@ -79484,21 +84142,22 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
 }
 static int selectNodeIsConstant(Walker *pWalker, Select *NotUsed){
   UNUSED_PARAMETER(NotUsed);
-  pWalker->u.i = 0;
+  pWalker->eCode = 0;
   return WRC_Abort;
 }
-static int exprIsConst(Expr *p, int initFlag){
+static int exprIsConst(Expr *p, int initFlag, int iCur){
   Walker w;
   memset(&w, 0, sizeof(w));
-  w.u.i = initFlag;
+  w.eCode = initFlag;
   w.xExprCallback = exprNodeIsConstant;
   w.xSelectCallback = selectNodeIsConstant;
+  w.u.iCur = iCur;
   sqlite3WalkExpr(&w, p);
-  return w.u.i;
+  return w.eCode;
 }
 
 /*
-** Walk an expression tree.  Return 1 if the expression is constant
+** Walk an expression tree.  Return non-zero if the expression is constant
 ** and 0 if it involves variables or function calls.
 **
 ** For the purposes of this function, a double-quoted string (ex: "abc")
@@ -79506,21 +84165,31 @@ static int exprIsConst(Expr *p, int initFlag){
 ** a constant.
 */
 SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr *p){
-  return exprIsConst(p, 1);
+  return exprIsConst(p, 1, 0);
 }
 
 /*
-** Walk an expression tree.  Return 1 if the expression is constant
+** Walk an expression tree.  Return non-zero if the expression is constant
 ** that does no originate from the ON or USING clauses of a join.
 ** Return 0 if it involves variables or function calls or terms from
 ** an ON or USING clause.
 */
 SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){
-  return exprIsConst(p, 3);
+  return exprIsConst(p, 2, 0);
+}
+
+/*
+** Walk an expression tree.  Return non-zero if the expression constant
+** for any single row of the table with cursor iCur.  In other words, the
+** expression must not refer to any non-deterministic function nor any
+** table other than iCur.
+*/
+SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){
+  return exprIsConst(p, 3, iCur);
 }
 
 /*
-** Walk an expression tree.  Return 1 if the expression is constant
+** Walk an expression tree.  Return non-zero if the expression is constant
 ** or a function call with constant arguments.  Return and 0 if there
 ** are any variables.
 **
@@ -79528,8 +84197,9 @@ SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){
 ** is considered a variable but a single-quoted string (ex: 'abc') is
 ** a constant.
 */
-SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p){
-  return exprIsConst(p, 2);
+SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){
+  assert( isInit==0 || isInit==1 );
+  return exprIsConst(p, 4+isInit, 0);
 }
 
 /*
@@ -79596,7 +84266,8 @@ SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){
       return 0;
     case TK_COLUMN:
       assert( p->pTab!=0 );
-      return p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0;
+      return ExprHasProperty(p, EP_CanBeNull) ||
+             (p->iColumn>=0 && p->pTab->aCol[p->iColumn].notNull==0);
     default:
       return 1;
   }
@@ -79767,7 +84438,7 @@ static int sqlite3InRhsIsConstant(Expr *pIn){
 **
 ** If the RHS of the IN operator is a list or a more complex subquery, then
 ** an ephemeral table might need to be generated from the RHS and then
-** pX->iTable made to point to the ephermeral table instead of an
+** pX->iTable made to point to the ephemeral table instead of an
 ** existing table.
 **
 ** The inFlags parameter must contain exactly one of the bits
@@ -79824,7 +84495,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int
   ** ephemeral table.
   */
   p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
-  if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){
+  if( pParse->nErr==0 && isCandidateForInOpt(p) ){
     sqlite3 *db = pParse->db;              /* Database connection */
     Table *pTab;                           /* Table <table>. */
     Expr *pExpr;                           /* Expression <column> */
@@ -79897,7 +84568,7 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, u32 inFlags, int
   ** and IN_INDEX_NOOP is an allowed reply
   ** and the RHS of the IN operator is a list, not a subquery
   ** and the RHS is not contant or has two or fewer terms,
-  ** then it is not worth creating an ephermeral table to evaluate
+  ** then it is not worth creating an ephemeral table to evaluate
   ** the IN operator so return IN_INDEX_NOOP.
   */
   if( eType==0
@@ -80039,7 +84710,6 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
         assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
         pSelect->iLimit = 0;
         testcase( pSelect->selFlags & SF_Distinct );
-        pSelect->selFlags &= ~SF_Distinct;
         testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
         if( sqlite3Select(pParse, pSelect, &dest) ){
           sqlite3KeyInfoUnref(pKeyInfo);
@@ -80138,6 +84808,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
       sqlite3SelectDestInit(&dest, 0, ++pParse->nMem);
       if( pExpr->op==TK_SELECT ){
         dest.eDest = SRT_Mem;
+        dest.iSdst = dest.iSDParm;
         sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iSDParm);
         VdbeComment((v, "Init subquery result"));
       }else{
@@ -80149,6 +84820,7 @@ SQLITE_PRIVATE int sqlite3CodeSubselect(
       pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0,
                                   &sqlite3IntTokens[1]);
       pSel->iLimit = 0;
+      pSel->selFlags &= ~SF_MultiValue;
       if( sqlite3Select(pParse, pSel, &dest) ){
         return 0;
       }
@@ -80437,7 +85109,8 @@ SQLITE_PRIVATE void sqlite3ExprCacheStore(Parse *pParse, int iTab, int iCol, int
   int idxLru;
   struct yColCache *p;
 
-  assert( iReg>0 );  /* Register numbers are always positive */
+  /* Unless an error has occurred, register numbers are always positive. */
+  assert( iReg>0 || pParse->nErr || pParse->db->mallocFailed );
   assert( iCol>=-1 && iCol<32768 );  /* Finite column numbers */
 
   /* The SQLITE_ColumnCache flag disables the column cache.  This is used
@@ -80657,16 +85330,9 @@ SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse *pParse, int iStart, in
 ** over to iTo..iTo+nReg-1. Keep the column cache up-to-date.
 */
 SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
-  int i;
-  struct yColCache *p;
   assert( iFrom>=iTo+nReg || iFrom+nReg<=iTo );
   sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg);
-  for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
-    int x = p->iReg;
-    if( x>=iFrom && x<iFrom+nReg ){
-      p->iReg += iTo-iFrom;
-    }
-  }
+  sqlite3ExprCacheRemove(pParse, iFrom, nReg);
 }
 
 #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
@@ -80821,26 +85487,13 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
 #ifndef SQLITE_OMIT_CAST
     case TK_CAST: {
       /* Expressions of the form:   CAST(pLeft AS token) */
-      int aff, to_op;
       inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
-      assert( !ExprHasProperty(pExpr, EP_IntValue) );
-      aff = sqlite3AffinityType(pExpr->u.zToken, 0);
-      to_op = aff - SQLITE_AFF_TEXT + OP_ToText;
-      assert( to_op==OP_ToText    || aff!=SQLITE_AFF_TEXT    );
-      assert( to_op==OP_ToBlob    || aff!=SQLITE_AFF_NONE    );
-      assert( to_op==OP_ToNumeric || aff!=SQLITE_AFF_NUMERIC );
-      assert( to_op==OP_ToInt     || aff!=SQLITE_AFF_INTEGER );
-      assert( to_op==OP_ToReal    || aff!=SQLITE_AFF_REAL    );
-      testcase( to_op==OP_ToText );
-      testcase( to_op==OP_ToBlob );
-      testcase( to_op==OP_ToNumeric );
-      testcase( to_op==OP_ToInt );
-      testcase( to_op==OP_ToReal );
       if( inReg!=target ){
         sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target);
         inReg = target;
       }
-      sqlite3VdbeAddOp1(v, to_op, inReg);
+      sqlite3VdbeAddOp2(v, OP_Cast, target,
+                        sqlite3AffinityType(pExpr->u.zToken, 0));
       testcase( usedAsColumnCache(pParse, inReg, inReg) );
       sqlite3ExprCacheAffinityChange(pParse, inReg, 1);
       break;
@@ -80996,7 +85649,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
       }
 
       /* Attempt a direct implementation of the built-in COALESCE() and
-      ** IFNULL() functions.  This avoids unnecessary evalation of
+      ** IFNULL() functions.  This avoids unnecessary evaluation of
       ** arguments past the first non-NULL argument.
       */
       if( pDef->funcFlags & SQLITE_FUNC_COALESCE ){
@@ -81205,7 +85858,10 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target)
 
 #ifndef SQLITE_OMIT_FLOATING_POINT
       /* If the column has REAL affinity, it may currently be stored as an
-      ** integer. Use OP_RealAffinity to make sure it is really real.  */
+      ** integer. Use OP_RealAffinity to make sure it is really real.
+      **
+      ** EVIDENCE-OF: R-60985-57662 SQLite will convert the value back to
+      ** floating point when extracting it from the record.  */
       if( pExpr->iColumn>=0 
        && pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL
       ){
@@ -81435,7 +86091,7 @@ SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int ta
 }
 
 /*
-** Generate code that evalutes the given expression and puts the result
+** Generate code that evaluates the given expression and puts the result
 ** in register target.
 **
 ** Also make a copy of the expression results into another "cache" register
@@ -81458,90 +86114,86 @@ SQLITE_PRIVATE void sqlite3ExprCodeAndCache(Parse *pParse, Expr *pExpr, int targ
   exprToRegister(pExpr, iMem);
 }
 
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
+#ifdef SQLITE_DEBUG
 /*
 ** Generate a human-readable explanation of an expression tree.
 */
-SQLITE_PRIVATE void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){
-  int op;                   /* The opcode being coded */
+SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
   const char *zBinOp = 0;   /* Binary operator */
   const char *zUniOp = 0;   /* Unary operator */
+  pView = sqlite3TreeViewPush(pView, moreToFollow);
   if( pExpr==0 ){
-    op = TK_NULL;
-  }else{
-    op = pExpr->op;
+    sqlite3TreeViewLine(pView, "nil");
+    sqlite3TreeViewPop(pView);
+    return;
   }
-  switch( op ){
+  switch( pExpr->op ){
     case TK_AGG_COLUMN: {
-      sqlite3ExplainPrintf(pOut, "AGG{%d:%d}",
+      sqlite3TreeViewLine(pView, "AGG{%d:%d}",
             pExpr->iTable, pExpr->iColumn);
       break;
     }
     case TK_COLUMN: {
       if( pExpr->iTable<0 ){
         /* This only happens when coding check constraints */
-        sqlite3ExplainPrintf(pOut, "COLUMN(%d)", pExpr->iColumn);
+        sqlite3TreeViewLine(pView, "COLUMN(%d)", pExpr->iColumn);
       }else{
-        sqlite3ExplainPrintf(pOut, "{%d:%d}",
+        sqlite3TreeViewLine(pView, "{%d:%d}",
                              pExpr->iTable, pExpr->iColumn);
       }
       break;
     }
     case TK_INTEGER: {
       if( pExpr->flags & EP_IntValue ){
-        sqlite3ExplainPrintf(pOut, "%d", pExpr->u.iValue);
+        sqlite3TreeViewLine(pView, "%d", pExpr->u.iValue);
       }else{
-        sqlite3ExplainPrintf(pOut, "%s", pExpr->u.zToken);
+        sqlite3TreeViewLine(pView, "%s", pExpr->u.zToken);
       }
       break;
     }
 #ifndef SQLITE_OMIT_FLOATING_POINT
     case TK_FLOAT: {
-      sqlite3ExplainPrintf(pOut,"%s", pExpr->u.zToken);
+      sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
       break;
     }
 #endif
     case TK_STRING: {
-      sqlite3ExplainPrintf(pOut,"%Q", pExpr->u.zToken);
+      sqlite3TreeViewLine(pView,"%Q", pExpr->u.zToken);
       break;
     }
     case TK_NULL: {
-      sqlite3ExplainPrintf(pOut,"NULL");
+      sqlite3TreeViewLine(pView,"NULL");
       break;
     }
 #ifndef SQLITE_OMIT_BLOB_LITERAL
     case TK_BLOB: {
-      sqlite3ExplainPrintf(pOut,"%s", pExpr->u.zToken);
+      sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
       break;
     }
 #endif
     case TK_VARIABLE: {
-      sqlite3ExplainPrintf(pOut,"VARIABLE(%s,%d)",
-                           pExpr->u.zToken, pExpr->iColumn);
+      sqlite3TreeViewLine(pView,"VARIABLE(%s,%d)",
+                          pExpr->u.zToken, pExpr->iColumn);
       break;
     }
     case TK_REGISTER: {
-      sqlite3ExplainPrintf(pOut,"REGISTER(%d)", pExpr->iTable);
+      sqlite3TreeViewLine(pView,"REGISTER(%d)", pExpr->iTable);
       break;
     }
     case TK_AS: {
-      sqlite3ExplainExpr(pOut, pExpr->pLeft);
+      sqlite3TreeViewLine(pView,"AS %Q", pExpr->u.zToken);
+      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
+      break;
+    }
+    case TK_ID: {
+      sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken);
       break;
     }
 #ifndef SQLITE_OMIT_CAST
     case TK_CAST: {
       /* Expressions of the form:   CAST(pLeft AS token) */
-      const char *zAff = "unk";
-      switch( sqlite3AffinityType(pExpr->u.zToken, 0) ){
-        case SQLITE_AFF_TEXT:    zAff = "TEXT";     break;
-        case SQLITE_AFF_NONE:    zAff = "NONE";     break;
-        case SQLITE_AFF_NUMERIC: zAff = "NUMERIC";  break;
-        case SQLITE_AFF_INTEGER: zAff = "INTEGER";  break;
-        case SQLITE_AFF_REAL:    zAff = "REAL";     break;
-      }
-      sqlite3ExplainPrintf(pOut, "CAST-%s(", zAff);
-      sqlite3ExplainExpr(pOut, pExpr->pLeft);
-      sqlite3ExplainPrintf(pOut, ")");
+      sqlite3TreeViewLine(pView,"CAST %Q", pExpr->u.zToken);
+      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
       break;
     }
 #endif /* SQLITE_OMIT_CAST */
@@ -81565,6 +86217,7 @@ SQLITE_PRIVATE void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){
     case TK_LSHIFT:  zBinOp = "LSHIFT"; break;
     case TK_RSHIFT:  zBinOp = "RSHIFT"; break;
     case TK_CONCAT:  zBinOp = "CONCAT"; break;
+    case TK_DOT:     zBinOp = "DOT";    break;
 
     case TK_UMINUS:  zUniOp = "UMINUS"; break;
     case TK_UPLUS:   zUniOp = "UPLUS";  break;
@@ -81574,8 +86227,8 @@ SQLITE_PRIVATE void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){
     case TK_NOTNULL: zUniOp = "NOTNULL"; break;
 
     case TK_COLLATE: {
-      sqlite3ExplainExpr(pOut, pExpr->pLeft);
-      sqlite3ExplainPrintf(pOut,".COLLATE(%s)",pExpr->u.zToken);
+      sqlite3TreeViewLine(pView, "COLLATE %Q", pExpr->u.zToken);
+      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
       break;
     }
 
@@ -81587,41 +86240,36 @@ SQLITE_PRIVATE void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){
       }else{
         pFarg = pExpr->x.pList;
       }
-      if( op==TK_AGG_FUNCTION ){
-        sqlite3ExplainPrintf(pOut, "AGG_FUNCTION%d:%s(",
+      if( pExpr->op==TK_AGG_FUNCTION ){
+        sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q",
                              pExpr->op2, pExpr->u.zToken);
       }else{
-        sqlite3ExplainPrintf(pOut, "FUNCTION:%s(", pExpr->u.zToken);
+        sqlite3TreeViewLine(pView, "FUNCTION %Q", pExpr->u.zToken);
       }
       if( pFarg ){
-        sqlite3ExplainExprList(pOut, pFarg);
+        sqlite3TreeViewExprList(pView, pFarg, 0, 0);
       }
-      sqlite3ExplainPrintf(pOut, ")");
       break;
     }
 #ifndef SQLITE_OMIT_SUBQUERY
     case TK_EXISTS: {
-      sqlite3ExplainPrintf(pOut, "EXISTS(");
-      sqlite3ExplainSelect(pOut, pExpr->x.pSelect);
-      sqlite3ExplainPrintf(pOut,")");
+      sqlite3TreeViewLine(pView, "EXISTS-expr");
+      sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
       break;
     }
     case TK_SELECT: {
-      sqlite3ExplainPrintf(pOut, "(");
-      sqlite3ExplainSelect(pOut, pExpr->x.pSelect);
-      sqlite3ExplainPrintf(pOut, ")");
+      sqlite3TreeViewLine(pView, "SELECT-expr");
+      sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
       break;
     }
     case TK_IN: {
-      sqlite3ExplainPrintf(pOut, "IN(");
-      sqlite3ExplainExpr(pOut, pExpr->pLeft);
-      sqlite3ExplainPrintf(pOut, ",");
+      sqlite3TreeViewLine(pView, "IN");
+      sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
       if( ExprHasProperty(pExpr, EP_xIsSelect) ){
-        sqlite3ExplainSelect(pOut, pExpr->x.pSelect);
+        sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
       }else{
-        sqlite3ExplainExprList(pOut, pExpr->x.pList);
+        sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
       }
-      sqlite3ExplainPrintf(pOut, ")");
       break;
     }
 #endif /* SQLITE_OMIT_SUBQUERY */
@@ -81641,13 +86289,10 @@ SQLITE_PRIVATE void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){
       Expr *pX = pExpr->pLeft;
       Expr *pY = pExpr->x.pList->a[0].pExpr;
       Expr *pZ = pExpr->x.pList->a[1].pExpr;
-      sqlite3ExplainPrintf(pOut, "BETWEEN(");
-      sqlite3ExplainExpr(pOut, pX);
-      sqlite3ExplainPrintf(pOut, ",");
-      sqlite3ExplainExpr(pOut, pY);
-      sqlite3ExplainPrintf(pOut, ",");
-      sqlite3ExplainExpr(pOut, pZ);
-      sqlite3ExplainPrintf(pOut, ")");
+      sqlite3TreeViewLine(pView, "BETWEEN");
+      sqlite3TreeViewExpr(pView, pX, 1);
+      sqlite3TreeViewExpr(pView, pY, 1);
+      sqlite3TreeViewExpr(pView, pZ, 0);
       break;
     }
     case TK_TRIGGER: {
@@ -81658,15 +86303,14 @@ SQLITE_PRIVATE void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){
       ** is set to the column of the pseudo-table to read, or to -1 to
       ** read the rowid field.
       */
-      sqlite3ExplainPrintf(pOut, "%s(%d)", 
+      sqlite3TreeViewLine(pView, "%s(%d)", 
           pExpr->iTable ? "NEW" : "OLD", pExpr->iColumn);
       break;
     }
     case TK_CASE: {
-      sqlite3ExplainPrintf(pOut, "CASE(");
-      sqlite3ExplainExpr(pOut, pExpr->pLeft);
-      sqlite3ExplainPrintf(pOut, ",");
-      sqlite3ExplainExprList(pOut, pExpr->x.pList);
+      sqlite3TreeViewLine(pView, "CASE");
+      sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
+      sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
       break;
     }
 #ifndef SQLITE_OMIT_TRIGGER
@@ -81678,55 +86322,57 @@ SQLITE_PRIVATE void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){
         case OE_Fail:       zType = "fail";      break;
         case OE_Ignore:     zType = "ignore";    break;
       }
-      sqlite3ExplainPrintf(pOut, "RAISE-%s(%s)", zType, pExpr->u.zToken);
+      sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken);
       break;
     }
 #endif
+    default: {
+      sqlite3TreeViewLine(pView, "op=%d", pExpr->op);
+      break;
+    }
   }
   if( zBinOp ){
-    sqlite3ExplainPrintf(pOut,"%s(", zBinOp);
-    sqlite3ExplainExpr(pOut, pExpr->pLeft);
-    sqlite3ExplainPrintf(pOut,",");
-    sqlite3ExplainExpr(pOut, pExpr->pRight);
-    sqlite3ExplainPrintf(pOut,")");
+    sqlite3TreeViewLine(pView, "%s", zBinOp);
+    sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
+    sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
   }else if( zUniOp ){
-    sqlite3ExplainPrintf(pOut,"%s(", zUniOp);
-    sqlite3ExplainExpr(pOut, pExpr->pLeft);
-    sqlite3ExplainPrintf(pOut,")");
+    sqlite3TreeViewLine(pView, "%s", zUniOp);
+    sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
   }
+  sqlite3TreeViewPop(pView);
 }
-#endif /* defined(SQLITE_ENABLE_TREE_EXPLAIN) */
+#endif /* SQLITE_DEBUG */
 
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
+#ifdef SQLITE_DEBUG
 /*
 ** Generate a human-readable explanation of an expression list.
 */
-SQLITE_PRIVATE void sqlite3ExplainExprList(Vdbe *pOut, ExprList *pList){
+SQLITE_PRIVATE void sqlite3TreeViewExprList(
+  TreeView *pView,
+  const ExprList *pList,
+  u8 moreToFollow,
+  const char *zLabel
+){
   int i;
-  if( pList==0 || pList->nExpr==0 ){
-    sqlite3ExplainPrintf(pOut, "(empty-list)");
-    return;
-  }else if( pList->nExpr==1 ){
-    sqlite3ExplainExpr(pOut, pList->a[0].pExpr);
+  pView = sqlite3TreeViewPush(pView, moreToFollow);
+  if( zLabel==0 || zLabel[0]==0 ) zLabel = "LIST";
+  if( pList==0 ){
+    sqlite3TreeViewLine(pView, "%s (empty)", zLabel);
   }else{
-    sqlite3ExplainPush(pOut);
+    sqlite3TreeViewLine(pView, "%s", zLabel);
     for(i=0; i<pList->nExpr; i++){
-      sqlite3ExplainPrintf(pOut, "item[%d] = ", i);
-      sqlite3ExplainPush(pOut);
-      sqlite3ExplainExpr(pOut, pList->a[i].pExpr);
-      sqlite3ExplainPop(pOut);
-      if( pList->a[i].zName ){
+      sqlite3TreeViewExpr(pView, pList->a[i].pExpr, i<pList->nExpr-1);
+#if 0
+     if( pList->a[i].zName ){
         sqlite3ExplainPrintf(pOut, " AS %s", pList->a[i].zName);
       }
       if( pList->a[i].bSpanIsTab ){
         sqlite3ExplainPrintf(pOut, " (%s)", pList->a[i].zSpan);
       }
-      if( i<pList->nExpr-1 ){
-        sqlite3ExplainNL(pOut);
-      }
+#endif
     }
-    sqlite3ExplainPop(pOut);
   }
+  sqlite3TreeViewPop(pView);
 }
 #endif /* SQLITE_DEBUG */
 
@@ -81790,7 +86436,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeExprList(
 **    x>=y AND x<=z
 **
 ** Code it as such, taking care to do the common subexpression
-** elementation of x.
+** elimination of x.
 */
 static void exprCodeBetween(
   Parse *pParse,    /* Parsing and code generating context */
@@ -82175,7 +86821,7 @@ SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
     if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2;
     if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2;
     if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
-    if( ALWAYS((combinedFlags & EP_Reduced)==0) ){
+    if( ALWAYS((combinedFlags & EP_Reduced)==0) && pA->op!=TK_STRING ){
       if( pA->iColumn!=pB->iColumn ) return 2;
       if( pA->iTable!=pB->iTable 
        && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
@@ -82277,10 +86923,11 @@ static int exprSrcCount(Walker *pWalker, Expr *pExpr){
     int i;
     struct SrcCount *p = pWalker->u.pSrcCount;
     SrcList *pSrc = p->pSrc;
-    for(i=0; i<pSrc->nSrc; i++){
+    int nSrc = pSrc ? pSrc->nSrc : 0;
+    for(i=0; i<nSrc; i++){
       if( pExpr->iTable==pSrc->a[i].iCursor ) break;
     }
-    if( i<pSrc->nSrc ){
+    if( i<nSrc ){
       p->nThis++;
     }else{
       p->nOther++;
@@ -82527,7 +87174,7 @@ SQLITE_PRIVATE int sqlite3GetTempReg(Parse *pParse){
 ** purpose.
 **
 ** If a register is currently being used by the column cache, then
-** the dallocation is deferred until the column cache line that uses
+** the deallocation is deferred until the column cache line that uses
 ** the register becomes stale.
 */
 SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
@@ -82706,6 +87353,7 @@ static void renameParentFunc(
         n = sqlite3GetToken(z, &token);
       }while( token==TK_SPACE );
 
+      if( token==TK_ILLEGAL ) break;
       zParent = sqlite3DbStrNDup(db, (const char *)z, n);
       if( zParent==0 ) break;
       sqlite3Dequote(zParent);
@@ -82754,8 +87402,8 @@ static void renameTriggerFunc(
   UNUSED_PARAMETER(NotUsed);
 
   /* The principle used to locate the table name in the CREATE TRIGGER 
-  ** statement is that the table name is the first token that is immediatedly
-  ** preceded by either TK_ON or TK_DOT and immediatedly followed by one
+  ** statement is that the table name is the first token that is immediately
+  ** preceded by either TK_ON or TK_DOT and immediately followed by one
   ** of TK_WHEN, TK_BEGIN or TK_FOR.
   */
   if( zSql ){
@@ -83270,7 +87918,10 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
   */
   if( pDflt ){
     sqlite3_value *pVal = 0;
-    if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){
+    int rc;
+    rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal);
+    assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
+    if( rc!=SQLITE_OK ){
       db->mallocFailed = 1;
       return;
     }
@@ -83446,7 +88097,7 @@ exit_begin_add_column:
 ** not possible to enable both STAT3 and STAT4 at the same time.  If they
 ** are both enabled, then STAT4 takes precedence.
 **
-** For most applications, sqlite_stat1 provides all the statisics required
+** For most applications, sqlite_stat1 provides all the statistics required
 ** for the query planner to make good choices.
 **
 ** Format of sqlite_stat1:
@@ -83797,8 +88448,9 @@ static void stat4Destructor(void *pOld){
 ** original WITHOUT ROWID table as N==K as a special case.
 **
 ** This routine allocates the Stat4Accum object in heap memory. The return 
-** value is a pointer to the the Stat4Accum object encoded as a blob (i.e. 
-** the size of the blob is sizeof(void*) bytes). 
+** value is a pointer to the Stat4Accum object.  The datatype of the
+** return value is BLOB, but it is really just a pointer to the Stat4Accum
+** object.
 */
 static void statInit(
   sqlite3_context *context,
@@ -83857,7 +88509,7 @@ static void statInit(
     p->mxSample = mxSample;
     p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1);
     p->current.anLt = &p->current.anEq[nColUp];
-    p->iPrn = nCol*0x689e962d ^ sqlite3_value_int(argv[2])*0xd0944565;
+    p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]);
   
     /* Set up the Stat4Accum.a[] and aBest[] arrays */
     p->a = (struct Stat4Sample*)&p->current.anLt[nColUp];
@@ -83876,8 +88528,11 @@ static void statInit(
   }
 #endif
 
-  /* Return a pointer to the allocated object to the caller */
-  sqlite3_result_blob(context, p, sizeof(p), stat4Destructor);
+  /* Return a pointer to the allocated object to the caller.  Note that
+  ** only the pointer (the 2nd parameter) matters.  The size of the object
+  ** (given by the 3rd parameter) is never used and can be any positive
+  ** value. */
+  sqlite3_result_blob(context, p, sizeof(*p), stat4Destructor);
 }
 static const FuncDef statInitFuncdef = {
   2+IsStat34,      /* nArg */
@@ -84203,7 +88858,7 @@ static const FuncDef statPushFuncdef = {
 ** Implementation of the stat_get(P,J) SQL function.  This routine is
 ** used to query statistical information that has been gathered into
 ** the Stat4Accum object by prior calls to stat_push().  The P parameter
-** is a BLOB which is decoded into a pointer to the Stat4Accum objects.
+** has type BLOB but it is really just a pointer to the Stat4Accum object.
 ** The content to returned is determined by the parameter J
 ** which is one of the STAT_GET_xxxx values defined above.
 **
@@ -84607,7 +89262,8 @@ static void analyzeOneTable(
 
     /* Add the entry to the stat1 table. */
     callStatGet(v, regStat4, STAT_GET_STAT1, regStat1);
-    sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "aaa", 0);
+    assert( "BBB"[0]==SQLITE_AFF_TEXT );
+    sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
     sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
     sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
     sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
@@ -84670,7 +89326,8 @@ static void analyzeOneTable(
     sqlite3VdbeAddOp2(v, OP_Count, iTabCur, regStat1);
     jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); VdbeCoverage(v);
     sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
-    sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "aaa", 0);
+    assert( "BBB"[0]==SQLITE_AFF_TEXT );
+    sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
     sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
     sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
     sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
@@ -84841,7 +89498,7 @@ static void decodeIntArray(
 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
   if( z==0 ) z = "";
 #else
-  if( NEVER(z==0) ) z = "";
+  assert( z!=0 );
 #endif
   for(i=0; *z && i<nOut; i++){
     v = 0;
@@ -84850,36 +89507,39 @@ static void decodeIntArray(
       z++;
     }
 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
-    if( aOut ){
-      aOut[i] = v;
-    }else
+    if( aOut ) aOut[i] = v;
+    if( aLog ) aLog[i] = sqlite3LogEst(v);
 #else
     assert( aOut==0 );
     UNUSED_PARAMETER(aOut);
+    assert( aLog!=0 );
+    aLog[i] = sqlite3LogEst(v);
 #endif
-    {
-      aLog[i] = sqlite3LogEst(v);
-    }
     if( *z==' ' ) z++;
   }
 #ifndef SQLITE_ENABLE_STAT3_OR_STAT4
-  assert( pIndex!=0 );
+  assert( pIndex!=0 ); {
 #else
-  if( pIndex )
+  if( pIndex ){
 #endif
-  while( z[0] ){
-    if( sqlite3_strglob("unordered*", z)==0 ){
-      pIndex->bUnordered = 1;
-    }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
-      pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3));
-    }
+    pIndex->bUnordered = 0;
+    pIndex->noSkipScan = 0;
+    while( z[0] ){
+      if( sqlite3_strglob("unordered*", z)==0 ){
+        pIndex->bUnordered = 1;
+      }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){
+        pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3));
+      }else if( sqlite3_strglob("noskipscan*", z)==0 ){
+        pIndex->noSkipScan = 1;
+      }
 #ifdef SQLITE_ENABLE_COSTMULT
-    else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){
-      pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9));
-    }
+      else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){
+        pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9));
+      }
 #endif
-    while( z[0]!=0 && z[0]!=' ' ) z++;
-    while( z[0]==' ' ) z++;
+      while( z[0]!=0 && z[0]!=' ' ) z++;
+      while( z[0]==' ' ) z++;
+    }
   }
 }
 
@@ -84920,8 +89580,20 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
   z = argv[2];
 
   if( pIndex ){
+    tRowcnt *aiRowEst = 0;
+    int nCol = pIndex->nKeyCol+1;
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+    /* Index.aiRowEst may already be set here if there are duplicate 
+    ** sqlite_stat1 entries for this index. In that case just clobber
+    ** the old data with the new instead of allocating a new array.  */
+    if( pIndex->aiRowEst==0 ){
+      pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol);
+      if( pIndex->aiRowEst==0 ) pInfo->db->mallocFailed = 1;
+    }
+    aiRowEst = pIndex->aiRowEst;
+#endif
     pIndex->bUnordered = 0;
-    decodeIntArray((char*)z, pIndex->nKeyCol+1, 0, pIndex->aiRowLogEst, pIndex);
+    decodeIntArray((char*)z, nCol, aiRowEst, pIndex->aiRowLogEst, pIndex);
     if( pIndex->pPartIdxWhere==0 ) pTable->nRowLogEst = pIndex->aiRowLogEst[0];
   }else{
     Index fakeIdx;
@@ -84980,25 +89652,39 @@ static void initAvgEq(Index *pIdx){
       pIdx->aAvgEq[nCol] = 1;
     }
     for(iCol=0; iCol<nCol; iCol++){
+      int nSample = pIdx->nSample;
       int i;                    /* Used to iterate through samples */
       tRowcnt sumEq = 0;        /* Sum of the nEq values */
-      tRowcnt nSum = 0;         /* Number of terms contributing to sumEq */
       tRowcnt avgEq = 0;
-      tRowcnt nDLt = pFinal->anDLt[iCol];
+      tRowcnt nRow;             /* Number of rows in index */
+      i64 nSum100 = 0;          /* Number of terms contributing to sumEq */
+      i64 nDist100;             /* Number of distinct values in index */
+
+      if( !pIdx->aiRowEst || iCol>=pIdx->nKeyCol || pIdx->aiRowEst[iCol+1]==0 ){
+        nRow = pFinal->anLt[iCol];
+        nDist100 = (i64)100 * pFinal->anDLt[iCol];
+        nSample--;
+      }else{
+        nRow = pIdx->aiRowEst[0];
+        nDist100 = ((i64)100 * pIdx->aiRowEst[0]) / pIdx->aiRowEst[iCol+1];
+      }
+      pIdx->nRowEst0 = nRow;
 
       /* Set nSum to the number of distinct (iCol+1) field prefixes that
-      ** occur in the stat4 table for this index before pFinal. Set
-      ** sumEq to the sum of the nEq values for column iCol for the same
-      ** set (adding the value only once where there exist dupicate 
-      ** prefixes).  */
-      for(i=0; i<(pIdx->nSample-1); i++){
-        if( aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] ){
+      ** occur in the stat4 table for this index. Set sumEq to the sum of 
+      ** the nEq values for column iCol for the same set (adding the value 
+      ** only once where there exist duplicate prefixes).  */
+      for(i=0; i<nSample; i++){
+        if( i==(pIdx->nSample-1)
+         || aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] 
+        ){
           sumEq += aSample[i].anEq[iCol];
-          nSum++;
+          nSum100 += 100;
         }
       }
-      if( nDLt>nSum ){
-        avgEq = (pFinal->anLt[iCol] - sumEq)/(nDLt - nSum);
+
+      if( nDist100>nSum100 ){
+        avgEq = ((i64)100 * (nRow - sumEq))/(nDist100 - nSum100);
       }
       if( avgEq==0 ) avgEq = 1;
       pIdx->aAvgEq[iCol] = avgEq;
@@ -85244,12 +89930,17 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
 
   /* Load the statistics from the sqlite_stat4 table. */
 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
-  if( rc==SQLITE_OK ){
+  if( rc==SQLITE_OK && OptimizationEnabled(db, SQLITE_Stat34) ){
     int lookasideEnabled = db->lookaside.bEnabled;
     db->lookaside.bEnabled = 0;
     rc = loadStat4(db, sInfo.zDatabase);
     db->lookaside.bEnabled = lookasideEnabled;
   }
+  for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
+    Index *pIdx = sqliteHashData(i);
+    sqlite3_free(pIdx->aiRowEst);
+    pIdx->aiRowEst = 0;
+  }
 #endif
 
   if( rc==SQLITE_NOMEM ){
@@ -85414,6 +90105,7 @@ static void attachFunc(
         "attached databases must use the same text encoding as main database");
       rc = SQLITE_ERROR;
     }
+    sqlite3BtreeEnter(aNew->pBt);
     pPager = sqlite3BtreePager(aNew->pBt);
     sqlite3PagerLockingMode(pPager, db->dfltLockMode);
     sqlite3BtreeSecureDelete(aNew->pBt,
@@ -85421,6 +90113,7 @@ static void attachFunc(
 #ifndef SQLITE_OMIT_PAGER_PRAGMAS
     sqlite3BtreeSetPagerFlags(aNew->pBt, 3 | (db->flags & PAGER_FLAGS_MASK));
 #endif
+    sqlite3BtreeLeave(aNew->pBt);
   }
   aNew->safety_level = 3;
   aNew->zName = sqlite3DbStrDup(db, zName);
@@ -85453,7 +90146,7 @@ static void attachFunc(
       case SQLITE_NULL:
         /* No key specified.  Use the key from the main database */
         sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
-        if( nKey>0 || sqlite3BtreeGetReserve(db->aDb[0].pBt)>0 ){
+        if( nKey>0 || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){
           rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey);
         }
         break;
@@ -85471,6 +90164,15 @@ static void attachFunc(
     rc = sqlite3Init(db, &zErrDyn);
     sqlite3BtreeLeaveAll(db);
   }
+#ifdef SQLITE_USER_AUTHENTICATION
+  if( rc==SQLITE_OK ){
+    u8 newAuth = 0;
+    rc = sqlite3UserAuthCheckLogin(db, zName, &newAuth);
+    if( newAuth<db->auth.authLevel ){
+      rc = SQLITE_AUTH_USER;
+    }
+  }
+#endif
   if( rc ){
     int iDb = db->nDb - 1;
     assert( iDb>=2 );
@@ -85551,7 +90253,7 @@ static void detachFunc(
   sqlite3BtreeClose(pDb->pBt);
   pDb->pBt = 0;
   pDb->pSchema = 0;
-  sqlite3ResetAllSchemasOfConnection(db);
+  sqlite3CollapseDatabaseArray(db);
   return;
 
 detach_error:
@@ -85585,7 +90287,6 @@ static void codeAttach(
       SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
       SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
   ){
-    pParse->nErr++;
     goto attach_end;
   }
 
@@ -85907,13 +90608,16 @@ SQLITE_PRIVATE int sqlite3FixTriggerStep(
 ** Setting the auth function to NULL disables this hook.  The default
 ** setting of the auth function is NULL.
 */
-SQLITE_API int sqlite3_set_authorizer(
+SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer(
   sqlite3 *db,
   int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
   void *pArg
 ){
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+#endif
   sqlite3_mutex_enter(db->mutex);
-  db->xAuth = xAuth;
+  db->xAuth = (sqlite3_xauth)xAuth;
   db->pAuthArg = pArg;
   sqlite3ExpirePreparedStatements(db);
   sqlite3_mutex_leave(db->mutex);
@@ -85948,7 +90652,11 @@ SQLITE_PRIVATE int sqlite3AuthReadCol(
   char *zDb = db->aDb[iDb].zName; /* Name of attached database */
   int rc;                         /* Auth callback return code */
 
-  rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext);
+  rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext
+#ifdef SQLITE_USER_AUTHENTICATION
+                 ,db->auth.zAuthUser
+#endif
+                );
   if( rc==SQLITE_DENY ){
     if( db->nDb>2 || iDb!=0 ){
       sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",zDb,zTab,zCol);
@@ -86048,7 +90756,11 @@ SQLITE_PRIVATE int sqlite3AuthCheck(
   if( db->xAuth==0 ){
     return SQLITE_OK;
   }
-  rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext);
+  rc = db->xAuth(db->pAuthArg, code, zArg1, zArg2, zArg3, pParse->zAuthContext
+#ifdef SQLITE_USER_AUTHENTICATION
+                 ,db->auth.zAuthUser
+#endif
+                );
   if( rc==SQLITE_DENY ){
     sqlite3ErrorMsg(pParse, "not authorized");
     pParse->rc = SQLITE_AUTH;
@@ -86233,9 +90945,11 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
 
   assert( pParse->pToplevel==0 );
   db = pParse->db;
-  if( db->mallocFailed ) return;
   if( pParse->nested ) return;
-  if( pParse->nErr ) return;
+  if( db->mallocFailed || pParse->nErr ){
+    if( pParse->rc==SQLITE_OK ) pParse->rc = SQLITE_ERROR;
+    return;
+  }
 
   /* Begin by generating some termination code at the end of the
   ** vdbe program
@@ -86247,6 +90961,17 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
     while( sqlite3VdbeDeletePriorOpcode(v, OP_Close) ){}
     sqlite3VdbeAddOp0(v, OP_Halt);
 
+#if SQLITE_USER_AUTHENTICATION
+    if( pParse->nTableLock>0 && db->init.busy==0 ){
+      sqlite3UserAuthInit(db);
+      if( db->auth.authLevel<UAUTH_User ){
+        pParse->rc = SQLITE_AUTH_USER;
+        sqlite3ErrorMsg(pParse, "user not authenticated");
+        return;
+      }
+    }
+#endif
+
     /* The cookie mask contains one bit for each database file open.
     ** (Bit 0 is for main, bit 1 is for temp, and so forth.)  Bits are
     ** set for each database that is used.  Generate code to start a
@@ -86306,7 +91031,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){
 
   /* Get the VDBE program ready for execution
   */
-  if( v && ALWAYS(pParse->nErr==0) && !db->mallocFailed ){
+  if( v && pParse->nErr==0 && !db->mallocFailed ){
     assert( pParse->iCacheLevel==0 );  /* Disables and re-enables match */
     /* A minimum of one cursor is required if autoincrement is used
     *  See ticket [a696379c1f08866] */
@@ -86362,6 +91087,16 @@ SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
   pParse->nested--;
 }
 
+#if SQLITE_USER_AUTHENTICATION
+/*
+** Return TRUE if zTable is the name of the system table that stores the
+** list of users and their access credentials.
+*/
+SQLITE_PRIVATE int sqlite3UserAuthTable(const char *zTable){
+  return sqlite3_stricmp(zTable, "sqlite_user")==0;
+}
+#endif
+
 /*
 ** Locate the in-memory structure that describes a particular database
 ** table given the name of that table and (optionally) the name of the
@@ -86377,16 +91112,21 @@ SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
 SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
   Table *p = 0;
   int i;
-  int nName;
-  assert( zName!=0 );
-  nName = sqlite3Strlen30(zName);
+
   /* All mutexes are required for schema access.  Make sure we hold them. */
   assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) );
+#if SQLITE_USER_AUTHENTICATION
+  /* Only the admin user is allowed to know that the sqlite_user table
+  ** exists */
+  if( db->auth.authLevel<UAUTH_Admin && sqlite3UserAuthTable(zName)!=0 ){
+    return 0;
+  }
+#endif
   for(i=OMIT_TEMPDB; i<db->nDb; i++){
     int j = (i<2) ? i^1 : i;   /* Search TEMP before MAIN */
     if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue;
     assert( sqlite3SchemaMutexHeld(db, j, 0) );
-    p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName, nName);
+    p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName);
     if( p ) break;
   }
   return p;
@@ -86426,6 +91166,12 @@ SQLITE_PRIVATE Table *sqlite3LocateTable(
     }
     pParse->checkSchema = 1;
   }
+#if SQLITE_USER_AUTHENICATION
+  else if( pParse->db->auth.authLevel<UAUTH_User ){
+    sqlite3ErrorMsg(pParse, "user not authenticated");
+    p = 0;
+  }
+#endif
   return p;
 }
 
@@ -86469,7 +91215,6 @@ SQLITE_PRIVATE Table *sqlite3LocateTableItem(
 SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){
   Index *p = 0;
   int i;
-  int nName = sqlite3Strlen30(zName);
   /* All mutexes are required for schema access.  Make sure we hold them. */
   assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
   for(i=OMIT_TEMPDB; i<db->nDb; i++){
@@ -86478,7 +91223,7 @@ SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const cha
     assert( pSchema );
     if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;
     assert( sqlite3SchemaMutexHeld(db, j, 0) );
-    p = sqlite3HashFind(&pSchema->idxHash, zName, nName);
+    p = sqlite3HashFind(&pSchema->idxHash, zName);
     if( p ) break;
   }
   return p;
@@ -86491,10 +91236,12 @@ static void freeIndex(sqlite3 *db, Index *p){
 #ifndef SQLITE_OMIT_ANALYZE
   sqlite3DeleteIndexSamples(db, p);
 #endif
-  if( db==0 || db->pnBytesFreed==0 ) sqlite3KeyInfoUnref(p->pKeyInfo);
   sqlite3ExprDelete(db, p->pPartIdxWhere);
   sqlite3DbFree(db, p->zColAff);
   if( p->isResized ) sqlite3DbFree(db, p->azColl);
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
+  sqlite3_free(p->aiRowEst);
+#endif
   sqlite3DbFree(db, p);
 }
 
@@ -86506,13 +91253,11 @@ static void freeIndex(sqlite3 *db, Index *p){
 */
 SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){
   Index *pIndex;
-  int len;
   Hash *pHash;
 
   assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
   pHash = &db->aDb[iDb].pSchema->idxHash;
-  len = sqlite3Strlen30(zIdxName);
-  pIndex = sqlite3HashInsert(pHash, zIdxName, len, 0);
+  pIndex = sqlite3HashInsert(pHash, zIdxName, 0);
   if( ALWAYS(pIndex) ){
     if( pIndex->pTable->pIndex==pIndex ){
       pIndex->pTable->pIndex = pIndex->pNext;
@@ -86672,7 +91417,7 @@ SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){
     if( !db || db->pnBytesFreed==0 ){
       char *zName = pIndex->zName; 
       TESTONLY ( Index *pOld = ) sqlite3HashInsert(
-         &pIndex->pSchema->idxHash, zName, sqlite3Strlen30(zName), 0
+         &pIndex->pSchema->idxHash, zName, 0
       );
       assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
       assert( pOld==pIndex || pOld==0 );
@@ -86715,8 +91460,7 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char
   assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
   testcase( zTabName[0]==0 );  /* Zero-length table names are allowed */
   pDb = &db->aDb[iDb];
-  p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName,
-                        sqlite3Strlen30(zTabName),0);
+  p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, 0);
   sqlite3DeleteTable(db, p);
   db->flags |= SQLITE_InternChanges;
 }
@@ -86822,14 +91566,12 @@ SQLITE_PRIVATE int sqlite3TwoPartName(
   if( ALWAYS(pName2!=0) && pName2->n>0 ){
     if( db->init.busy ) {
       sqlite3ErrorMsg(pParse, "corrupt database");
-      pParse->nErr++;
       return -1;
     }
     *pUnqual = pName2;
     iDb = sqlite3FindDb(db, pName1);
     if( iDb<0 ){
       sqlite3ErrorMsg(pParse, "unknown database %T", pName1);
-      pParse->nErr++;
       return -1;
     }
   }else{
@@ -86988,7 +91730,7 @@ SQLITE_PRIVATE void sqlite3StartTable(
       if( !noErr ){
         sqlite3ErrorMsg(pParse, "table %T already exists", pName);
       }else{
-        assert( !db->init.busy );
+        assert( !db->init.busy || CORRUPT_DB );
         sqlite3CodeVerifySchema(pParse, iDb);
       }
       goto begin_table_error;
@@ -87240,7 +91982,7 @@ SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, u8 *pszEst){
   ** estimate is scaled so that the size of an integer is 1.  */
   if( pszEst ){
     *pszEst = 1;   /* default size is approx 4 bytes */
-    if( aff<=SQLITE_AFF_NONE ){
+    if( aff<SQLITE_AFF_NUMERIC ){
       if( zChar ){
         while( zChar[0] ){
           if( sqlite3Isdigit(zChar[0]) ){
@@ -87277,7 +92019,8 @@ SQLITE_PRIVATE void sqlite3AddColumnType(Parse *pParse, Token *pType){
   p = pParse->pNewTable;
   if( p==0 || NEVER(p->nCol<1) ) return;
   pCol = &p->aCol[p->nCol-1];
-  assert( pCol->zType==0 );
+  assert( pCol->zType==0 || CORRUPT_DB );
+  sqlite3DbFree(pParse->db, pCol->zType);
   pCol->zType = sqlite3NameFromToken(pParse->db, pType);
   pCol->affinity = sqlite3AffinityType(pCol->zType, &pCol->szEst);
 }
@@ -87299,7 +92042,7 @@ SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){
   p = pParse->pNewTable;
   if( p!=0 ){
     pCol = &(p->aCol[p->nCol-1]);
-    if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr) ){
+    if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr, db->init.busy) ){
       sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
           pCol->zName);
     }else{
@@ -87611,8 +92354,8 @@ static char *createTableStmt(sqlite3 *db, Table *p){
   zStmt[k++] = '(';
   for(pCol=p->aCol, i=0; i<p->nCol; i++, pCol++){
     static const char * const azType[] = {
-        /* SQLITE_AFF_TEXT    */ " TEXT",
         /* SQLITE_AFF_NONE    */ "",
+        /* SQLITE_AFF_TEXT    */ " TEXT",
         /* SQLITE_AFF_NUMERIC */ " NUM",
         /* SQLITE_AFF_INTEGER */ " INT",
         /* SQLITE_AFF_REAL    */ " REAL"
@@ -87624,15 +92367,15 @@ static char *createTableStmt(sqlite3 *db, Table *p){
     k += sqlite3Strlen30(&zStmt[k]);
     zSep = zSep2;
     identPut(zStmt, &k, pCol->zName);
-    assert( pCol->affinity-SQLITE_AFF_TEXT >= 0 );
-    assert( pCol->affinity-SQLITE_AFF_TEXT < ArraySize(azType) );
-    testcase( pCol->affinity==SQLITE_AFF_TEXT );
+    assert( pCol->affinity-SQLITE_AFF_NONE >= 0 );
+    assert( pCol->affinity-SQLITE_AFF_NONE < ArraySize(azType) );
     testcase( pCol->affinity==SQLITE_AFF_NONE );
+    testcase( pCol->affinity==SQLITE_AFF_TEXT );
     testcase( pCol->affinity==SQLITE_AFF_NUMERIC );
     testcase( pCol->affinity==SQLITE_AFF_INTEGER );
     testcase( pCol->affinity==SQLITE_AFF_REAL );
     
-    zType = azType[pCol->affinity - SQLITE_AFF_TEXT];
+    zType = azType[pCol->affinity - SQLITE_AFF_NONE];
     len = sqlite3Strlen30(zType);
     assert( pCol->affinity==SQLITE_AFF_NONE 
             || pCol->affinity==sqlite3AffinityType(zType, 0) );
@@ -87716,7 +92459,7 @@ static int hasColumn(const i16 *aiCol, int nCol, int x){
 **          no rowid btree for a WITHOUT ROWID.  Instead, the canonical
 **          data storage is a covering index btree.
 **     (2)  Bypass the creation of the sqlite_master table entry
-**          for the PRIMARY KEY as the the primary key index is now
+**          for the PRIMARY KEY as the primary key index is now
 **          identified by the sqlite_master table entry of the table itself.
 **     (3)  Set the Index.tnum of the PRIMARY KEY Index object in the
 **          schema to the rootpage from the main table.
@@ -87737,7 +92480,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
   Vdbe *v = pParse->pVdbe;
 
   /* Convert the OP_CreateTable opcode that would normally create the
-  ** root-page for the table into a OP_CreateIndex opcode.  The index
+  ** root-page for the table into an OP_CreateIndex opcode.  The index
   ** created will become the PRIMARY KEY index.
   */
   if( pParse->addrCrTab ){
@@ -87770,16 +92513,32 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){
     pTab->iPKey = -1;
   }else{
     pPk = sqlite3PrimaryKeyIndex(pTab);
+    /*
+    ** Remove all redundant columns from the PRIMARY KEY.  For example, change
+    ** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)".  Later
+    ** code assumes the PRIMARY KEY contains no repeated columns.
+    */
+    for(i=j=1; i<pPk->nKeyCol; i++){
+      if( hasColumn(pPk->aiColumn, j, pPk->aiColumn[i]) ){
+        pPk->nColumn--;
+      }else{
+        pPk->aiColumn[j++] = pPk->aiColumn[i];
+      }
+    }
+    pPk->nKeyCol = j;
   }
   pPk->isCovering = 1;
   assert( pPk!=0 );
   nPk = pPk->nKeyCol;
 
-  /* Make sure every column of the PRIMARY KEY is NOT NULL */
-  for(i=0; i<nPk; i++){
-    pTab->aCol[pPk->aiColumn[i]].notNull = 1;
+  /* Make sure every column of the PRIMARY KEY is NOT NULL.  (Except,
+  ** do not enforce this for imposter tables.) */
+  if( !db->init.imposterTable ){
+    for(i=0; i<nPk; i++){
+      pTab->aCol[pPk->aiColumn[i]].notNull = 1;
+    }
+    pPk->uniqNotNull = 1;
   }
-  pPk->uniqNotNull = 1;
 
   /* The root page of the PRIMARY KEY is the table root page */
   pPk->tnum = pTab->tnum;
@@ -88038,8 +92797,7 @@ SQLITE_PRIVATE void sqlite3EndTable(
     Table *pOld;
     Schema *pSchema = p->pSchema;
     assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
-    pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName,
-                             sqlite3Strlen30(p->zName),p);
+    pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, p);
     if( pOld ){
       assert( p==pOld );  /* Malloc must have failed inside HashInsert() */
       db->mallocFailed = 1;
@@ -88150,7 +92908,7 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){
   int nErr = 0;     /* Number of errors encountered */
   int n;            /* Temporarily holds the number of cursors assigned */
   sqlite3 *db = pParse->db;  /* Database connection for malloc errors */
-  int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
+  sqlite3_xauth xAuth;       /* Saved xAuth pointer */
 
   assert( pTable );
 
@@ -88496,6 +93254,7 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView,
   }
   assert( pParse->nErr==0 );
   assert( pName->nSrc==1 );
+  if( sqlite3ReadSchema(pParse) ) goto exit_drop_table;
   if( noErr ) db->suppressErr++;
   pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]);
   if( noErr ) db->suppressErr--;
@@ -88689,7 +93448,7 @@ SQLITE_PRIVATE void sqlite3CreateForeignKey(
 
   assert( sqlite3SchemaMutexHeld(db, 0, p->pSchema) );
   pNextTo = (FKey *)sqlite3HashInsert(&p->pSchema->fkeyHash, 
-      pFKey->zTo, sqlite3Strlen30(pFKey->zTo), (void *)pFKey
+      pFKey->zTo, (void *)pFKey
   );
   if( pNextTo==pFKey ){
     db->mallocFailed = 1;
@@ -88752,7 +93511,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
   int iPartIdxLabel;             /* Jump to this label to skip a row */
   Vdbe *v;                       /* Generate code into this virtual machine */
   KeyInfo *pKey;                 /* KeyInfo for index */
-  int regRecord;                 /* Register holding assemblied index record */
+  int regRecord;                 /* Register holding assembled index record */
   sqlite3 *db = pParse->db;      /* The database connection */
   int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
 
@@ -88777,7 +93536,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
 
   /* Open the sorter cursor if we are to use one. */
   iSorter = pParse->nTab++;
-  sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)
+  sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, pIndex->nKeyCol, (char*)
                     sqlite3KeyInfoRef(pKey), P4_KEYINFO);
 
   /* Open the table. Loop through all rows of the table, inserting index
@@ -88808,8 +93567,9 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
   }else{
     addr2 = sqlite3VdbeCurrentAddr(v);
   }
-  sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord);
-  sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
+  sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx);
+  sqlite3VdbeAddOp3(v, OP_Last, iIdx, 0, -1);
+  sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0);
   sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
   sqlite3ReleaseTempReg(pParse, regRecord);
   sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v);
@@ -88902,8 +93662,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
   char *zExtra = 0;                /* Extra space after the Index object */
   Index *pPk = 0;      /* PRIMARY KEY index for WITHOUT ROWID tables */
 
-  assert( pParse->nErr==0 );      /* Never called with prior errors */
-  if( db->mallocFailed || IN_DECLARE_VTAB ){
+  if( db->mallocFailed || IN_DECLARE_VTAB || pParse->nErr>0 ){
     goto exit_create_index;
   }
   if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
@@ -88965,6 +93724,10 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
   assert( pTab!=0 );
   assert( pParse->nErr==0 );
   if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 
+       && db->init.busy==0
+#if SQLITE_USER_AUTHENTICATION
+       && sqlite3UserAuthTable(pTab->zName)==0
+#endif
        && sqlite3StrNICmp(&pTab->zName[7],"altertab_",9)!=0 ){
     sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName);
     goto exit_create_index;
@@ -89126,7 +93889,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
       pParse->checkSchema = 1;
       goto exit_create_index;
     }
-    assert( pTab->nCol<=0x7fff && j<=0x7fff );
+    assert( j<=0x7fff );
     pIndex->aiColumn[i] = (i16)j;
     if( pListItem->pExpr ){
       int nColl;
@@ -89225,6 +93988,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
             pIdx->onError = pIndex->onError;
           }
         }
+        pRet = pIdx;
         goto exit_create_index;
       }
     }
@@ -89237,8 +94001,7 @@ SQLITE_PRIVATE Index *sqlite3CreateIndex(
     Index *p;
     assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) );
     p = sqlite3HashInsert(&pIndex->pSchema->idxHash, 
-                          pIndex->zName, sqlite3Strlen30(pIndex->zName),
-                          pIndex);
+                          pIndex->zName, pIndex);
     if( p ){
       assert( p==pIndex );  /* Malloc must have failed */
       db->mallocFailed = 1;
@@ -89353,7 +94116,7 @@ exit_create_index:
 ** Fill the Index.aiRowEst[] array with default information - information
 ** to be used when we have not run the ANALYZE command.
 **
-** aiRowEst[0] is suppose to contain the number of elements in the index.
+** aiRowEst[0] is supposed to contain the number of elements in the index.
 ** Since we do not know, guess 1 million.  aiRowEst[1] is an estimate of the
 ** number of rows in the table that match any particular value of the
 ** first column of the index.  aiRowEst[2] is an estimate of the number
@@ -89732,7 +94495,7 @@ SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){
 ** if this is the first term of the FROM clause.  pTable and pDatabase
 ** are the name of the table and database named in the FROM clause term.
 ** pDatabase is NULL if the database name qualifier is missing - the
-** usual case.  If the term has a alias, then pAlias points to the
+** usual case.  If the term has an alias, then pAlias points to the
 ** alias token.  If the term is a subquery, then pSubquery is the
 ** SELECT statement that the subquery encodes.  The pTable and
 ** pDatabase parameters are NULL for subqueries.  The pOn and pUsing
@@ -89818,7 +94581,6 @@ SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pI
 SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList *p){
   if( p ){
     int i;
-    assert( p->a || p->nSrc==0 );
     for(i=p->nSrc-1; i>0; i--){
       p->a[i].jointype = p->a[i-1].jointype;
     }
@@ -90065,8 +94827,7 @@ SQLITE_PRIVATE void sqlite3UniqueConstraint(
   StrAccum errMsg;
   Table *pTab = pIdx->pTable;
 
-  sqlite3StrAccumInit(&errMsg, 0, 0, 200);
-  errMsg.db = pParse->db;
+  sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
   for(j=0; j<pIdx->nKeyCol; j++){
     char *zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
     if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
@@ -90244,40 +95005,31 @@ SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){
 ** when it has finished using it.
 */
 SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){
+  int i;
+  int nCol = pIdx->nColumn;
+  int nKey = pIdx->nKeyCol;
+  KeyInfo *pKey;
   if( pParse->nErr ) return 0;
-#ifndef SQLITE_OMIT_SHARED_CACHE
-  if( pIdx->pKeyInfo && pIdx->pKeyInfo->db!=pParse->db ){
-    sqlite3KeyInfoUnref(pIdx->pKeyInfo);
-    pIdx->pKeyInfo = 0;
+  if( pIdx->uniqNotNull ){
+    pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey);
+  }else{
+    pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0);
   }
-#endif
-  if( pIdx->pKeyInfo==0 ){
-    int i;
-    int nCol = pIdx->nColumn;
-    int nKey = pIdx->nKeyCol;
-    KeyInfo *pKey;
-    if( pIdx->uniqNotNull ){
-      pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey);
-    }else{
-      pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0);
+  if( pKey ){
+    assert( sqlite3KeyInfoIsWriteable(pKey) );
+    for(i=0; i<nCol; i++){
+      char *zColl = pIdx->azColl[i];
+      assert( zColl!=0 );
+      pKey->aColl[i] = strcmp(zColl,"BINARY")==0 ? 0 :
+                        sqlite3LocateCollSeq(pParse, zColl);
+      pKey->aSortOrder[i] = pIdx->aSortOrder[i];
     }
-    if( pKey ){
-      assert( sqlite3KeyInfoIsWriteable(pKey) );
-      for(i=0; i<nCol; i++){
-        char *zColl = pIdx->azColl[i];
-        assert( zColl!=0 );
-        pKey->aColl[i] = strcmp(zColl,"BINARY")==0 ? 0 :
-                          sqlite3LocateCollSeq(pParse, zColl);
-        pKey->aSortOrder[i] = pIdx->aSortOrder[i];
-      }
-      if( pParse->nErr ){
-        sqlite3KeyInfoUnref(pKey);
-      }else{
-        pIdx->pKeyInfo = pKey;
-      }
+    if( pParse->nErr ){
+      sqlite3KeyInfoUnref(pKey);
+      pKey = 0;
     }
   }
-  return sqlite3KeyInfoRef(pIdx->pKeyInfo);
+  return pKey;
 }
 
 #ifndef SQLITE_OMIT_CTE
@@ -90495,7 +95247,7 @@ SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){
 **
 ** Each pointer stored in the sqlite3.aCollSeq hash table contains an
 ** array of three CollSeq structures. The first is the collation sequence
-** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be.
+** preferred for UTF-8, the second UTF-16le, and the third UTF-16be.
 **
 ** Stored immediately after the three collation sequences is a copy of
 ** the collation sequence name. A pointer to this string is stored in
@@ -90507,11 +95259,11 @@ static CollSeq *findCollSeqEntry(
   int create            /* Create a new entry if true */
 ){
   CollSeq *pColl;
-  int nName = sqlite3Strlen30(zName);
-  pColl = sqlite3HashFind(&db->aCollSeq, zName, nName);
+  pColl = sqlite3HashFind(&db->aCollSeq, zName);
 
   if( 0==pColl && create ){
-    pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1 );
+    int nName = sqlite3Strlen30(zName);
+    pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1);
     if( pColl ){
       CollSeq *pDel = 0;
       pColl[0].zName = (char*)&pColl[3];
@@ -90522,7 +95274,7 @@ static CollSeq *findCollSeqEntry(
       pColl[2].enc = SQLITE_UTF16BE;
       memcpy(pColl[0].zName, zName, nName);
       pColl[0].zName[nName] = 0;
-      pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, nName, pColl);
+      pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, pColl);
 
       /* If a malloc() failure occurred in sqlite3HashInsert(), it will 
       ** return the pColl pointer to be deleted (because it wasn't added
@@ -90922,7 +95674,7 @@ SQLITE_PRIVATE void sqlite3MaterializeView(
   Parse *pParse,       /* Parsing context */
   Table *pView,        /* View definition */
   Expr *pWhere,        /* Optional WHERE clause to be added */
-  int iCur             /* Cursor number for ephemerial table */
+  int iCur             /* Cursor number for ephemeral table */
 ){
   SelectDest dest;
   Select *pSel;
@@ -91021,7 +95773,7 @@ SQLITE_PRIVATE Expr *sqlite3LimitWhere(
 
   pInClause->x.pSelect = pSelect;
   pInClause->flags |= EP_xIsSelect;
-  sqlite3ExprSetHeight(pParse, pInClause);
+  sqlite3ExprSetHeightAndFlags(pParse, pInClause);
   return pInClause;
 
   /* something went wrong. clean up anything allocated. */
@@ -91058,8 +95810,8 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
   WhereInfo *pWInfo;     /* Information about the WHERE clause */
   Index *pIdx;           /* For looping over indices of the table */
   int iTabCur;           /* Cursor number for the table */
-  int iDataCur;          /* VDBE cursor for the canonical data source */
-  int iIdxCur;           /* Cursor number of the first index */
+  int iDataCur = 0;      /* VDBE cursor for the canonical data source */
+  int iIdxCur = 0;       /* Cursor number of the first index */
   int nIdx;              /* Number of indices */
   sqlite3 *db;           /* Main database structure */
   AuthContext sContext;  /* Authorization context */
@@ -91080,7 +95832,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
   int addrBypass = 0;    /* Address of jump over the delete logic */
   int addrLoop = 0;      /* Top of the delete loop */
   int addrDelete = 0;    /* Jump directly to the delete logic */
-  int addrEphOpen = 0;   /* Instruction to open the Ephermeral table */
+  int addrEphOpen = 0;   /* Instruction to open the Ephemeral table */
  
 #ifndef SQLITE_OMIT_TRIGGER
   int isView;                  /* True if attempting to delete from a view */
@@ -91160,7 +95912,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
   sqlite3BeginWriteOperation(pParse, 1, iDb);
 
   /* If we are trying to delete from a view, realize that view into
-  ** a ephemeral table.
+  ** an ephemeral table.
   */
 #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
   if( isView ){
@@ -91214,7 +95966,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
       iRowSet = ++pParse->nMem;
       sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet);
     }else{
-      /* For a WITHOUT ROWID table, create an ephermeral table used to
+      /* For a WITHOUT ROWID table, create an ephemeral table used to
       ** hold all primary keys for rows to be deleted. */
       pPk = sqlite3PrimaryKeyIndex(pTab);
       assert( pPk!=0 );
@@ -91298,10 +96050,11 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
     ** triggers.
     */
     if( !isView ){
+      testcase( IsVirtual(pTab) );
       sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, iTabCur, aToOpen,
                                  &iDataCur, &iIdxCur);
-      assert( pPk || iDataCur==iTabCur );
-      assert( pPk || iIdxCur==iDataCur+1 );
+      assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur );
+      assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 );
     }
   
     /* Set up a loop over the rowids/primary-keys that were found in the
@@ -91309,9 +96062,10 @@ SQLITE_PRIVATE void sqlite3DeleteFrom(
     */
     if( okOnePass ){
       /* Just one row.  Hence the top-of-loop is a no-op */
-      assert( nKey==nPk ); /* OP_Found will use an unpacked key */
+      assert( nKey==nPk );  /* OP_Found will use an unpacked key */
+      assert( !IsVirtual(pTab) );
       if( aToOpen[iDataCur-iTabCur] ){
-        assert( pPk!=0 );
+        assert( pPk!=0 || pTab->pSelect!=0 );
         sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
         VdbeCoverage(v);
       }
@@ -91387,7 +96141,7 @@ delete_from_cleanup:
   return;
 }
 /* Make sure "isView" and other macros defined above are undefined. Otherwise
-** thely may interfere with compilation of other functions in this file
+** they may interfere with compilation of other functions in this file
 ** (or in another file, if this file becomes part of the amalgamation).  */
 #ifdef isView
  #undef isView
@@ -91681,7 +96435,7 @@ SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** This file contains the C-language implementions for many of the SQL
+** This file contains the C-language implementations for many of the SQL
 ** functions of SQLite.  (Some function, and in particular the date and
 ** time functions, are implemented separately.)
 */
@@ -91692,7 +96446,12 @@ SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){
 ** Return the collating function associated with a function.
 */
 static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){
-  return context->pColl;
+  VdbeOp *pOp;
+  assert( context->pVdbe!=0 );
+  pOp = &context->pVdbe->aOp[context->iOp-1];
+  assert( pOp->opcode==OP_CollSeq );
+  assert( pOp->p4type==P4_COLLSEQ );
+  return pOp->p4.pColl;
 }
 
 /*
@@ -91824,8 +96583,8 @@ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
     default: {
       /* Because sqlite3_value_double() returns 0.0 if the argument is not
       ** something that can be converted into a number, we have:
-      ** IMP: R-57326-31541 Abs(X) return 0.0 if X is a string or blob that
-      ** cannot be converted to a numeric value. 
+      ** IMP: R-01992-00519 Abs(X) returns 0.0 if X is a string or blob
+      ** that cannot be converted to a numeric value.
       */
       double rVal = sqlite3_value_double(argv[0]);
       if( rVal<0 ) rVal = -rVal;
@@ -91897,13 +96656,13 @@ static void printfFunc(
   StrAccum str;
   const char *zFormat;
   int n;
+  sqlite3 *db = sqlite3_context_db_handle(context);
 
   if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){
     x.nArg = argc-1;
     x.nUsed = 0;
     x.apArg = argv+1;
-    sqlite3StrAccumInit(&str, 0, 0, SQLITE_MAX_LENGTH);
-    str.db = sqlite3_context_db_handle(context);
+    sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
     sqlite3XPrintf(&str, SQLITE_PRINTF_SQLFUNC, zFormat, &x);
     n = str.nChar;
     sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
@@ -91958,6 +96717,14 @@ static void substrFunc(
       }
     }
   }
+#ifdef SQLITE_SUBSTR_COMPATIBILITY
+  /* If SUBSTR_COMPATIBILITY is defined then substr(X,0,N) work the same as
+  ** as substr(X,1,N) - it returns the first N characters of X.  This
+  ** is essentially a back-out of the bug-fix in check-in [5fc125d362df4b8]
+  ** from 2009-02-02 for compatibility of applications that exploited the
+  ** old buggy behavior. */
+  if( p1==0 ) p1 = 1; /* <rdar://problem/6778339> */
+#endif
   if( argc==3 ){
     p2 = sqlite3_value_int(argv[2]);
     if( p2<0 ){
@@ -91995,13 +96762,14 @@ static void substrFunc(
     for(z2=z; *z2 && p2; p2--){
       SQLITE_SKIP_UTF8(z2);
     }
-    sqlite3_result_text(context, (char*)z, (int)(z2-z), SQLITE_TRANSIENT);
+    sqlite3_result_text64(context, (char*)z, z2-z, SQLITE_TRANSIENT,
+                          SQLITE_UTF8);
   }else{
     if( p1+p2>len ){
       p2 = len-p1;
       if( p2<0 ) p2 = 0;
     }
-    sqlite3_result_blob(context, (char*)&z[p1], (int)p2, SQLITE_TRANSIENT);
+    sqlite3_result_blob64(context, (char*)&z[p1], (u64)p2, SQLITE_TRANSIENT);
   }
 }
 
@@ -92044,7 +96812,7 @@ static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
 #endif
 
 /*
-** Allocate nByte bytes of space using sqlite3_malloc(). If the
+** Allocate nByte bytes of space using sqlite3Malloc(). If the
 ** allocation fails, call sqlite3_result_error_nomem() to notify
 ** the database handle that malloc() has failed and return NULL.
 ** If nByte is larger than the maximum string or blob length, then
@@ -92060,7 +96828,7 @@ static void *contextMalloc(sqlite3_context *context, i64 nByte){
     sqlite3_result_error_toobig(context);
     z = 0;
   }else{
-    z = sqlite3Malloc((int)nByte);
+    z = sqlite3Malloc(nByte);
     if( !z ){
       sqlite3_result_error_nomem(context);
     }
@@ -92236,10 +97004,12 @@ struct compareInfo {
 ** whereas only characters less than 0x80 do in ASCII.
 */
 #if defined(SQLITE_EBCDIC)
-# define sqlite3Utf8Read(A)    (*((*A)++))
-# define GlobUpperToLower(A)   A = sqlite3UpperToLower[A]
+# define sqlite3Utf8Read(A)        (*((*A)++))
+# define GlobUpperToLower(A)       A = sqlite3UpperToLower[A]
+# define GlobUpperToLowerAscii(A)  A = sqlite3UpperToLower[A]
 #else
-# define GlobUpperToLower(A)   if( !((A)&~0x7f) ){ A = sqlite3UpperToLower[A]; }
+# define GlobUpperToLower(A)       if( A<=0x7f ){ A = sqlite3UpperToLower[A]; }
+# define GlobUpperToLowerAscii(A)  A = sqlite3UpperToLower[A]
 #endif
 
 static const struct compareInfo globInfo = { '*', '?', '[', 0 };
@@ -92252,7 +97022,7 @@ static const struct compareInfo likeInfoAlt = { '%', '_',   0, 0 };
 
 /*
 ** Compare two UTF-8 strings for equality where the first string can
-** potentially be a "glob" expression.  Return true (1) if they
+** potentially be a "glob" or "like" expression.  Return true (1) if they
 ** are the same and false (0) if they are different.
 **
 ** Globbing rules:
@@ -92272,11 +97042,18 @@ static const struct compareInfo likeInfoAlt = { '%', '_',   0, 0 };
 ** "[a-z]" matches any single lower-case letter.  To match a '-', make
 ** it the last character in the list.
 **
-** This routine is usually quick, but can be N**2 in the worst case.
+** Like matching rules:
+** 
+**      '%'       Matches any sequence of zero or more characters
+**
+***     '_'       Matches any one character
 **
-** Hints: to match '*' or '?', put them in "[]".  Like this:
+**      Ec        Where E is the "esc" character and c is any other
+**                character, including '%', '_', and esc, match exactly c.
 **
-**         abc[*]xyz        Matches "abc*xyz" only
+** The comments through this routine usually assume glob matching.
+**
+** This routine is usually quick, but can be N**2 in the worst case.
 */
 static int patternCompare(
   const u8 *zPattern,              /* The glob pattern */
@@ -92284,17 +97061,25 @@ static int patternCompare(
   const struct compareInfo *pInfo, /* Information about how to do the compare */
   u32 esc                          /* The escape character */
 ){
-  u32 c, c2;
-  int invert;
-  int seen;
-  u8 matchOne = pInfo->matchOne;
-  u8 matchAll = pInfo->matchAll;
-  u8 matchSet = pInfo->matchSet;
-  u8 noCase = pInfo->noCase; 
-  int prevEscape = 0;     /* True if the previous character was 'escape' */
+  u32 c, c2;                       /* Next pattern and input string chars */
+  u32 matchOne = pInfo->matchOne;  /* "?" or "_" */
+  u32 matchAll = pInfo->matchAll;  /* "*" or "%" */
+  u32 matchOther;                  /* "[" or the escape character */
+  u8 noCase = pInfo->noCase;       /* True if uppercase==lowercase */
+  const u8 *zEscaped = 0;          /* One past the last escaped input char */
+  
+  /* The GLOB operator does not have an ESCAPE clause.  And LIKE does not
+  ** have the matchSet operator.  So we either have to look for one or
+  ** the other, never both.  Hence the single variable matchOther is used
+  ** to store the one we have to look for.
+  */
+  matchOther = esc ? esc : pInfo->matchSet;
 
   while( (c = sqlite3Utf8Read(&zPattern))!=0 ){
-    if( c==matchAll && !prevEscape ){
+    if( c==matchAll ){  /* Match "*" */
+      /* Skip over multiple "*" characters in the pattern.  If there
+      ** are also "?" characters, skip those as well, but consume a
+      ** single character of the input string for each "?" skipped */
       while( (c=sqlite3Utf8Read(&zPattern)) == matchAll
                || c == matchOne ){
         if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){
@@ -92302,86 +97087,98 @@ static int patternCompare(
         }
       }
       if( c==0 ){
-        return 1;
-      }else if( c==esc ){
-        c = sqlite3Utf8Read(&zPattern);
-        if( c==0 ){
-          return 0;
-        }
-      }else if( c==matchSet ){
-        assert( esc==0 );         /* This is GLOB, not LIKE */
-        assert( matchSet<0x80 );  /* '[' is a single-byte character */
-        while( *zString && patternCompare(&zPattern[-1],zString,pInfo,esc)==0 ){
-          SQLITE_SKIP_UTF8(zString);
+        return 1;   /* "*" at the end of the pattern matches */
+      }else if( c==matchOther ){
+        if( esc ){
+          c = sqlite3Utf8Read(&zPattern);
+          if( c==0 ) return 0;
+        }else{
+          /* "[...]" immediately follows the "*".  We have to do a slow
+          ** recursive search in this case, but it is an unusual case. */
+          assert( matchOther<0x80 );  /* '[' is a single-byte character */
+          while( *zString
+                 && patternCompare(&zPattern[-1],zString,pInfo,esc)==0 ){
+            SQLITE_SKIP_UTF8(zString);
+          }
+          return *zString!=0;
         }
-        return *zString!=0;
       }
-      while( (c2 = sqlite3Utf8Read(&zString))!=0 ){
+
+      /* At this point variable c contains the first character of the
+      ** pattern string past the "*".  Search in the input string for the
+      ** first matching character and recursively contine the match from
+      ** that point.
+      **
+      ** For a case-insensitive search, set variable cx to be the same as
+      ** c but in the other case and search the input string for either
+      ** c or cx.
+      */
+      if( c<=0x80 ){
+        u32 cx;
         if( noCase ){
-          GlobUpperToLower(c2);
-          GlobUpperToLower(c);
-          while( c2 != 0 && c2 != c ){
-            c2 = sqlite3Utf8Read(&zString);
-            GlobUpperToLower(c2);
-          }
+          cx = sqlite3Toupper(c);
+          c = sqlite3Tolower(c);
         }else{
-          while( c2 != 0 && c2 != c ){
-            c2 = sqlite3Utf8Read(&zString);
-          }
+          cx = c;
+        }
+        while( (c2 = *(zString++))!=0 ){
+          if( c2!=c && c2!=cx ) continue;
+          if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
+        }
+      }else{
+        while( (c2 = sqlite3Utf8Read(&zString))!=0 ){
+          if( c2!=c ) continue;
+          if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
         }
-        if( c2==0 ) return 0;
-        if( patternCompare(zPattern,zString,pInfo,esc) ) return 1;
       }
       return 0;
-    }else if( c==matchOne && !prevEscape ){
-      if( sqlite3Utf8Read(&zString)==0 ){
-        return 0;
-      }
-    }else if( c==matchSet ){
-      u32 prior_c = 0;
-      assert( esc==0 );    /* This only occurs for GLOB, not LIKE */
-      seen = 0;
-      invert = 0;
-      c = sqlite3Utf8Read(&zString);
-      if( c==0 ) return 0;
-      c2 = sqlite3Utf8Read(&zPattern);
-      if( c2=='^' ){
-        invert = 1;
-        c2 = sqlite3Utf8Read(&zPattern);
-      }
-      if( c2==']' ){
-        if( c==']' ) seen = 1;
+    }
+    if( c==matchOther ){
+      if( esc ){
+        c = sqlite3Utf8Read(&zPattern);
+        if( c==0 ) return 0;
+        zEscaped = zPattern;
+      }else{
+        u32 prior_c = 0;
+        int seen = 0;
+        int invert = 0;
+        c = sqlite3Utf8Read(&zString);
+        if( c==0 ) return 0;
         c2 = sqlite3Utf8Read(&zPattern);
-      }
-      while( c2 && c2!=']' ){
-        if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){
+        if( c2=='^' ){
+          invert = 1;
           c2 = sqlite3Utf8Read(&zPattern);
-          if( c>=prior_c && c<=c2 ) seen = 1;
-          prior_c = 0;
-        }else{
-          if( c==c2 ){
-            seen = 1;
+        }
+        if( c2==']' ){
+          if( c==']' ) seen = 1;
+          c2 = sqlite3Utf8Read(&zPattern);
+        }
+        while( c2 && c2!=']' ){
+          if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){
+            c2 = sqlite3Utf8Read(&zPattern);
+            if( c>=prior_c && c<=c2 ) seen = 1;
+            prior_c = 0;
+          }else{
+            if( c==c2 ){
+              seen = 1;
+            }
+            prior_c = c2;
           }
-          prior_c = c2;
+          c2 = sqlite3Utf8Read(&zPattern);
         }
-        c2 = sqlite3Utf8Read(&zPattern);
-      }
-      if( c2==0 || (seen ^ invert)==0 ){
-        return 0;
-      }
-    }else if( esc==c && !prevEscape ){
-      prevEscape = 1;
-    }else{
-      c2 = sqlite3Utf8Read(&zString);
-      if( noCase ){
-        GlobUpperToLower(c);
-        GlobUpperToLower(c2);
-      }
-      if( c!=c2 ){
-        return 0;
+        if( c2==0 || (seen ^ invert)==0 ){
+          return 0;
+        }
+        continue;
       }
-      prevEscape = 0;
     }
+    c2 = sqlite3Utf8Read(&zString);
+    if( c==c2 ) continue;
+    if( noCase && c<0x80 && c2<0x80 && sqlite3Tolower(c)==sqlite3Tolower(c2) ){
+      continue;
+    }
+    if( c==matchOne && zPattern!=zEscaped && c2!=0 ) continue;
+    return 0;
   }
   return *zString==0;
 }
@@ -92389,7 +97186,7 @@ static int patternCompare(
 /*
 ** The sqlite3_strglob() interface.
 */
-SQLITE_API int sqlite3_strglob(const char *zGlobPattern, const char *zString){
+SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlobPattern, const char *zString){
   return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, 0)==0;
 }
 
@@ -92684,7 +97481,7 @@ static void charFunc(
 ){
   unsigned char *z, *zOut;
   int i;
-  zOut = z = sqlite3_malloc( argc*4+1 );
+  zOut = z = sqlite3_malloc64( argc*4+1 );
   if( z==0 ){
     sqlite3_result_error_nomem(context);
     return;
@@ -92711,7 +97508,7 @@ static void charFunc(
       *zOut++ = 0x80 + (u8)(c & 0x3F);
     }                                                    \
   }
-  sqlite3_result_text(context, (char*)z, (int)(zOut-z), sqlite3_free);
+  sqlite3_result_text64(context, (char*)z, zOut-z, sqlite3_free, SQLITE_UTF8);
 }
 
 /*
@@ -92832,7 +97629,7 @@ static void replaceFunc(
         return;
       }
       zOld = zOut;
-      zOut = sqlite3_realloc(zOut, (int)nOut);
+      zOut = sqlite3_realloc64(zOut, (int)nOut);
       if( zOut==0 ){
         sqlite3_result_error_nomem(context);
         sqlite3_free(zOld);
@@ -93161,6 +97958,7 @@ static void minmaxStep(
       sqlite3SkipAccumulatorLoad(context);
     }
   }else{
+    pBest->db = sqlite3_context_db_handle(context);
     sqlite3VdbeMemCopy(pBest, pArg);
   }
 }
@@ -93193,8 +97991,7 @@ static void groupConcatStep(
 
   if( pAccum ){
     sqlite3 *db = sqlite3_context_db_handle(context);
-    int firstTerm = pAccum->useMalloc==0;
-    pAccum->useMalloc = 2;
+    int firstTerm = pAccum->mxAlloc==0;
     pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH];
     if( !firstTerm ){
       if( argc==2 ){
@@ -93278,6 +98075,11 @@ SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive)
 ** then set aWc[0] through aWc[2] to the wildcard characters and
 ** return TRUE.  If the function is not a LIKE-style function then
 ** return FALSE.
+**
+** *pIsNocase is set to true if uppercase and lowercase are equivalent for
+** the function (default for LIKE).  If the function makes the distinction
+** between uppercase and lowercase (as does GLOB) then *pIsNocase is set to
+** false.
 */
 SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
   FuncDef *pDef;
@@ -93308,7 +98110,7 @@ SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocas
 }
 
 /*
-** All all of the FuncDef structures in the aBuiltinFunc[] array above
+** All of the FuncDef structures in the aBuiltinFunc[] array above
 ** to the global function hash table.  This occurs at start-time (as
 ** a consequence of calling sqlite3_initialize()).
 **
@@ -93332,10 +98134,12 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
     FUNCTION(trim,               2, 3, 0, trimFunc         ),
     FUNCTION(min,               -1, 0, 1, minmaxFunc       ),
     FUNCTION(min,                0, 0, 1, 0                ),
-    AGGREGATE(min,               1, 0, 1, minmaxStep,      minMaxFinalize ),
+    AGGREGATE2(min,              1, 0, 1, minmaxStep,      minMaxFinalize,
+                                          SQLITE_FUNC_MINMAX ),
     FUNCTION(max,               -1, 1, 1, minmaxFunc       ),
     FUNCTION(max,                0, 1, 1, 0                ),
-    AGGREGATE(max,               1, 1, 1, minmaxStep,      minMaxFinalize ),
+    AGGREGATE2(max,              1, 1, 1, minmaxStep,      minMaxFinalize,
+                                          SQLITE_FUNC_MINMAX ),
     FUNCTION2(typeof,            1, 0, 0, typeofFunc,  SQLITE_FUNC_TYPEOF),
     FUNCTION2(length,            1, 0, 0, lengthFunc,  SQLITE_FUNC_LENGTH),
     FUNCTION(instr,              2, 0, 0, instrFunc        ),
@@ -93365,6 +98169,9 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
     FUNCTION(sqlite_version,     0, 0, 0, versionFunc      ),
     FUNCTION(sqlite_source_id,   0, 0, 0, sourceidFunc     ),
     FUNCTION(sqlite_log,         2, 0, 0, errlogFunc       ),
+#if SQLITE_USER_AUTHENTICATION
+    FUNCTION(sqlite_crypt,       2, 0, 0, sqlite3CryptFunc ),
+#endif
 #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
     FUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc  ),
     FUNCTION(sqlite_compileoption_get, 1, 0, 0, compileoptiongetFunc  ),
@@ -93385,8 +98192,8 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
     AGGREGATE(sum,               1, 0, 0, sumStep,         sumFinalize    ),
     AGGREGATE(total,             1, 0, 0, sumStep,         totalFinalize    ),
     AGGREGATE(avg,               1, 0, 0, sumStep,         avgFinalize    ),
- /* AGGREGATE(count,             0, 0, 0, countStep,       countFinalize  ), */
-    {0,SQLITE_UTF8|SQLITE_FUNC_COUNT,0,0,0,countStep,countFinalize,"count",0,0},
+    AGGREGATE2(count,            0, 0, 0, countStep,       countFinalize,
+               SQLITE_FUNC_COUNT  ),
     AGGREGATE(count,             1, 0, 0, countStep,       countFinalize  ),
     AGGREGATE(group_concat,      1, 0, 0, groupConcatStep, groupConcatFinalize),
     AGGREGATE(group_concat,      2, 0, 0, groupConcatStep, groupConcatFinalize),
@@ -93593,7 +98400,7 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){
 **
 **   4) No parent key columns were provided explicitly as part of the
 **      foreign key definition, and the PRIMARY KEY of the parent table 
-**      consists of a a different number of columns to the child key in 
+**      consists of a different number of columns to the child key in 
 **      the child table.
 **
 ** then non-zero is returned, and a "foreign key mismatch" error loaded
@@ -93857,7 +98664,7 @@ static void fkLookupParent(
         OE_Abort, 0, P4_STATIC, P5_ConstraintFK);
   }else{
     if( nIncr>0 && pFKey->isDeferred==0 ){
-      sqlite3ParseToplevel(pParse)->mayAbort = 1;
+      sqlite3MayAbort(pParse);
     }
     sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
   }
@@ -93929,6 +98736,10 @@ static Expr *exprTableColumn(
 ** code for an SQL UPDATE operation, this function may be called twice -
 ** once to "delete" the old row and once to "insert" the new row.
 **
+** Parameter nIncr is passed -1 when inserting a row (as this may decrease
+** the number of FK violations in the db) or +1 when deleting one (as this
+** may increase the number of FK constraint problems).
+**
 ** The code generated by this function scans through the rows in the child
 ** table that correspond to the parent table row being deleted or inserted.
 ** For each child row found, one of the following actions is taken:
@@ -94045,13 +98856,9 @@ static void fkScanChildren(
   sqlite3ResolveExprNames(&sNameContext, pWhere);
 
   /* Create VDBE to loop through the entries in pSrc that match the WHERE
-  ** clause. If the constraint is not deferred, throw an exception for
-  ** each row found. Otherwise, for deferred constraints, increment the
-  ** deferred constraint counter by nIncr for each row selected.  */
+  ** clause. For each row found, increment either the deferred or immediate
+  ** foreign key constraint counter. */
   pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0);
-  if( nIncr>0 && pFKey->isDeferred==0 ){
-    sqlite3ParseToplevel(pParse)->mayAbort = 1;
-  }
   sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr);
   if( pWInfo ){
     sqlite3WhereEnd(pWInfo);
@@ -94079,8 +98886,7 @@ static void fkScanChildren(
 ** table).
 */
 SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *pTab){
-  int nName = sqlite3Strlen30(pTab->zName);
-  return (FKey *)sqlite3HashFind(&pTab->pSchema->fkeyHash, pTab->zName, nName);
+  return (FKey *)sqlite3HashFind(&pTab->pSchema->fkeyHash, pTab->zName);
 }
 
 /*
@@ -94232,6 +99038,24 @@ static int fkParentIsModified(
 }
 
 /*
+** Return true if the parser passed as the first argument is being
+** used to code a trigger that is really a "SET NULL" action belonging
+** to trigger pFKey.
+*/
+static int isSetNullAction(Parse *pParse, FKey *pFKey){
+  Parse *pTop = sqlite3ParseToplevel(pParse);
+  if( pTop->pTriggerPrg ){
+    Trigger *p = pTop->pTriggerPrg->pTrigger;
+    if( (p==pFKey->apTrigger[0] && pFKey->aAction[0]==OE_SetNull)
+     || (p==pFKey->apTrigger[1] && pFKey->aAction[1]==OE_SetNull)
+    ){
+      return 1;
+    }
+  }
+  return 0;
+}
+
+/*
 ** This function is called when inserting, deleting or updating a row of
 ** table pTab to generate VDBE code to perform foreign key constraint 
 ** processing for the operation.
@@ -94283,7 +99107,7 @@ SQLITE_PRIVATE void sqlite3FkCheck(
     int *aiCol;
     int iCol;
     int i;
-    int isIgnore = 0;
+    int bIgnore = 0;
 
     if( aChange 
      && sqlite3_stricmp(pTab->zName, pFKey->zTo)!=0
@@ -94342,7 +99166,7 @@ SQLITE_PRIVATE void sqlite3FkCheck(
         int rcauth;
         char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zName;
         rcauth = sqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb);
-        isIgnore = (rcauth==SQLITE_IGNORE);
+        bIgnore = (rcauth==SQLITE_IGNORE);
       }
 #endif
     }
@@ -94357,12 +99181,18 @@ SQLITE_PRIVATE void sqlite3FkCheck(
       /* A row is being removed from the child table. Search for the parent.
       ** If the parent does not exist, removing the child row resolves an 
       ** outstanding foreign key constraint violation. */
-      fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1,isIgnore);
+      fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1, bIgnore);
     }
-    if( regNew!=0 ){
+    if( regNew!=0 && !isSetNullAction(pParse, pFKey) ){
       /* A row is being added to the child table. If a parent row cannot
-      ** be found, adding the child row has violated the FK constraint. */ 
-      fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1,isIgnore);
+      ** be found, adding the child row has violated the FK constraint. 
+      **
+      ** If this operation is being performed as part of a trigger program
+      ** that is actually a "SET NULL" action belonging to this very 
+      ** foreign key, then omit this scan altogether. As all child key
+      ** values are guaranteed to be NULL, it is not possible for adding
+      ** this row to cause an FK violation.  */
+      fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1, bIgnore);
     }
 
     sqlite3DbFree(db, aiFree);
@@ -94383,8 +99213,8 @@ SQLITE_PRIVATE void sqlite3FkCheck(
      && !pParse->pToplevel && !pParse->isMultiWrite 
     ){
       assert( regOld==0 && regNew!=0 );
-      /* Inserting a single row into a parent table cannot cause an immediate
-      ** foreign key violation. So do nothing in this case.  */
+      /* Inserting a single row into a parent table cannot cause (or fix)
+      ** an immediate foreign key violation. So do nothing in this case.  */
       continue;
     }
 
@@ -94408,13 +99238,28 @@ SQLITE_PRIVATE void sqlite3FkCheck(
         fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1);
       }
       if( regOld!=0 ){
-        /* If there is a RESTRICT action configured for the current operation
-        ** on the parent table of this FK, then throw an exception 
-        ** immediately if the FK constraint is violated, even if this is a
-        ** deferred trigger. That's what RESTRICT means. To defer checking
-        ** the constraint, the FK should specify NO ACTION (represented
-        ** using OE_None). NO ACTION is the default.  */
+        int eAction = pFKey->aAction[aChange!=0];
         fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1);
+        /* If this is a deferred FK constraint, or a CASCADE or SET NULL
+        ** action applies, then any foreign key violations caused by
+        ** removing the parent key will be rectified by the action trigger.
+        ** So do not set the "may-abort" flag in this case.
+        **
+        ** Note 1: If the FK is declared "ON UPDATE CASCADE", then the
+        ** may-abort flag will eventually be set on this statement anyway
+        ** (when this function is called as part of processing the UPDATE
+        ** within the action trigger).
+        **
+        ** Note 2: At first glance it may seem like SQLite could simply omit
+        ** all OP_FkCounter related scans when either CASCADE or SET NULL
+        ** applies. The trouble starts if the CASCADE or SET NULL action 
+        ** trigger causes other triggers or action rules attached to the 
+        ** child table to fire. In these cases the fk constraint counters
+        ** might be set incorrectly if any OP_FkCounter related scans are 
+        ** omitted.  */
+        if( !pFKey->isDeferred && eAction!=OE_Cascade && eAction!=OE_SetNull ){
+          sqlite3MayAbort(pParse);
+        }
       }
       pItem->zName = 0;
       sqlite3SrcListDelete(db, pSrc);
@@ -94566,7 +99411,8 @@ static Trigger *fkActionTrigger(
 
       iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
       assert( iFromCol>=0 );
-      tToCol.z = pIdx ? pTab->aCol[pIdx->aiColumn[i]].zName : "oid";
+      assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKey<pTab->nCol) );
+      tToCol.z = pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName;
       tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName;
 
       tToCol.n = sqlite3Strlen30(tToCol.z);
@@ -94578,10 +99424,10 @@ static Trigger *fkActionTrigger(
       ** parent table are used for the comparison. */
       pEq = sqlite3PExpr(pParse, TK_EQ,
           sqlite3PExpr(pParse, TK_DOT, 
-            sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld),
-            sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
+            sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
+            sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
           , 0),
-          sqlite3PExpr(pParse, TK_ID, 0, 0, &tFromCol)
+          sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
       , 0);
       pWhere = sqlite3ExprAnd(db, pWhere, pEq);
 
@@ -94593,12 +99439,12 @@ static Trigger *fkActionTrigger(
       if( pChanges ){
         pEq = sqlite3PExpr(pParse, TK_IS,
             sqlite3PExpr(pParse, TK_DOT, 
-              sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld),
-              sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
+              sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
+              sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
               0),
             sqlite3PExpr(pParse, TK_DOT, 
-              sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
-              sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
+              sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
+              sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
               0),
             0);
         pWhen = sqlite3ExprAnd(db, pWhen, pEq);
@@ -94608,8 +99454,8 @@ static Trigger *fkActionTrigger(
         Expr *pNew;
         if( action==OE_Cascade ){
           pNew = sqlite3PExpr(pParse, TK_DOT, 
-            sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
-            sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
+            sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
+            sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
           , 0);
         }else if( action==OE_SetDflt ){
           Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
@@ -94656,13 +99502,12 @@ static Trigger *fkActionTrigger(
     pTrigger = (Trigger *)sqlite3DbMallocZero(db, 
         sizeof(Trigger) +         /* struct Trigger */
         sizeof(TriggerStep) +     /* Single step in trigger program */
-        nFrom + 1                 /* Space for pStep->target.z */
+        nFrom + 1                 /* Space for pStep->zTarget */
     );
     if( pTrigger ){
       pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1];
-      pStep->target.z = (char *)&pStep[1];
-      pStep->target.n = nFrom;
-      memcpy((char *)pStep->target.z, zFrom, nFrom);
+      pStep->zTarget = (char *)&pStep[1];
+      memcpy((char *)pStep->zTarget, zFrom, nFrom);
   
       pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
       pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE);
@@ -94758,7 +99603,7 @@ SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *db, Table *pTab){
       }else{
         void *p = (void *)pFKey->pNextTo;
         const char *z = (p ? pFKey->pNextTo->zTo : pFKey->zTo);
-        sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, sqlite3Strlen30(z), p);
+        sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, p);
       }
       if( pFKey->pNextTo ){
         pFKey->pNextTo->pPrevTo = pFKey->pPrevTo;
@@ -94841,13 +99686,13 @@ SQLITE_PRIVATE void sqlite3OpenTable(
 **
 **  Character      Column affinity
 **  ------------------------------
-**  'a'            TEXT
-**  'b'            NONE
-**  'c'            NUMERIC
-**  'd'            INTEGER
-**  'e'            REAL
+**  'A'            NONE
+**  'B'            TEXT
+**  'C'            NUMERIC
+**  'D'            INTEGER
+**  'F'            REAL
 **
-** An extra 'd' is appended to the end of the string to cover the
+** An extra 'D' is appended to the end of the string to cover the
 ** rowid that appears as the last column in every index.
 **
 ** Memory for the buffer containing the column index affinity string
@@ -94896,11 +99741,11 @@ SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){
 **
 **  Character      Column affinity
 **  ------------------------------
-**  'a'            TEXT
-**  'b'            NONE
-**  'c'            NUMERIC
-**  'd'            INTEGER
-**  'e'            REAL
+**  'A'            NONE
+**  'B'            TEXT
+**  'C'            NUMERIC
+**  'D'            INTEGER
+**  'E'            REAL
 */
 SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
   int i;
@@ -95127,20 +99972,23 @@ static int xferOptimization(
 /*
 ** This routine is called to handle SQL of the following forms:
 **
-**    insert into TABLE (IDLIST) values(EXPRLIST)
+**    insert into TABLE (IDLIST) values(EXPRLIST),(EXPRLIST),...
 **    insert into TABLE (IDLIST) select
+**    insert into TABLE (IDLIST) default values
 **
 ** The IDLIST following the table name is always optional.  If omitted,
-** then a list of all columns for the table is substituted.  The IDLIST
-** appears in the pColumn parameter.  pColumn is NULL if IDLIST is omitted.
+** then a list of all (non-hidden) columns for the table is substituted.
+** The IDLIST appears in the pColumn parameter.  pColumn is NULL if IDLIST
+** is omitted.
 **
-** The pList parameter holds EXPRLIST in the first form of the INSERT
-** statement above, and pSelect is NULL.  For the second form, pList is
-** NULL and pSelect is a pointer to the select statement used to generate
-** data for the insert.
+** For the pSelect parameter holds the values to be inserted for the
+** first two forms shown above.  A VALUES clause is really just short-hand
+** for a SELECT statement that omits the FROM clause and everything else
+** that follows.  If the pSelect parameter is NULL, that means that the
+** DEFAULT VALUES form of the INSERT statement is intended.
 **
 ** The code generated follows one of four templates.  For a simple
-** insert with data coming from a VALUES clause, the code executes
+** insert with data coming from a single-row VALUES clause, the code executes
 ** once straight down through.  Pseudo-code follows (we call this
 ** the "1st template"):
 **
@@ -95195,7 +100043,7 @@ static int xferOptimization(
 ** The 4th template is used if the insert statement takes its
 ** values from a SELECT but the data is being inserted into a table
 ** that is also read as part of the SELECT.  In the third form,
-** we have to use a intermediate table to store the results of
+** we have to use an intermediate table to store the results of
 ** the select.  The template is like this:
 **
 **         X <- A
@@ -95247,7 +100095,7 @@ SQLITE_PRIVATE void sqlite3Insert(
   u8 useTempTable = 0;  /* Store SELECT results in intermediate table */
   u8 appendFlag = 0;    /* True if the insert is likely to be an append */
   u8 withoutRowid;      /* 0 for normal table.  1 for WITHOUT ROWID table */
-  u8 bIdListInOrder = 1; /* True if IDLIST is in table order */
+  u8 bIdListInOrder;    /* True if IDLIST is in table order */
   ExprList *pList = 0;  /* List of VALUES() to be inserted  */
 
   /* Register allocations */
@@ -95272,8 +100120,8 @@ SQLITE_PRIVATE void sqlite3Insert(
   }
 
   /* If the Select object is really just a simple VALUES() list with a
-  ** single row values (the common case) then keep that one row of values
-  ** and go ahead and discard the Select object
+  ** single row (the common case) then keep that one row of values
+  ** and discard the other (unused) parts of the pSelect object
   */
   if( pSelect && (pSelect->selFlags & SF_Values)!=0 && pSelect->pPrior==0 ){
     pList = pSelect->pEList;
@@ -95360,7 +100208,7 @@ SQLITE_PRIVATE void sqlite3Insert(
   regAutoinc = autoIncBegin(pParse, iDb, pTab);
 
   /* Allocate registers for holding the rowid of the new row,
-  ** the content of the new row, and the assemblied row record.
+  ** the content of the new row, and the assembled row record.
   */
   regRowid = regIns = pParse->nMem+1;
   pParse->nMem += pTab->nCol + 1;
@@ -95381,6 +100229,7 @@ SQLITE_PRIVATE void sqlite3Insert(
   ** is appears in the original table.  (The index of the INTEGER
   ** PRIMARY KEY in the original table is pTab->iPKey.)
   */
+  bIdListInOrder = (pTab->tabFlags & TF_OOOHidden)==0;
   if( pColumn ){
     for(i=0; i<pColumn->nId; i++){
       pColumn->a[i].idx = -1;
@@ -95416,7 +100265,8 @@ SQLITE_PRIVATE void sqlite3Insert(
   ** co-routine is the common header to the 3rd and 4th templates.
   */
   if( pSelect ){
-    /* Data is coming from a SELECT.  Generate a co-routine to run the SELECT */
+    /* Data is coming from a SELECT or from a multi-row VALUES clause.
+    ** Generate a co-routine to run the SELECT. */
     int regYield;       /* Register holding co-routine entry-point */
     int addrTop;        /* Top of the co-routine */
     int rc;             /* Result code */
@@ -95429,8 +100279,7 @@ SQLITE_PRIVATE void sqlite3Insert(
     dest.nSdst = pTab->nCol;
     rc = sqlite3Select(pParse, pSelect, &dest);
     regFromSelect = dest.iSdst;
-    assert( pParse->nErr==0 || rc );
-    if( rc || db->mallocFailed ) goto insert_cleanup;
+    if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup;
     sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
     sqlite3VdbeJumpHere(v, addrTop - 1);                       /* label B: */
     assert( pSelect->pEList );
@@ -95478,8 +100327,8 @@ SQLITE_PRIVATE void sqlite3Insert(
       sqlite3ReleaseTempReg(pParse, regTempRowid);
     }
   }else{
-    /* This is the case if the data for the INSERT is coming from a VALUES
-    ** clause
+    /* This is the case if the data for the INSERT is coming from a 
+    ** single-row VALUES clause
     */
     NameContext sNC;
     memset(&sNC, 0, sizeof(sNC));
@@ -95812,7 +100661,7 @@ insert_cleanup:
 }
 
 /* Make sure "isView" and other macros defined above are undefined. Otherwise
-** thely may interfere with compilation of other functions in this file
+** they may interfere with compilation of other functions in this file
 ** (or in another file, if this file becomes part of the amalgamation).  */
 #ifdef isView
  #undef isView
@@ -95928,7 +100777,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(
   int ix;              /* Index loop counter */
   int nCol;            /* Number of columns */
   int onError;         /* Conflict resolution strategy */
-  int j1;              /* Addresss of jump instruction */
+  int j1;              /* Address of jump instruction */
   int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
   int nPkField;        /* Number of fields in PRIMARY KEY. 1 for ROWID tables */
   int ipkTop = 0;      /* Top of the rowid change constraint check */
@@ -96332,7 +101181,7 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
   Index *pIdx;        /* An index being inserted or updated */
   u8 pik_flags;       /* flag values passed to the btree insert */
   int regData;        /* Content registers (after the rowid) */
-  int regRec;         /* Register holding assemblied record for the table */
+  int regRec;         /* Register holding assembled record for the table */
   int i;              /* Loop counter */
   u8 bAffinityDone = 0; /* True if OP_Affinity has been run already */
 
@@ -96397,6 +101246,9 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion(
 ** For a WITHOUT ROWID table, *piDataCur will be somewhere in the range
 ** of *piIdxCurs, depending on where the PRIMARY KEY index appears on the
 ** pTab->pIndex list.
+**
+** If pTab is a virtual table, then this routine is a no-op and the
+** *piDataCur and *piIdxCur values are left uninitialized.
 */
 SQLITE_PRIVATE int sqlite3OpenTableAndIndices(
   Parse *pParse,   /* Parsing context */
@@ -96415,9 +101267,9 @@ SQLITE_PRIVATE int sqlite3OpenTableAndIndices(
 
   assert( op==OP_OpenRead || op==OP_OpenWrite );
   if( IsVirtual(pTab) ){
-    assert( aToOpen==0 );
-    *piDataCur = 0;
-    *piIdxCur = 1;
+    /* This routine is a no-op for virtual tables. Leave the output
+    ** variables *piDataCur and *piIdxCur uninitialized so that valgrind
+    ** can detect if they are used by mistake in the caller. */
     return 0;
   }
   iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
@@ -96454,7 +101306,7 @@ SQLITE_PRIVATE int sqlite3OpenTableAndIndices(
 ** The following global variable is incremented whenever the
 ** transfer optimization is used.  This is used for testing
 ** purposes only - to make sure the transfer optimization really
-** is happening when it is suppose to.
+** is happening when it is supposed to.
 */
 SQLITE_API int sqlite3_xferopt_count;
 #endif /* SQLITE_TEST */
@@ -96521,7 +101373,7 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){
 **     INSERT INTO tab1 SELECT * FROM tab2;
 **
 ** The xfer optimization transfers raw records from tab2 over to tab1.  
-** Columns are not decoded and reassemblied, which greatly improves
+** Columns are not decoded and reassembled, which greatly improves
 ** performance.  Raw index records are transferred in the same way.
 **
 ** The xfer optimization is only attempted if tab1 and tab2 are compatible.
@@ -96547,6 +101399,7 @@ static int xferOptimization(
   int onError,          /* How to handle constraint errors */
   int iDbDest           /* The database of pDest */
 ){
+  sqlite3 *db = pParse->db;
   ExprList *pEList;                /* The result set of the SELECT */
   Table *pSrc;                     /* The table in the FROM clause of SELECT */
   Index *pSrcIdx, *pDestIdx;       /* Source and destination indices */
@@ -96694,11 +101547,11 @@ static int xferOptimization(
   ** the extra complication to make this rule less restrictive is probably
   ** not worth the effort.  Ticket [6284df89debdfa61db8073e062908af0c9b6118e]
   */
-  if( (pParse->db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){
+  if( (db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){
     return 0;
   }
 #endif
-  if( (pParse->db->flags & SQLITE_CountRows)!=0 ){
+  if( (db->flags & SQLITE_CountRows)!=0 ){
     return 0;  /* xfer opt does not play well with PRAGMA count_changes */
   }
 
@@ -96709,7 +101562,7 @@ static int xferOptimization(
 #ifdef SQLITE_TEST
   sqlite3_xferopt_count++;
 #endif
-  iDbSrc = sqlite3SchemaToIndex(pParse->db, pSrc->pSchema);
+  iDbSrc = sqlite3SchemaToIndex(db, pSrc->pSchema);
   v = sqlite3GetVdbe(pParse);
   sqlite3CodeVerifySchema(pParse, iDbSrc);
   iSrc = pParse->nTab++;
@@ -96719,14 +101572,18 @@ static int xferOptimization(
   regRowid = sqlite3GetTempReg(pParse);
   sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite);
   assert( HasRowid(pDest) || destHasUniqueIdx );
-  if( (pDest->iPKey<0 && pDest->pIndex!=0)          /* (1) */
+  if( (db->flags & SQLITE_Vacuum)==0 && (
+      (pDest->iPKey<0 && pDest->pIndex!=0)          /* (1) */
    || destHasUniqueIdx                              /* (2) */
    || (onError!=OE_Abort && onError!=OE_Rollback)   /* (3) */
-  ){
+  )){
     /* In some circumstances, we are able to run the xfer optimization
-    ** only if the destination table is initially empty.  This code makes
-    ** that determination.  Conditions under which the destination must
-    ** be empty:
+    ** only if the destination table is initially empty. Unless the
+    ** SQLITE_Vacuum flag is set, this block generates code to make
+    ** that determination. If SQLITE_Vacuum is set, then the destination
+    ** table is always empty.
+    **
+    ** Conditions under which the destination must be empty:
     **
     ** (1) There is no INTEGER PRIMARY KEY but there are indices.
     **     (If the destination is not initially empty, the rowid fields
@@ -96769,6 +101626,7 @@ static int xferOptimization(
     sqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName);
   }
   for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
+    u8 useSeekResult = 0;
     for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){
       if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
     }
@@ -96782,7 +101640,33 @@ static int xferOptimization(
     VdbeComment((v, "%s", pDestIdx->zName));
     addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v);
     sqlite3VdbeAddOp2(v, OP_RowKey, iSrc, regData);
+    if( db->flags & SQLITE_Vacuum ){
+      /* This INSERT command is part of a VACUUM operation, which guarantees
+      ** that the destination table is empty. If all indexed columns use
+      ** collation sequence BINARY, then it can also be assumed that the
+      ** index will be populated by inserting keys in strictly sorted 
+      ** order. In this case, instead of seeking within the b-tree as part
+      ** of every OP_IdxInsert opcode, an OP_Last is added before the
+      ** OP_IdxInsert to seek to the point within the b-tree where each key 
+      ** should be inserted. This is faster.
+      **
+      ** If any of the indexed columns use a collation sequence other than
+      ** BINARY, this optimization is disabled. This is because the user 
+      ** might change the definition of a collation sequence and then run
+      ** a VACUUM command. In that case keys may not be written in strictly
+      ** sorted order.  */
+      for(i=0; i<pSrcIdx->nColumn; i++){
+        char *zColl = pSrcIdx->azColl[i];
+        assert( zColl!=0 );
+        if( sqlite3_stricmp("BINARY", zColl) ) break;
+      }
+      if( i==pSrcIdx->nColumn ){
+        useSeekResult = OPFLAG_USESEEKRESULT;
+        sqlite3VdbeAddOp3(v, OP_Last, iDest, 0, -1);
+      }
+    }
     sqlite3VdbeAddOp3(v, OP_IdxInsert, iDest, regData, 1);
+    sqlite3VdbeChangeP5(v, useSeekResult);
     sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v);
     sqlite3VdbeJumpHere(v, addr1);
     sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
@@ -96832,7 +101716,7 @@ static int xferOptimization(
 ** argument to xCallback().  If xCallback=NULL then no callback
 ** is invoked, even for queries.
 */
-SQLITE_API int sqlite3_exec(
+SQLITE_API int SQLITE_STDCALL sqlite3_exec(
   sqlite3 *db,                /* The database on which the SQL executes */
   const char *zSql,           /* The SQL to be executed */
   sqlite3_callback xCallback, /* Invoke this callback routine */
@@ -96849,7 +101733,7 @@ SQLITE_API int sqlite3_exec(
   if( zSql==0 ) zSql = "";
 
   sqlite3_mutex_enter(db->mutex);
-  sqlite3Error(db, SQLITE_OK, 0);
+  sqlite3Error(db, SQLITE_OK);
   while( rc==SQLITE_OK && zSql[0] ){
     int nCol;
     char **azVals = 0;
@@ -96907,7 +101791,7 @@ SQLITE_API int sqlite3_exec(
           rc = SQLITE_ABORT;
           sqlite3VdbeFinalize((Vdbe *)pStmt);
           pStmt = 0;
-          sqlite3Error(db, SQLITE_ABORT, 0);
+          sqlite3Error(db, SQLITE_ABORT);
           goto exec_out;
         }
       }
@@ -96930,14 +101814,14 @@ exec_out:
   sqlite3DbFree(db, azCols);
 
   rc = sqlite3ApiExit(db, rc);
-  if( rc!=SQLITE_OK && ALWAYS(rc==sqlite3_errcode(db)) && pzErrMsg ){
+  if( rc!=SQLITE_OK && pzErrMsg ){
     int nErrMsg = 1 + sqlite3Strlen30(sqlite3_errmsg(db));
     *pzErrMsg = sqlite3Malloc(nErrMsg);
     if( *pzErrMsg ){
       memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg);
     }else{
       rc = SQLITE_NOMEM;
-      sqlite3Error(db, SQLITE_NOMEM, 0);
+      sqlite3Error(db, SQLITE_NOMEM);
     }
   }else if( pzErrMsg ){
     *pzErrMsg = 0;
@@ -96999,7 +101883,7 @@ typedef struct sqlite3_api_routines sqlite3_api_routines;
 ** WARNING:  In order to maintain backwards compatibility, add new
 ** interfaces to the end of this structure only.  If you insert new
 ** interfaces in the middle of this structure, then older different
-** versions of SQLite will not be able to load each others' shared
+** versions of SQLite will not be able to load each other's shared
 ** libraries!
 */
 struct sqlite3_api_routines {
@@ -97221,11 +102105,28 @@ struct sqlite3_api_routines {
   const char *(*uri_parameter)(const char*,const char*);
   char *(*vsnprintf)(int,char*,const char*,va_list);
   int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
+  /* Version 3.8.7 and later */
+  int (*auto_extension)(void(*)(void));
+  int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64,
+                     void(*)(void*));
+  int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64,
+                      void(*)(void*),unsigned char);
+  int (*cancel_auto_extension)(void(*)(void));
+  int (*load_extension)(sqlite3*,const char*,const char*,char**);
+  void *(*malloc64)(sqlite3_uint64);
+  sqlite3_uint64 (*msize)(void*);
+  void *(*realloc64)(void*,sqlite3_uint64);
+  void (*reset_auto_extension)(void);
+  void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64,
+                        void(*)(void*));
+  void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
+                         void(*)(void*), unsigned char);
+  int (*strglob)(const char*,const char*);
 };
 
 /*
 ** The following macros redefine the API routines so that they are
-** redirected throught the global sqlite3_api structure.
+** redirected through the global sqlite3_api structure.
 **
 ** This header file is also used by the loadext.c source file
 ** (part of the main SQLite library - not an extension) so that
@@ -97438,6 +102339,19 @@ struct sqlite3_api_routines {
 #define sqlite3_uri_parameter          sqlite3_api->uri_parameter
 #define sqlite3_uri_vsnprintf          sqlite3_api->vsnprintf
 #define sqlite3_wal_checkpoint_v2      sqlite3_api->wal_checkpoint_v2
+/* Version 3.8.7 and later */
+#define sqlite3_auto_extension         sqlite3_api->auto_extension
+#define sqlite3_bind_blob64            sqlite3_api->bind_blob64
+#define sqlite3_bind_text64            sqlite3_api->bind_text64
+#define sqlite3_cancel_auto_extension  sqlite3_api->cancel_auto_extension
+#define sqlite3_load_extension         sqlite3_api->load_extension
+#define sqlite3_malloc64               sqlite3_api->malloc64
+#define sqlite3_msize                  sqlite3_api->msize
+#define sqlite3_realloc64              sqlite3_api->realloc64
+#define sqlite3_reset_auto_extension   sqlite3_api->reset_auto_extension
+#define sqlite3_result_blob64          sqlite3_api->result_blob64
+#define sqlite3_result_text64          sqlite3_api->result_text64
+#define sqlite3_strglob                sqlite3_api->strglob
 #endif /* SQLITE_CORE */
 
 #ifndef SQLITE_CORE
@@ -97475,7 +102389,6 @@ struct sqlite3_api_routines {
 # define sqlite3_column_table_name16    0
 # define sqlite3_column_origin_name     0
 # define sqlite3_column_origin_name16   0
-# define sqlite3_table_column_metadata  0
 #endif
 
 #ifdef SQLITE_OMIT_AUTHORIZATION
@@ -97831,7 +102744,20 @@ static const sqlite3_api_routines sqlite3Apis = {
   sqlite3_uri_int64,
   sqlite3_uri_parameter,
   sqlite3_vsnprintf,
-  sqlite3_wal_checkpoint_v2
+  sqlite3_wal_checkpoint_v2,
+  /* Version 3.8.7 and later */
+  sqlite3_auto_extension,
+  sqlite3_bind_blob64,
+  sqlite3_bind_text64,
+  sqlite3_cancel_auto_extension,
+  sqlite3_load_extension,
+  sqlite3_malloc64,
+  sqlite3_msize,
+  sqlite3_realloc64,
+  sqlite3_reset_auto_extension,
+  sqlite3_result_blob64,
+  sqlite3_result_text64,
+  sqlite3_strglob
 };
 
 /*
@@ -97859,7 +102785,7 @@ static int sqlite3LoadExtension(
   const char *zEntry;
   char *zAltEntry = 0;
   void **aHandle;
-  int nMsg = 300 + sqlite3Strlen30(zFile);
+  u64 nMsg = 300 + sqlite3Strlen30(zFile);
   int ii;
 
   /* Shared library endings to try if zFile cannot be loaded as written */
@@ -97902,7 +102828,7 @@ static int sqlite3LoadExtension(
 #endif
   if( handle==0 ){
     if( pzErrMsg ){
-      *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
+      *pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg);
       if( zErrmsg ){
         sqlite3_snprintf(nMsg, zErrmsg, 
             "unable to open shared library [%s]", zFile);
@@ -97928,7 +102854,7 @@ static int sqlite3LoadExtension(
   if( xInit==0 && zProc==0 ){
     int iFile, iEntry, c;
     int ncFile = sqlite3Strlen30(zFile);
-    zAltEntry = sqlite3_malloc(ncFile+30);
+    zAltEntry = sqlite3_malloc64(ncFile+30);
     if( zAltEntry==0 ){
       sqlite3OsDlClose(pVfs, handle);
       return SQLITE_NOMEM;
@@ -97950,7 +102876,7 @@ static int sqlite3LoadExtension(
   if( xInit==0 ){
     if( pzErrMsg ){
       nMsg += sqlite3Strlen30(zEntry);
-      *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
+      *pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg);
       if( zErrmsg ){
         sqlite3_snprintf(nMsg, zErrmsg,
             "no entry point [%s] in shared library [%s]", zEntry, zFile);
@@ -97985,7 +102911,7 @@ static int sqlite3LoadExtension(
   db->aExtension[db->nExtension++] = handle;
   return SQLITE_OK;
 }
-SQLITE_API int sqlite3_load_extension(
+SQLITE_API int SQLITE_STDCALL sqlite3_load_extension(
   sqlite3 *db,          /* Load the extension into this database connection */
   const char *zFile,    /* Name of the shared library containing extension */
   const char *zProc,    /* Entry point.  Use "sqlite3_extension_init" if 0 */
@@ -98016,7 +102942,7 @@ SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3 *db){
 ** Enable or disable extension loading.  Extension loading is disabled by
 ** default so as not to open security holes in older applications.
 */
-SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff){
+SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff){
   sqlite3_mutex_enter(db->mutex);
   if( onoff ){
     db->flags |= SQLITE_LoadExtension;
@@ -98049,7 +102975,7 @@ static const sqlite3_api_routines sqlite3Apis = { 0 };
 */
 typedef struct sqlite3AutoExtList sqlite3AutoExtList;
 static SQLITE_WSD struct sqlite3AutoExtList {
-  int nExt;              /* Number of entries in aExt[] */          
+  u32 nExt;              /* Number of entries in aExt[] */          
   void (**aExt)(void);   /* Pointers to the extension init functions */
 } sqlite3Autoext = { 0, 0 };
 
@@ -98073,7 +102999,7 @@ static SQLITE_WSD struct sqlite3AutoExtList {
 ** Register a statically linked extension that is automatically
 ** loaded by every new database connection.
 */
-SQLITE_API int sqlite3_auto_extension(void (*xInit)(void)){
+SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xInit)(void)){
   int rc = SQLITE_OK;
 #ifndef SQLITE_OMIT_AUTOINIT
   rc = sqlite3_initialize();
@@ -98082,7 +103008,7 @@ SQLITE_API int sqlite3_auto_extension(void (*xInit)(void)){
   }else
 #endif
   {
-    int i;
+    u32 i;
 #if SQLITE_THREADSAFE
     sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
 #endif
@@ -98092,9 +103018,9 @@ SQLITE_API int sqlite3_auto_extension(void (*xInit)(void)){
       if( wsdAutoext.aExt[i]==xInit ) break;
     }
     if( i==wsdAutoext.nExt ){
-      int nByte = (wsdAutoext.nExt+1)*sizeof(wsdAutoext.aExt[0]);
+      u64 nByte = (wsdAutoext.nExt+1)*sizeof(wsdAutoext.aExt[0]);
       void (**aNew)(void);
-      aNew = sqlite3_realloc(wsdAutoext.aExt, nByte);
+      aNew = sqlite3_realloc64(wsdAutoext.aExt, nByte);
       if( aNew==0 ){
         rc = SQLITE_NOMEM;
       }else{
@@ -98118,7 +103044,7 @@ SQLITE_API int sqlite3_auto_extension(void (*xInit)(void)){
 ** Return 1 if xInit was found on the list and removed.  Return 0 if xInit
 ** was not on the list.
 */
-SQLITE_API int sqlite3_cancel_auto_extension(void (*xInit)(void)){
+SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void (*xInit)(void)){
 #if SQLITE_THREADSAFE
   sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
 #endif
@@ -98126,7 +103052,7 @@ SQLITE_API int sqlite3_cancel_auto_extension(void (*xInit)(void)){
   int n = 0;
   wsdAutoextInit;
   sqlite3_mutex_enter(mutex);
-  for(i=wsdAutoext.nExt-1; i>=0; i--){
+  for(i=(int)wsdAutoext.nExt-1; i>=0; i--){
     if( wsdAutoext.aExt[i]==xInit ){
       wsdAutoext.nExt--;
       wsdAutoext.aExt[i] = wsdAutoext.aExt[wsdAutoext.nExt];
@@ -98141,7 +103067,7 @@ SQLITE_API int sqlite3_cancel_auto_extension(void (*xInit)(void)){
 /*
 ** Reset the automatic extension loading mechanism.
 */
-SQLITE_API void sqlite3_reset_auto_extension(void){
+SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void){
 #ifndef SQLITE_OMIT_AUTOINIT
   if( sqlite3_initialize()==SQLITE_OK )
 #endif
@@ -98164,7 +103090,7 @@ SQLITE_API void sqlite3_reset_auto_extension(void){
 ** If anything goes wrong, set an error in the database connection.
 */
 SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
-  int i;
+  u32 i;
   int go = 1;
   int rc;
   int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
@@ -98190,7 +103116,7 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
     sqlite3_mutex_leave(mutex);
     zErrmsg = 0;
     if( xInit && (rc = xInit(db, &zErrmsg, &sqlite3Apis))!=0 ){
-      sqlite3Error(db, rc,
+      sqlite3ErrorWithMsg(db, rc,
             "automatic extension loading failed: %s", zErrmsg);
       go = 0;
     }
@@ -98223,11 +103149,18 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
 #endif
 
 /***************************************************************************
-** The next block of code, including the PragTyp_XXXX macro definitions and
-** the aPragmaName[] object is composed of generated code. DO NOT EDIT.
-**
-** To add new pragmas, edit the code in ../tool/mkpragmatab.tcl and rerun
-** that script.  Then copy/paste the output in place of the following:
+** The "pragma.h" include file is an automatically generated file that
+** that includes the PragType_XXXX macro definitions and the aPragmaName[]
+** object.  This ensures that the aPragmaName[] table is arranged in
+** lexicographical order to facility a binary search of the pragma name.
+** Do not edit pragma.h directly.  Edit and rerun the script in at 
+** ../tool/mkpragmatab.tcl. */
+/************** Include pragma.h in the middle of pragma.c *******************/
+/************** Begin file pragma.h ******************************************/
+/* DO NOT EDIT!
+** This file is automatically generated by the script at
+** ../tool/mkpragmatab.tcl.  To update the set of pragmas, edit
+** that script and rerun it.
 */
 #define PragTyp_HEADER_VALUE                   0
 #define PragTyp_AUTO_VACUUM                    1
@@ -98262,15 +103195,17 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){
 #define PragTyp_TABLE_INFO                    30
 #define PragTyp_TEMP_STORE                    31
 #define PragTyp_TEMP_STORE_DIRECTORY          32
-#define PragTyp_WAL_AUTOCHECKPOINT            33
-#define PragTyp_WAL_CHECKPOINT                34
-#define PragTyp_ACTIVATE_EXTENSIONS           35
-#define PragTyp_HEXKEY                        36
-#define PragTyp_KEY                           37
-#define PragTyp_REKEY                         38
-#define PragTyp_LOCK_STATUS                   39
-#define PragTyp_PARSER_TRACE                  40
+#define PragTyp_THREADS                       33
+#define PragTyp_WAL_AUTOCHECKPOINT            34
+#define PragTyp_WAL_CHECKPOINT                35
+#define PragTyp_ACTIVATE_EXTENSIONS           36
+#define PragTyp_HEXKEY                        37
+#define PragTyp_KEY                           38
+#define PragTyp_REKEY                         39
+#define PragTyp_LOCK_STATUS                   40
+#define PragTyp_PARSER_TRACE                  41
 #define PragFlag_NeedSchema           0x01
+#define PragFlag_ReadOnly             0x02
 static const struct sPragmaNames {
   const char *const zName;  /* Name of pragma */
   u8 ePragTyp;              /* PragTyp_XXX value */
@@ -98287,7 +103222,7 @@ static const struct sPragmaNames {
   { /* zName:     */ "application_id",
     /* ePragTyp:  */ PragTyp_HEADER_VALUE,
     /* ePragFlag: */ 0,
-    /* iArg:      */ 0 },
+    /* iArg:      */ BTREE_APPLICATION_ID },
 #endif
 #if !defined(SQLITE_OMIT_AUTOVACUUM)
   { /* zName:     */ "auto_vacuum",
@@ -98353,6 +103288,12 @@ static const struct sPragmaNames {
     /* ePragFlag: */ 0,
     /* iArg:      */ 0 },
 #endif
+#if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
+  { /* zName:     */ "data_version",
+    /* ePragTyp:  */ PragTyp_HEADER_VALUE,
+    /* ePragFlag: */ PragFlag_ReadOnly,
+    /* iArg:      */ BTREE_DATA_VERSION },
+#endif
 #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
   { /* zName:     */ "database_list",
     /* ePragTyp:  */ PragTyp_DATABASE_LIST,
@@ -98408,8 +103349,8 @@ static const struct sPragmaNames {
 #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
   { /* zName:     */ "freelist_count",
     /* ePragTyp:  */ PragTyp_HEADER_VALUE,
-    /* ePragFlag: */ 0,
-    /* iArg:      */ 0 },
+    /* ePragFlag: */ PragFlag_ReadOnly,
+    /* iArg:      */ BTREE_FREE_PAGE_COUNT },
 #endif
 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
   { /* zName:     */ "full_column_names",
@@ -98454,6 +103395,10 @@ static const struct sPragmaNames {
     /* ePragTyp:  */ PragTyp_INDEX_LIST,
     /* ePragFlag: */ PragFlag_NeedSchema,
     /* iArg:      */ 0 },
+  { /* zName:     */ "index_xinfo",
+    /* ePragTyp:  */ PragTyp_INDEX_INFO,
+    /* ePragFlag: */ PragFlag_NeedSchema,
+    /* iArg:      */ 1 },
 #endif
 #if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
   { /* zName:     */ "integrity_check",
@@ -98561,7 +103506,7 @@ static const struct sPragmaNames {
   { /* zName:     */ "schema_version",
     /* ePragTyp:  */ PragTyp_HEADER_VALUE,
     /* ePragFlag: */ 0,
-    /* iArg:      */ 0 },
+    /* iArg:      */ BTREE_SCHEMA_VERSION },
 #endif
 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
   { /* zName:     */ "secure_delete",
@@ -98619,11 +103564,15 @@ static const struct sPragmaNames {
     /* ePragFlag: */ 0,
     /* iArg:      */ 0 },
 #endif
+  { /* zName:     */ "threads",
+    /* ePragTyp:  */ PragTyp_THREADS,
+    /* ePragFlag: */ 0,
+    /* iArg:      */ 0 },
 #if !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
   { /* zName:     */ "user_version",
     /* ePragTyp:  */ PragTyp_HEADER_VALUE,
     /* ePragFlag: */ 0,
-    /* iArg:      */ 0 },
+    /* iArg:      */ BTREE_USER_VERSION },
 #endif
 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
 #if defined(SQLITE_DEBUG)
@@ -98666,9 +103615,10 @@ static const struct sPragmaNames {
     /* iArg:      */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
 #endif
 };
-/* Number of pragmas: 56 on by default, 69 total. */
-/* End of the automatically generated pragma table.
-***************************************************************************/
+/* Number of pragmas: 59 on by default, 72 total. */
+
+/************** End of pragma.h **********************************************/
+/************** Continuing where we left off in pragma.c *********************/
 
 /*
 ** Interpret the given string as a safety level.  Return 0 for OFF,
@@ -98804,15 +103754,15 @@ static int changeTempStorage(Parse *pParse, const char *zStorageType){
 */
 static void returnSingleInt(Parse *pParse, const char *zLabel, i64 value){
   Vdbe *v = sqlite3GetVdbe(pParse);
-  int mem = ++pParse->nMem;
+  int nMem = ++pParse->nMem;
   i64 *pI64 = sqlite3DbMallocRaw(pParse->db, sizeof(value));
   if( pI64 ){
     memcpy(pI64, &value, sizeof(value));
   }
-  sqlite3VdbeAddOp4(v, OP_Int64, 0, mem, 0, (char*)pI64, P4_INT64);
+  sqlite3VdbeAddOp4(v, OP_Int64, 0, nMem, 0, (char*)pI64, P4_INT64);
   sqlite3VdbeSetNumCols(v, 1);
   sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC);
-  sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
+  sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1);
 }
 
 
@@ -98934,11 +103884,12 @@ SQLITE_PRIVATE void sqlite3Pragma(
   Token *pId;            /* Pointer to <id> token */
   char *aFcntl[4];       /* Argument to SQLITE_FCNTL_PRAGMA */
   int iDb;               /* Database index for <database> */
-  int lwr, upr, mid;           /* Binary search bounds */
+  int lwr, upr, mid = 0;       /* Binary search bounds */
   int rc;                      /* return value form SQLITE_FCNTL_PRAGMA */
   sqlite3 *db = pParse->db;    /* The database connection */
   Db *pDb;                     /* The specific database being pragmaed */
   Vdbe *v = sqlite3GetVdbe(pParse);  /* Prepared statement */
+  const struct sPragmaNames *pPragma;
 
   if( v==0 ) return;
   sqlite3VdbeRunOnlyOnce(v);
@@ -98974,6 +103925,17 @@ SQLITE_PRIVATE void sqlite3Pragma(
   /* Send an SQLITE_FCNTL_PRAGMA file-control to the underlying VFS
   ** connection.  If it returns SQLITE_OK, then assume that the VFS
   ** handled the pragma and generate a no-op prepared statement.
+  **
+  ** IMPLEMENTATION-OF: R-12238-55120 Whenever a PRAGMA statement is parsed,
+  ** an SQLITE_FCNTL_PRAGMA file control is sent to the open sqlite3_file
+  ** object corresponding to the database file to which the pragma
+  ** statement refers.
+  **
+  ** IMPLEMENTATION-OF: R-29875-31678 The argument to the SQLITE_FCNTL_PRAGMA
+  ** file control is an array of pointers to strings (char**) in which the
+  ** second element of the array is the name of the pragma and the third
+  ** element is the argument to the pragma or NULL if the pragma has no
+  ** argument.
   */
   aFcntl[0] = 0;
   aFcntl[1] = zLeft;
@@ -98983,11 +103945,11 @@ SQLITE_PRIVATE void sqlite3Pragma(
   rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
   if( rc==SQLITE_OK ){
     if( aFcntl[0] ){
-      int mem = ++pParse->nMem;
-      sqlite3VdbeAddOp4(v, OP_String8, 0, mem, 0, aFcntl[0], 0);
+      int nMem = ++pParse->nMem;
+      sqlite3VdbeAddOp4(v, OP_String8, 0, nMem, 0, aFcntl[0], 0);
       sqlite3VdbeSetNumCols(v, 1);
       sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "result", SQLITE_STATIC);
-      sqlite3VdbeAddOp2(v, OP_ResultRow, mem, 1);
+      sqlite3VdbeAddOp2(v, OP_ResultRow, nMem, 1);
       sqlite3_free(aFcntl[0]);
     }
     goto pragma_out;
@@ -99016,14 +103978,15 @@ SQLITE_PRIVATE void sqlite3Pragma(
     }
   }
   if( lwr>upr ) goto pragma_out;
+  pPragma = &aPragmaNames[mid];
 
   /* Make sure the database schema is loaded if the pragma requires that */
-  if( (aPragmaNames[mid].mPragFlag & PragFlag_NeedSchema)!=0 ){
+  if( (pPragma->mPragFlag & PragFlag_NeedSchema)!=0 ){
     if( sqlite3ReadSchema(pParse) ) goto pragma_out;
   }
 
   /* Jump to the appropriate pragma handler */
-  switch( aPragmaNames[mid].ePragTyp ){
+  switch( pPragma->ePragTyp ){
   
 #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
   /*
@@ -99591,7 +104554,9 @@ SQLITE_PRIVATE void sqlite3Pragma(
         sqlite3ErrorMsg(pParse, 
             "Safety level may not be changed inside a transaction");
       }else{
-        pDb->safety_level = getSafetyLevel(zRight,0,1)+1;
+        int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK;
+        if( iLevel==0 ) iLevel = 1;
+        pDb->safety_level = iLevel;
         setAllPagerFlags(db);
       }
     }
@@ -99602,15 +104567,20 @@ SQLITE_PRIVATE void sqlite3Pragma(
 #ifndef SQLITE_OMIT_FLAG_PRAGMAS
   case PragTyp_FLAG: {
     if( zRight==0 ){
-      returnSingleInt(pParse, aPragmaNames[mid].zName,
-                     (db->flags & aPragmaNames[mid].iArg)!=0 );
+      returnSingleInt(pParse, pPragma->zName, (db->flags & pPragma->iArg)!=0 );
     }else{
-      int mask = aPragmaNames[mid].iArg;    /* Mask of bits to set or clear. */
+      int mask = pPragma->iArg;    /* Mask of bits to set or clear. */
       if( db->autoCommit==0 ){
         /* Foreign key support may not be enabled or disabled while not
         ** in auto-commit mode.  */
         mask &= ~(SQLITE_ForeignKeys);
       }
+#if SQLITE_USER_AUTHENTICATION
+      if( db->auth.authLevel==UAUTH_User ){
+        /* Do not allow non-admin users to modify the schema arbitrarily */
+        mask &= ~(SQLITE_WriteSchema);
+      }
+#endif
 
       if( sqlite3GetBoolean(zRight, 0) ){
         db->flags |= mask;
@@ -99729,7 +104699,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
         }else if( pPk==0 ){
           k = 1;
         }else{
-          for(k=1; ALWAYS(k<=pTab->nCol) && pPk->aiColumn[k-1]!=i; k++){}
+          for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
         }
         sqlite3VdbeAddOp2(v, OP_Integer, k, 6);
         sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
@@ -99776,20 +104746,42 @@ SQLITE_PRIVATE void sqlite3Pragma(
     pIdx = sqlite3FindIndex(db, zRight, zDb);
     if( pIdx ){
       int i;
+      int mx;
+      if( pPragma->iArg ){
+        /* PRAGMA index_xinfo (newer version with more rows and columns) */
+        mx = pIdx->nColumn;
+        pParse->nMem = 6;
+      }else{
+        /* PRAGMA index_info (legacy version) */
+        mx = pIdx->nKeyCol;
+        pParse->nMem = 3;
+      }
       pTab = pIdx->pTable;
-      sqlite3VdbeSetNumCols(v, 3);
-      pParse->nMem = 3;
+      sqlite3VdbeSetNumCols(v, pParse->nMem);
       sqlite3CodeVerifySchema(pParse, iDb);
       sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seqno", SQLITE_STATIC);
       sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "cid", SQLITE_STATIC);
       sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "name", SQLITE_STATIC);
-      for(i=0; i<pIdx->nKeyCol; i++){
+      if( pPragma->iArg ){
+        sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "desc", SQLITE_STATIC);
+        sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "coll", SQLITE_STATIC);
+        sqlite3VdbeSetColName(v, 5, COLNAME_NAME, "key", SQLITE_STATIC);
+      }
+      for(i=0; i<mx; i++){
         i16 cnum = pIdx->aiColumn[i];
         sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
         sqlite3VdbeAddOp2(v, OP_Integer, cnum, 2);
-        assert( pTab->nCol>cnum );
-        sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pTab->aCol[cnum].zName, 0);
-        sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
+        if( cnum<0 ){
+          sqlite3VdbeAddOp2(v, OP_Null, 0, 3);
+        }else{
+          sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pTab->aCol[cnum].zName, 0);
+        }
+        if( pPragma->iArg ){
+          sqlite3VdbeAddOp2(v, OP_Integer, pIdx->aSortOrder[i], 4);
+          sqlite3VdbeAddOp4(v, OP_String8, 0, 5, 0, pIdx->azColl[i], 0);
+          sqlite3VdbeAddOp2(v, OP_Integer, i<pIdx->nKeyCol, 6);
+        }
+        sqlite3VdbeAddOp2(v, OP_ResultRow, 1, pParse->nMem);
       }
     }
   }
@@ -99802,17 +104794,22 @@ SQLITE_PRIVATE void sqlite3Pragma(
     pTab = sqlite3FindTable(db, zRight, zDb);
     if( pTab ){
       v = sqlite3GetVdbe(pParse);
-      sqlite3VdbeSetNumCols(v, 3);
-      pParse->nMem = 3;
+      sqlite3VdbeSetNumCols(v, 5);
+      pParse->nMem = 5;
       sqlite3CodeVerifySchema(pParse, iDb);
       sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "seq", SQLITE_STATIC);
       sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "name", SQLITE_STATIC);
       sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "unique", SQLITE_STATIC);
+      sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "origin", SQLITE_STATIC);
+      sqlite3VdbeSetColName(v, 4, COLNAME_NAME, "partial", SQLITE_STATIC);
       for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){
+        const char *azOrigin[] = { "c", "u", "pk" };
         sqlite3VdbeAddOp2(v, OP_Integer, i, 1);
         sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0, pIdx->zName, 0);
         sqlite3VdbeAddOp2(v, OP_Integer, IsUniqueIndex(pIdx), 3);
-        sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
+        sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, azOrigin[pIdx->idxType], 0);
+        sqlite3VdbeAddOp2(v, OP_Integer, pIdx->pPartIdxWhere!=0, 5);
+        sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5);
       }
     }
   }
@@ -100336,7 +105333,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
       ){
         for(pEnc=&encnames[0]; pEnc->zName; pEnc++){
           if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){
-            ENC(pParse->db) = pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
+            SCHEMA_ENC(db) = ENC(db) =
+                pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE;
             break;
           }
         }
@@ -100381,24 +105379,9 @@ SQLITE_PRIVATE void sqlite3Pragma(
   ** applications for any purpose.
   */
   case PragTyp_HEADER_VALUE: {
-    int iCookie;   /* Cookie index. 1 for schema-cookie, 6 for user-cookie. */
+    int iCookie = pPragma->iArg;  /* Which cookie to read or write */
     sqlite3VdbeUsesBtree(v, iDb);
-    switch( zLeft[0] ){
-      case 'a': case 'A':
-        iCookie = BTREE_APPLICATION_ID;
-        break;
-      case 'f': case 'F':
-        iCookie = BTREE_FREE_PAGE_COUNT;
-        break;
-      case 's': case 'S':
-        iCookie = BTREE_SCHEMA_VERSION;
-        break;
-      default:
-        iCookie = BTREE_USER_VERSION;
-        break;
-    }
-
-    if( zRight && iCookie!=BTREE_FREE_PAGE_COUNT ){
+    if( zRight && (pPragma->mPragFlag & PragFlag_ReadOnly)==0 ){
       /* Write the specified cookie value */
       static const VdbeOpList setCookie[] = {
         { OP_Transaction,    0,  1,  0},    /* 0 */
@@ -100451,7 +105434,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
 
 #ifndef SQLITE_OMIT_WAL
   /*
-  **   PRAGMA [database.]wal_checkpoint = passive|full|restart
+  **   PRAGMA [database.]wal_checkpoint = passive|full|restart|truncate
   **
   ** Checkpoint the database.
   */
@@ -100463,6 +105446,8 @@ SQLITE_PRIVATE void sqlite3Pragma(
         eMode = SQLITE_CHECKPOINT_FULL;
       }else if( sqlite3StrICmp(zRight, "restart")==0 ){
         eMode = SQLITE_CHECKPOINT_RESTART;
+      }else if( sqlite3StrICmp(zRight, "truncate")==0 ){
+        eMode = SQLITE_CHECKPOINT_TRUNCATE;
       }
     }
     sqlite3VdbeSetNumCols(v, 3);
@@ -100498,8 +105483,9 @@ SQLITE_PRIVATE void sqlite3Pragma(
   /*
   **  PRAGMA shrink_memory
   **
-  ** This pragma attempts to free as much memory as possible from the
-  ** current database connection.
+  ** IMPLEMENTATION-OF: R-23445-46109 This pragma causes the database
+  ** connection on which it is invoked to free up as much memory as it
+  ** can, by calling sqlite3_db_release_memory().
   */
   case PragTyp_SHRINK_MEMORY: {
     sqlite3_db_release_memory(db);
@@ -100516,7 +105502,7 @@ SQLITE_PRIVATE void sqlite3Pragma(
   ** disables the timeout.
   */
   /*case PragTyp_BUSY_TIMEOUT*/ default: {
-    assert( aPragmaNames[mid].ePragTyp==PragTyp_BUSY_TIMEOUT );
+    assert( pPragma->ePragTyp==PragTyp_BUSY_TIMEOUT );
     if( zRight ){
       sqlite3_busy_timeout(db, sqlite3Atoi(zRight));
     }
@@ -100528,8 +105514,12 @@ SQLITE_PRIVATE void sqlite3Pragma(
   **   PRAGMA soft_heap_limit
   **   PRAGMA soft_heap_limit = N
   **
-  ** Call sqlite3_soft_heap_limit64(N).  Return the result.  If N is omitted,
-  ** use -1.
+  ** IMPLEMENTATION-OF: R-26343-45930 This pragma invokes the
+  ** sqlite3_soft_heap_limit64() interface with the argument N, if N is
+  ** specified and is a non-negative integer.
+  ** IMPLEMENTATION-OF: R-64451-07163 The soft_heap_limit pragma always
+  ** returns the same integer that would be returned by the
+  ** sqlite3_soft_heap_limit64(-1) C-language function.
   */
   case PragTyp_SOFT_HEAP_LIMIT: {
     sqlite3_int64 N;
@@ -100540,6 +105530,26 @@ SQLITE_PRIVATE void sqlite3Pragma(
     break;
   }
 
+  /*
+  **   PRAGMA threads
+  **   PRAGMA threads = N
+  **
+  ** Configure the maximum number of worker threads.  Return the new
+  ** maximum, which might be less than requested.
+  */
+  case PragTyp_THREADS: {
+    sqlite3_int64 N;
+    if( zRight
+     && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK
+     && N>=0
+    ){
+      sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff));
+    }
+    returnSingleInt(pParse, "threads",
+                    sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1));
+    break;
+  }
+
 #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
   /*
   ** Report the current state of file logs for all databases
@@ -100695,7 +105705,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char
   if( argv==0 ) return 0;   /* Might happen if EMPTY_RESULT_CALLBACKS are on */
   if( argv[1]==0 ){
     corruptSchema(pData, argv[0], 0);
-  }else if( argv[2] && argv[2][0] ){
+  }else if( sqlite3_strnicmp(argv[2],"create ",7)==0 ){
     /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
     ** But because db->init.busy is set to 1, no VDBE code is generated
     ** or executed.  All the parser does is build the internal data
@@ -100726,8 +105736,8 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char
       }
     }
     sqlite3_finalize(pStmt);
-  }else if( argv[0]==0 ){
-    corruptSchema(pData, 0, 0);
+  }else if( argv[0]==0 || (argv[2]!=0 && argv[2][0]!=0) ){
+    corruptSchema(pData, argv[0], 0);
   }else{
     /* If the SQL column is blank it means this is an index that
     ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
@@ -100956,7 +105966,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){
         db->aDb[iDb].zName, zMasterName);
 #ifndef SQLITE_OMIT_AUTHORIZATION
     {
-      int (*xAuth)(void*,int,const char*,const char*,const char*,const char*);
+      sqlite3_xauth xAuth;
       xAuth = db->xAuth;
       db->xAuth = 0;
 #endif
@@ -101022,8 +106032,11 @@ SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){
   int commit_internal = !(db->flags&SQLITE_InternChanges);
   
   assert( sqlite3_mutex_held(db->mutex) );
+  assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) );
+  assert( db->init.busy==0 );
   rc = SQLITE_OK;
   db->init.busy = 1;
+  ENC(db) = SCHEMA_ENC(db);
   for(i=0; rc==SQLITE_OK && i<db->nDb; i++){
     if( DbHasProperty(db, i, DB_SchemaLoaded) || i==1 ) continue;
     rc = sqlite3InitOne(db, i, pzErrMsg);
@@ -101037,8 +106050,8 @@ SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){
   ** schema may contain references to objects in other databases.
   */
 #ifndef SQLITE_OMIT_TEMPDB
-  if( rc==SQLITE_OK && ALWAYS(db->nDb>1)
-                    && !DbHasProperty(db, 1, DB_SchemaLoaded) ){
+  assert( db->nDb>1 );
+  if( rc==SQLITE_OK && !DbHasProperty(db, 1, DB_SchemaLoaded) ){
     rc = sqlite3InitOne(db, 1, pzErrMsg);
     if( rc ){
       sqlite3ResetOneSchema(db, 1);
@@ -101221,7 +106234,7 @@ static int sqlite3Prepare(
       rc = sqlite3BtreeSchemaLocked(pBt);
       if( rc ){
         const char *zDb = db->aDb[i].zName;
-        sqlite3Error(db, rc, "database schema is locked: %s", zDb);
+        sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb);
         testcase( db->flags & SQLITE_ReadUncommitted );
         goto end_prepare;
       }
@@ -101238,7 +106251,7 @@ static int sqlite3Prepare(
     testcase( nBytes==mxLen );
     testcase( nBytes==mxLen+1 );
     if( nBytes>mxLen ){
-      sqlite3Error(db, SQLITE_TOOBIG, "statement too long");
+      sqlite3ErrorWithMsg(db, SQLITE_TOOBIG, "statement too long");
       rc = sqlite3ApiExit(db, SQLITE_TOOBIG);
       goto end_prepare;
     }
@@ -101305,10 +106318,10 @@ static int sqlite3Prepare(
   }
 
   if( zErrMsg ){
-    sqlite3Error(db, rc, "%s", zErrMsg);
+    sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg);
     sqlite3DbFree(db, zErrMsg);
   }else{
-    sqlite3Error(db, rc, 0);
+    sqlite3Error(db, rc);
   }
 
   /* Delete any TriggerPrg structures allocated while parsing this statement. */
@@ -101336,9 +106349,12 @@ static int sqlite3LockAndPrepare(
   const char **pzTail       /* OUT: End of parsed string */
 ){
   int rc;
-  assert( ppStmt!=0 );
+
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( ppStmt==0 ) return SQLITE_MISUSE_BKPT;
+#endif
   *ppStmt = 0;
-  if( !sqlite3SafetyCheckOk(db) ){
+  if( !sqlite3SafetyCheckOk(db)||zSql==0 ){
     return SQLITE_MISUSE_BKPT;
   }
   sqlite3_mutex_enter(db->mutex);
@@ -101399,7 +106415,7 @@ SQLITE_PRIVATE int sqlite3Reprepare(Vdbe *p){
 ** and the statement is automatically recompiled if an schema change
 ** occurs.
 */
-SQLITE_API int sqlite3_prepare(
+SQLITE_API int SQLITE_STDCALL sqlite3_prepare(
   sqlite3 *db,              /* Database handle. */
   const char *zSql,         /* UTF-8 encoded SQL statement. */
   int nBytes,               /* Length of zSql in bytes. */
@@ -101411,7 +106427,7 @@ SQLITE_API int sqlite3_prepare(
   assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );  /* VERIFY: F13021 */
   return rc;
 }
-SQLITE_API int sqlite3_prepare_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2(
   sqlite3 *db,              /* Database handle. */
   const char *zSql,         /* UTF-8 encoded SQL statement. */
   int nBytes,               /* Length of zSql in bytes. */
@@ -101445,9 +106461,11 @@ static int sqlite3Prepare16(
   const char *zTail8 = 0;
   int rc = SQLITE_OK;
 
-  assert( ppStmt );
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( ppStmt==0 ) return SQLITE_MISUSE_BKPT;
+#endif
   *ppStmt = 0;
-  if( !sqlite3SafetyCheckOk(db) ){
+  if( !sqlite3SafetyCheckOk(db)||zSql==0 ){
     return SQLITE_MISUSE_BKPT;
   }
   if( nBytes>=0 ){
@@ -101485,7 +106503,7 @@ static int sqlite3Prepare16(
 ** and the statement is automatically recompiled if an schema change
 ** occurs.
 */
-SQLITE_API int sqlite3_prepare16(
+SQLITE_API int SQLITE_STDCALL sqlite3_prepare16(
   sqlite3 *db,              /* Database handle. */ 
   const void *zSql,         /* UTF-16 encoded SQL statement. */
   int nBytes,               /* Length of zSql in bytes. */
@@ -101497,7 +106515,7 @@ SQLITE_API int sqlite3_prepare16(
   assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 );  /* VERIFY: F13021 */
   return rc;
 }
-SQLITE_API int sqlite3_prepare16_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2(
   sqlite3 *db,              /* Database handle. */ 
   const void *zSql,         /* UTF-16 encoded SQL statement. */
   int nBytes,               /* Length of zSql in bytes. */
@@ -101530,6 +106548,20 @@ SQLITE_API int sqlite3_prepare16_v2(
 */
 
 /*
+** Trace output macros
+*/
+#if SELECTTRACE_ENABLED
+/***/ int sqlite3SelectTrace = 0;
+# define SELECTTRACE(K,P,S,X)  \
+  if(sqlite3SelectTrace&(K))   \
+    sqlite3DebugPrintf("%*s%s.%p: ",(P)->nSelectIndent*2-2,"",(S)->zSelName,(S)),\
+    sqlite3DebugPrintf X
+#else
+# define SELECTTRACE(K,P,S,X)
+#endif
+
+
+/*
 ** An instance of the following object is used to record information about
 ** how to process the DISTINCT keyword, to simplify passing that information
 ** into the selectInnerLoop() routine.
@@ -101559,20 +106591,25 @@ struct SortCtx {
 #define SORTFLAG_UseSorter  0x01   /* Use SorterOpen instead of OpenEphemeral */
 
 /*
-** Delete all the content of a Select structure but do not deallocate
-** the select structure itself.
+** Delete all the content of a Select structure.  Deallocate the structure
+** itself only if bFree is true.
 */
-static void clearSelect(sqlite3 *db, Select *p){
-  sqlite3ExprListDelete(db, p->pEList);
-  sqlite3SrcListDelete(db, p->pSrc);
-  sqlite3ExprDelete(db, p->pWhere);
-  sqlite3ExprListDelete(db, p->pGroupBy);
-  sqlite3ExprDelete(db, p->pHaving);
-  sqlite3ExprListDelete(db, p->pOrderBy);
-  sqlite3SelectDelete(db, p->pPrior);
-  sqlite3ExprDelete(db, p->pLimit);
-  sqlite3ExprDelete(db, p->pOffset);
-  sqlite3WithDelete(db, p->pWith);
+static void clearSelect(sqlite3 *db, Select *p, int bFree){
+  while( p ){
+    Select *pPrior = p->pPrior;
+    sqlite3ExprListDelete(db, p->pEList);
+    sqlite3SrcListDelete(db, p->pSrc);
+    sqlite3ExprDelete(db, p->pWhere);
+    sqlite3ExprListDelete(db, p->pGroupBy);
+    sqlite3ExprDelete(db, p->pHaving);
+    sqlite3ExprListDelete(db, p->pOrderBy);
+    sqlite3ExprDelete(db, p->pLimit);
+    sqlite3ExprDelete(db, p->pOffset);
+    sqlite3WithDelete(db, p->pWith);
+    if( bFree ) sqlite3DbFree(db, p);
+    p = pPrior;
+    bFree = 1;
+  }
 }
 
 /*
@@ -101607,7 +106644,6 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
   Select standin;
   sqlite3 *db = pParse->db;
   pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
-  assert( db->mallocFailed || !pOffset || pLimit ); /* OFFSET implies LIMIT */
   if( pNew==0 ){
     assert( db->mallocFailed );
     pNew = &standin;
@@ -101627,12 +106663,11 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
   pNew->op = TK_SELECT;
   pNew->pLimit = pLimit;
   pNew->pOffset = pOffset;
-  assert( pOffset==0 || pLimit!=0 );
+  assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 );
   pNew->addrOpenEphm[0] = -1;
   pNew->addrOpenEphm[1] = -1;
   if( db->mallocFailed ) {
-    clearSelect(db, pNew);
-    if( pNew!=&standin ) sqlite3DbFree(db, pNew);
+    clearSelect(db, pNew, pNew!=&standin);
     pNew = 0;
   }else{
     assert( pNew->pSrc!=0 || pParse->nErr>0 );
@@ -101641,14 +106676,23 @@ SQLITE_PRIVATE Select *sqlite3SelectNew(
   return pNew;
 }
 
+#if SELECTTRACE_ENABLED
+/*
+** Set the name of a Select object
+*/
+SQLITE_PRIVATE void sqlite3SelectSetName(Select *p, const char *zName){
+  if( p && zName ){
+    sqlite3_snprintf(sizeof(p->zSelName), p->zSelName, "%s", zName);
+  }
+}
+#endif
+
+
 /*
 ** Delete the given Select structure and all of its substructures.
 */
 SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){
-  if( p ){
-    clearSelect(db, p);
-    sqlite3DbFree(db, p);
-  }
+  clearSelect(db, p, 1);
 }
 
 /*
@@ -101970,28 +107014,43 @@ static KeyInfo *keyInfoFromExprList(
 );
 
 /*
-** Insert code into "v" that will push the record in register regData
-** into the sorter.
+** Generate code that will push the record in registers regData
+** through regData+nData-1 onto the sorter.
 */
 static void pushOntoSorter(
   Parse *pParse,         /* Parser context */
   SortCtx *pSort,        /* Information about the ORDER BY clause */
   Select *pSelect,       /* The whole SELECT statement */
-  int regData            /* Register holding data to be sorted */
+  int regData,           /* First register holding data to be sorted */
+  int nData,             /* Number of elements in the data array */
+  int nPrefixReg         /* No. of reg prior to regData available for use */
 ){
-  Vdbe *v = pParse->pVdbe;
-  int nExpr = pSort->pOrderBy->nExpr;
-  int regRecord = ++pParse->nMem;
-  int regBase = pParse->nMem+1;
-  int nOBSat = pSort->nOBSat;
-  int op;
+  Vdbe *v = pParse->pVdbe;                         /* Stmt under construction */
+  int bSeq = ((pSort->sortFlags & SORTFLAG_UseSorter)==0);
+  int nExpr = pSort->pOrderBy->nExpr;              /* No. of ORDER BY terms */
+  int nBase = nExpr + bSeq + nData;                /* Fields in sorter record */
+  int regBase;                                     /* Regs for sorter record */
+  int regRecord = ++pParse->nMem;                  /* Assembled sorter record */
+  int nOBSat = pSort->nOBSat;                      /* ORDER BY terms to skip */
+  int op;                            /* Opcode to add sorter record to sorter */
 
-  pParse->nMem += nExpr+2;        /* nExpr+2 registers allocated at regBase */
-  sqlite3ExprCacheClear(pParse);
-  sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, 0);
-  sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr);
-  sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1, 1);
-  sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nExpr+2-nOBSat,regRecord);
+  assert( bSeq==0 || bSeq==1 );
+  if( nPrefixReg ){
+    assert( nPrefixReg==nExpr+bSeq );
+    regBase = regData - nExpr - bSeq;
+  }else{
+    regBase = pParse->nMem + 1;
+    pParse->nMem += nBase;
+  }
+  sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, SQLITE_ECEL_DUP);
+  if( bSeq ){
+    sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr);
+  }
+  if( nPrefixReg==0 ){
+    sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData);
+  }
+
+  sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regRecord);
   if( nOBSat>0 ){
     int regPrevKey;   /* The first nOBSat columns of the previous row */
     int addrFirst;    /* Address of the OP_IfNot opcode */
@@ -102002,16 +107061,23 @@ static void pushOntoSorter(
 
     regPrevKey = pParse->nMem+1;
     pParse->nMem += pSort->nOBSat;
-    nKey = nExpr - pSort->nOBSat + 1;
-    addrFirst = sqlite3VdbeAddOp1(v, OP_IfNot, regBase+nExpr); VdbeCoverage(v);
+    nKey = nExpr - pSort->nOBSat + bSeq;
+    if( bSeq ){
+      addrFirst = sqlite3VdbeAddOp1(v, OP_IfNot, regBase+nExpr); 
+    }else{
+      addrFirst = sqlite3VdbeAddOp1(v, OP_SequenceTest, pSort->iECursor);
+    }
+    VdbeCoverage(v);
     sqlite3VdbeAddOp3(v, OP_Compare, regPrevKey, regBase, pSort->nOBSat);
     pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex);
     if( pParse->db->mallocFailed ) return;
-    pOp->p2 = nKey + 1;
+    pOp->p2 = nKey + nData;
     pKI = pOp->p4.pKeyInfo;
     memset(pKI->aSortOrder, 0, pKI->nField); /* Makes OP_Jump below testable */
     sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO);
-    pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat, 1);
+    testcase( pKI->nXField>2 );
+    pOp->p4.pKeyInfo = keyInfoFromExprList(pParse, pSort->pOrderBy, nOBSat,
+                                           pKI->nXField-1);
     addrJmp = sqlite3VdbeCurrentAddr(v);
     sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v);
     pSort->labelBkOut = sqlite3VdbeMakeLabel(v);
@@ -102019,7 +107085,7 @@ static void pushOntoSorter(
     sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
     sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor);
     sqlite3VdbeJumpHere(v, addrFirst);
-    sqlite3VdbeAddOp3(v, OP_Move, regBase, regPrevKey, pSort->nOBSat);
+    sqlite3ExprCodeMove(pParse, regBase, regPrevKey, pSort->nOBSat);
     sqlite3VdbeJumpHere(v, addrJmp);
   }
   if( pSort->sortFlags & SORTFLAG_UseSorter ){
@@ -102029,20 +107095,17 @@ static void pushOntoSorter(
   }
   sqlite3VdbeAddOp2(v, op, pSort->iECursor, regRecord);
   if( pSelect->iLimit ){
-    int addr1, addr2;
+    int addr;
     int iLimit;
     if( pSelect->iOffset ){
       iLimit = pSelect->iOffset+1;
     }else{
       iLimit = pSelect->iLimit;
     }
-    addr1 = sqlite3VdbeAddOp1(v, OP_IfZero, iLimit); VdbeCoverage(v);
-    sqlite3VdbeAddOp2(v, OP_AddImm, iLimit, -1);
-    addr2 = sqlite3VdbeAddOp0(v, OP_Goto);
-    sqlite3VdbeJumpHere(v, addr1);
+    addr = sqlite3VdbeAddOp3(v, OP_IfNotZero, iLimit, 0, -1); VdbeCoverage(v);
     sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor);
     sqlite3VdbeAddOp1(v, OP_Delete, pSort->iECursor);
-    sqlite3VdbeJumpHere(v, addr2);
+    sqlite3VdbeJumpHere(v, addr);
   }
 }
 
@@ -102141,6 +107204,7 @@ static void selectInnerLoop(
   int eDest = pDest->eDest;   /* How to dispose of results */
   int iParm = pDest->iSDParm; /* First argument to disposal method */
   int nResultCol;             /* Number of result columns */
+  int nPrefixReg = 0;         /* Number of extra registers before regResult */
 
   assert( v );
   assert( pEList!=0 );
@@ -102156,6 +107220,11 @@ static void selectInnerLoop(
   nResultCol = pEList->nExpr;
 
   if( pDest->iSdst==0 ){
+    if( pSort ){
+      nPrefixReg = pSort->pOrderBy->nExpr;
+      if( !(pSort->sortFlags & SORTFLAG_UseSorter) ) nPrefixReg++;
+      pParse->nMem += nPrefixReg;
+    }
     pDest->iSdst = pParse->nMem+1;
     pParse->nMem += nResultCol;
   }else if( pDest->iSdst+nResultCol > pParse->nMem ){
@@ -102272,10 +107341,10 @@ static void selectInnerLoop(
     case SRT_DistFifo:
     case SRT_Table:
     case SRT_EphemTab: {
-      int r1 = sqlite3GetTempReg(pParse);
+      int r1 = sqlite3GetTempRange(pParse, nPrefixReg+1);
       testcase( eDest==SRT_Table );
       testcase( eDest==SRT_EphemTab );
-      sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1);
+      sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg);
 #ifndef SQLITE_OMIT_CTE
       if( eDest==SRT_DistFifo ){
         /* If the destination is DistFifo, then cursor (iParm+1) is open
@@ -102290,7 +107359,7 @@ static void selectInnerLoop(
       }
 #endif
       if( pSort ){
-        pushOntoSorter(pParse, pSort, p, r1);
+        pushOntoSorter(pParse, pSort, p, r1+nPrefixReg, 1, nPrefixReg);
       }else{
         int r2 = sqlite3GetTempReg(pParse);
         sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2);
@@ -102298,7 +107367,7 @@ static void selectInnerLoop(
         sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
         sqlite3ReleaseTempReg(pParse, r2);
       }
-      sqlite3ReleaseTempReg(pParse, r1);
+      sqlite3ReleaseTempRange(pParse, r1, nPrefixReg+1);
       break;
     }
 
@@ -102316,7 +107385,7 @@ static void selectInnerLoop(
         ** ORDER BY in this case since the order of entries in the set
         ** does not matter.  But there might be a LIMIT clause, in which
         ** case the order does matter */
-        pushOntoSorter(pParse, pSort, p, regResult);
+        pushOntoSorter(pParse, pSort, p, regResult, 1, nPrefixReg);
       }else{
         int r1 = sqlite3GetTempReg(pParse);
         sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult,1,r1, &pDest->affSdst, 1);
@@ -102342,9 +107411,9 @@ static void selectInnerLoop(
     case SRT_Mem: {
       assert( nResultCol==1 );
       if( pSort ){
-        pushOntoSorter(pParse, pSort, p, regResult);
+        pushOntoSorter(pParse, pSort, p, regResult, 1, nPrefixReg);
       }else{
-        sqlite3ExprCodeMove(pParse, regResult, iParm, 1);
+        assert( regResult==iParm );
         /* The LIMIT clause will jump out of the loop for us */
       }
       break;
@@ -102356,10 +107425,7 @@ static void selectInnerLoop(
       testcase( eDest==SRT_Coroutine );
       testcase( eDest==SRT_Output );
       if( pSort ){
-        int r1 = sqlite3GetTempReg(pParse);
-        sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1);
-        pushOntoSorter(pParse, pSort, p, r1);
-        sqlite3ReleaseTempReg(pParse, r1);
+        pushOntoSorter(pParse, pSort, p, regResult, nResultCol, nPrefixReg);
       }else if( eDest==SRT_Coroutine ){
         sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
       }else{
@@ -102436,7 +107502,7 @@ static void selectInnerLoop(
   ** the output for us.
   */
   if( pSort==0 && p->iLimit ){
-    sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); VdbeCoverage(v);
+    sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v);
   }
 }
 
@@ -102502,7 +107568,7 @@ SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo *p){ return p->nRef==1; }
 ** then the KeyInfo structure is appropriate for initializing a virtual
 ** index to implement a DISTINCT test.
 **
-** Space to hold the KeyInfo structure is obtain from malloc.  The calling
+** Space to hold the KeyInfo structure is obtained from malloc.  The calling
 ** function is responsible for seeing that this structure is eventually
 ** freed.
 */
@@ -102519,7 +107585,7 @@ static KeyInfo *keyInfoFromExprList(
   int i;
 
   nExpr = pList->nExpr;
-  pInfo = sqlite3KeyInfoAlloc(db, nExpr+nExtra-iStart, 1);
+  pInfo = sqlite3KeyInfoAlloc(db, nExpr-iStart, nExtra+1);
   if( pInfo ){
     assert( sqlite3KeyInfoIsWriteable(pInfo) );
     for(i=iStart, pItem=pList->a+iStart; i<nExpr; i++, pItem++){
@@ -102639,46 +107705,58 @@ static void generateSortTail(
   int addr;
   int addrOnce = 0;
   int iTab;
-  int pseudoTab = 0;
   ExprList *pOrderBy = pSort->pOrderBy;
   int eDest = pDest->eDest;
   int iParm = pDest->iSDParm;
   int regRow;
   int regRowid;
   int nKey;
+  int iSortTab;                   /* Sorter cursor to read from */
+  int nSortData;                  /* Trailing values to read from sorter */
+  int i;
+  int bSeq;                       /* True if sorter record includes seq. no. */
+#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
+  struct ExprList_item *aOutEx = p->pEList->a;
+#endif
 
   if( pSort->labelBkOut ){
     sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
     sqlite3VdbeAddOp2(v, OP_Goto, 0, addrBreak);
     sqlite3VdbeResolveLabel(v, pSort->labelBkOut);
-    addrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
   }
   iTab = pSort->iECursor;
-  regRow = sqlite3GetTempReg(pParse);
   if( eDest==SRT_Output || eDest==SRT_Coroutine ){
-    pseudoTab = pParse->nTab++;
-    sqlite3VdbeAddOp3(v, OP_OpenPseudo, pseudoTab, regRow, nColumn);
     regRowid = 0;
+    regRow = pDest->iSdst;
+    nSortData = nColumn;
   }else{
     regRowid = sqlite3GetTempReg(pParse);
+    regRow = sqlite3GetTempReg(pParse);
+    nSortData = 1;
   }
   nKey = pOrderBy->nExpr - pSort->nOBSat;
   if( pSort->sortFlags & SORTFLAG_UseSorter ){
     int regSortOut = ++pParse->nMem;
-    int ptab2 = pParse->nTab++;
-    sqlite3VdbeAddOp3(v, OP_OpenPseudo, ptab2, regSortOut, nKey+2);
+    iSortTab = pParse->nTab++;
+    if( pSort->labelBkOut ){
+      addrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
+    }
+    sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nSortData);
     if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
     addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak);
     VdbeCoverage(v);
     codeOffset(v, p->iOffset, addrContinue);
-    sqlite3VdbeAddOp2(v, OP_SorterData, iTab, regSortOut);
-    sqlite3VdbeAddOp3(v, OP_Column, ptab2, nKey+1, regRow);
-    sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
+    sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab);
+    bSeq = 0;
   }else{
-    if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce);
     addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v);
     codeOffset(v, p->iOffset, addrContinue);
-    sqlite3VdbeAddOp3(v, OP_Column, iTab, nKey+1, regRow);
+    iSortTab = iTab;
+    bSeq = 1;
+  }
+  for(i=0; i<nSortData; i++){
+    sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
+    VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
   }
   switch( eDest ){
     case SRT_Table:
@@ -102707,17 +107785,9 @@ static void generateSortTail(
     }
 #endif
     default: {
-      int i;
       assert( eDest==SRT_Output || eDest==SRT_Coroutine ); 
       testcase( eDest==SRT_Output );
       testcase( eDest==SRT_Coroutine );
-      for(i=0; i<nColumn; i++){
-        assert( regRow!=pDest->iSdst+i );
-        sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iSdst+i);
-        if( i==0 ){
-          sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
-        }
-      }
       if( eDest==SRT_Output ){
         sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn);
         sqlite3ExprCacheAffinityChange(pParse, pDest->iSdst, nColumn);
@@ -102727,9 +107797,10 @@ static void generateSortTail(
       break;
     }
   }
-  sqlite3ReleaseTempReg(pParse, regRow);
-  sqlite3ReleaseTempReg(pParse, regRowid);
-
+  if( regRowid ){
+    sqlite3ReleaseTempReg(pParse, regRow);
+    sqlite3ReleaseTempReg(pParse, regRowid);
+  }
   /* The bottom of the loop
   */
   sqlite3VdbeResolveLabel(v, addrContinue);
@@ -102842,7 +107913,7 @@ static const char *columnTypeImpl(
         ** of the SELECT statement. Return the declaration type and origin
         ** data for the result-set column of the sub-select.
         */
-        if( iCol>=0 && ALWAYS(iCol<pS->pEList->nExpr) ){
+        if( iCol>=0 && iCol<pS->pEList->nExpr ){
           /* If iCol is less than zero, then the expression requests the
           ** rowid of the sub-select or view. This expression is legal (see 
           ** test case misc2.2.2) - it always evaluates to NULL.
@@ -103024,7 +108095,7 @@ static void generateColumnNames(
 }
 
 /*
-** Given a an expression list (which is really the list of expressions
+** Given an expression list (which is really the list of expressions
 ** that form the result set of a SELECT statement) compute appropriate
 ** column names for a table that would hold the expression list.
 **
@@ -103097,7 +108168,7 @@ static int selectColumnsFromExprList(
     }
 
     /* Make sure the column name is unique.  If the name is not unique,
-    ** append a integer to the name so that it becomes unique.
+    ** append an integer to the name so that it becomes unique.
     */
     nName = sqlite3Strlen30(zName);
     for(j=cnt=0; j<i; j++){
@@ -103162,12 +108233,14 @@ static void selectAddColumnTypeAndCollation(
   a = pSelect->pEList->a;
   for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
     p = a[i].pExpr;
-    pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p,0,0,0, &pCol->szEst));
+    if( pCol->zType==0 ){
+      pCol->zType = sqlite3DbStrDup(db, columnType(&sNC, p,0,0,0, &pCol->szEst));
+    }
     szAll += pCol->szEst;
     pCol->affinity = sqlite3ExprAffinity(p);
     if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_NONE;
     pColl = sqlite3ExprCollSeq(pParse, p);
-    if( pColl ){
+    if( pColl && pCol->zColl==0 ){
       pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
     }
   }
@@ -103284,7 +108357,7 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
       sqlite3ExprCode(pParse, p->pLimit, iLimit);
       sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v);
       VdbeComment((v, "LIMIT counter"));
-      sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak); VdbeCoverage(v);
+      sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v);
     }
     if( p->pOffset ){
       p->iOffset = iOffset = ++pParse->nMem;
@@ -103503,7 +108576,7 @@ static void generateWithRecursiveQuery(
   selectInnerLoop(pParse, p, p->pEList, iCurrent,
       0, 0, pDest, addrCont, addrBreak);
   if( regLimit ){
-    sqlite3VdbeAddOp3(v, OP_IfZero, regLimit, addrBreak, -1);
+    sqlite3VdbeAddOp2(v, OP_DecrJumpZero, regLimit, addrBreak);
     VdbeCoverage(v);
   }
   sqlite3VdbeResolveLabel(v, addrCont);
@@ -103536,6 +108609,65 @@ static int multiSelectOrderBy(
   SelectDest *pDest     /* What to do with query results */
 );
 
+/*
+** Error message for when two or more terms of a compound select have different
+** size result sets.
+*/
+static void selectWrongNumTermsError(Parse *pParse, Select *p){
+  if( p->selFlags & SF_Values ){
+    sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms");
+  }else{
+    sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
+      " do not have the same number of result columns", selectOpName(p->op));
+  }
+}
+
+/*
+** Handle the special case of a compound-select that originates from a
+** VALUES clause.  By handling this as a special case, we avoid deep
+** recursion, and thus do not need to enforce the SQLITE_LIMIT_COMPOUND_SELECT
+** on a VALUES clause.
+**
+** Because the Select object originates from a VALUES clause:
+**   (1) It has no LIMIT or OFFSET
+**   (2) All terms are UNION ALL
+**   (3) There is no ORDER BY clause
+*/
+static int multiSelectValues(
+  Parse *pParse,        /* Parsing context */
+  Select *p,            /* The right-most of SELECTs to be coded */
+  SelectDest *pDest     /* What to do with query results */
+){
+  Select *pPrior;
+  int nExpr = p->pEList->nExpr;
+  int nRow = 1;
+  int rc = 0;
+  assert( p->selFlags & SF_MultiValue );
+  do{
+    assert( p->selFlags & SF_Values );
+    assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
+    assert( p->pLimit==0 );
+    assert( p->pOffset==0 );
+    if( p->pEList->nExpr!=nExpr ){
+      selectWrongNumTermsError(pParse, p);
+      return 1;
+    }
+    if( p->pPrior==0 ) break;
+    assert( p->pPrior->pNext==p );
+    p = p->pPrior;
+    nRow++;
+  }while(1);
+  while( p ){
+    pPrior = p->pPrior;
+    p->pPrior = 0;
+    rc = sqlite3Select(pParse, p, pDest);
+    p->pPrior = pPrior;
+    if( rc ) break;
+    p->nSelectRow = nRow;
+    p = p->pNext;
+  }
+  return rc;
+}
 
 /*
 ** This routine is called to process a compound query form from
@@ -103617,17 +108749,19 @@ static int multiSelect(
     dest.eDest = SRT_Table;
   }
 
+  /* Special handling for a compound-select that originates as a VALUES clause.
+  */
+  if( p->selFlags & SF_MultiValue ){
+    rc = multiSelectValues(pParse, p, &dest);
+    goto multi_select_end;
+  }
+
   /* Make sure all SELECTs in the statement have the same number of elements
   ** in their result sets.
   */
   assert( p->pEList && pPrior->pEList );
   if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
-    if( p->selFlags & SF_Values ){
-      sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms");
-    }else{
-      sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
-        " do not have the same number of result columns", selectOpName(p->op));
-    }
+    selectWrongNumTermsError(pParse, p);
     rc = 1;
     goto multi_select_end;
   }
@@ -103666,7 +108800,7 @@ static int multiSelect(
       p->iLimit = pPrior->iLimit;
       p->iOffset = pPrior->iOffset;
       if( p->iLimit ){
-        addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit); VdbeCoverage(v);
+        addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
         VdbeComment((v, "Jump ahead if LIMIT reached"));
       }
       explainSetInteger(iSub2, pParse->iNextSelectId);
@@ -104002,7 +109136,7 @@ static int generateOutputSubroutine(
     */
     case SRT_Set: {
       int r1;
-      assert( pIn->nSdst==1 );
+      assert( pIn->nSdst==1 || pParse->nErr>0 );
       pDest->affSdst = 
          sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst);
       r1 = sqlite3GetTempReg(pParse);
@@ -104028,7 +109162,7 @@ static int generateOutputSubroutine(
     ** of the scan loop.
     */
     case SRT_Mem: {
-      assert( pIn->nSdst==1 );
+      assert( pIn->nSdst==1 || pParse->nErr>0 );  testcase( pIn->nSdst!=1 );
       sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1);
       /* The LIMIT clause will jump out of the loop for us */
       break;
@@ -104043,7 +109177,7 @@ static int generateOutputSubroutine(
         pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst);
         pDest->nSdst = pIn->nSdst;
       }
-      sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pDest->nSdst);
+      sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pIn->nSdst);
       sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm);
       break;
     }
@@ -104067,7 +109201,7 @@ static int generateOutputSubroutine(
   /* Jump to the end of the loop if the LIMIT is reached.
   */
   if( p->iLimit ){
-    sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1); VdbeCoverage(v);
+    sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v);
   }
 
   /* Generate the subroutine return
@@ -104259,8 +109393,10 @@ static int multiSelectOrderBy(
   if( aPermute ){
     struct ExprList_item *pItem;
     for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
-      assert( pItem->u.x.iOrderByCol>0
-          && pItem->u.x.iOrderByCol<=p->pEList->nExpr );
+      assert( pItem->u.x.iOrderByCol>0 );
+      /* assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr ) is also true
+      ** but only for well-formed SELECT statements. */
+      testcase( pItem->u.x.iOrderByCol > p->pEList->nExpr );
       aPermute[i] = pItem->u.x.iOrderByCol - 1;
     }
     pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1);
@@ -104470,7 +109606,7 @@ static int multiSelectOrderBy(
   /*** TBD:  Insert subroutine calls to close cursors on incomplete
   **** subqueries ****/
   explainComposite(pParse, p->op, iSub1, iSub2, 0);
-  return SQLITE_OK;
+  return pParse->nErr!=0;
 }
 #endif
 
@@ -104581,7 +109717,7 @@ static void substSelect(
 **
 **     SELECT x+y AS a FROM t1 WHERE z<100 AND a>5
 **
-** The code generated for this simpification gives the same result
+** The code generated for this simplification gives the same result
 ** but only has to scan the data once.  And because indices might 
 ** exist on the table t1, a complete scan of the data might be
 ** avoided.
@@ -104590,7 +109726,10 @@ static void substSelect(
 **
 **   (1)  The subquery and the outer query do not both use aggregates.
 **
-**   (2)  The subquery is not an aggregate or the outer query is not a join.
+**   (2)  The subquery is not an aggregate or (2a) the outer query is not a join
+**        and (2b) the outer query does not use subqueries other than the one
+**        FROM-clause subquery that is a candidate for flattening.  (2b is
+**        due to ticket [2f7170d73bf9abf80] from 2015-02-09.)
 **
 **   (3)  The subquery is not the right operand of a left outer join
 **        (Originally ticket #306.  Strengthened by ticket #3300)
@@ -104614,8 +109753,10 @@ static void substSelect(
 **   (9)  The subquery does not use LIMIT or the outer query does not use
 **        aggregates.
 **
-**  (10)  The subquery does not use aggregates or the outer query does not
-**        use LIMIT.
+**  (**)  Restriction (10) was removed from the code on 2005-02-05 but we
+**        accidently carried the comment forward until 2014-09-15.  Original
+**        text: "The subquery does not use aggregates or the outer query does not
+**        use LIMIT."
 **
 **  (11)  The subquery and the outer query do not both have ORDER BY clauses.
 **
@@ -104678,6 +109819,11 @@ static void substSelect(
 **        parent to a compound query confuses the code that handles
 **        recursive queries in multiSelect().
 **
+**  (24)  The subquery is not an aggregate that uses the built-in min() or 
+**        or max() functions.  (Without this restriction, a query like:
+**        "SELECT x FROM (SELECT max(y), x FROM t1)" would not necessarily
+**        return the value X for which Y was maximal.)
+**
 **
 ** In this routine, the "p" parameter is a pointer to the outer query.
 ** The subquery is p->pSrc->a[iFrom].  isAgg is true if the outer query
@@ -104720,12 +109866,21 @@ static int flattenSubquery(
   iParent = pSubitem->iCursor;
   pSub = pSubitem->pSelect;
   assert( pSub!=0 );
-  if( isAgg && subqueryIsAgg ) return 0;                 /* Restriction (1)  */
-  if( subqueryIsAgg && pSrc->nSrc>1 ) return 0;          /* Restriction (2)  */
+  if( subqueryIsAgg ){
+    if( isAgg ) return 0;                                /* Restriction (1)   */
+    if( pSrc->nSrc>1 ) return 0;                         /* Restriction (2a)  */
+    if( (p->pWhere && ExprHasProperty(p->pWhere,EP_Subquery))
+     || (sqlite3ExprListFlags(p->pEList) & EP_Subquery)!=0
+     || (sqlite3ExprListFlags(p->pOrderBy) & EP_Subquery)!=0
+    ){
+      return 0;                                          /* Restriction (2b)  */
+    }
+  }
+    
   pSubSrc = pSub->pSrc;
   assert( pSubSrc );
   /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
-  ** not arbitrary expresssions, we allowed some combining of LIMIT and OFFSET
+  ** not arbitrary expressions, we allowed some combining of LIMIT and OFFSET
   ** because they could be computed at compile-time.  But when LIMIT and OFFSET
   ** became arbitrary expressions, we were forced to add restrictions (13)
   ** and (14). */
@@ -104750,8 +109905,14 @@ static int flattenSubquery(
   if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){
      return 0;         /* Restriction (21) */
   }
-  if( pSub->selFlags & SF_Recursive ) return 0;          /* Restriction (22)  */
-  if( (p->selFlags & SF_Recursive) && pSub->pPrior ) return 0;       /* (23)  */
+  testcase( pSub->selFlags & SF_Recursive );
+  testcase( pSub->selFlags & SF_MinMaxAgg );
+  if( pSub->selFlags & (SF_Recursive|SF_MinMaxAgg) ){
+    return 0; /* Restrictions (22) and (24) */
+  }
+  if( (p->selFlags & SF_Recursive) && pSub->pPrior ){
+    return 0; /* Restriction (23) */
+  }
 
   /* OBSOLETE COMMENT 1:
   ** Restriction 3:  If the subquery is a join, make sure the subquery is 
@@ -104825,6 +109986,8 @@ static int flattenSubquery(
   }
 
   /***** If we reach this point, flattening is permitted. *****/
+  SELECTTRACE(1,pParse,p,("flatten %s.%p from term %d\n",
+                   pSub->zSelName, pSub, iFrom));
 
   /* Authorize the subquery */
   pParse->zAuthContext = pSubitem->zName;
@@ -104877,6 +110040,7 @@ static int flattenSubquery(
     p->pLimit = 0;
     p->pOffset = 0;
     pNew = sqlite3SelectDup(db, p, 0);
+    sqlite3SelectSetName(pNew, pSub->zSelName);
     p->pOffset = pOffset;
     p->pLimit = pLimit;
     p->pOrderBy = pOrderBy;
@@ -104889,6 +110053,9 @@ static int flattenSubquery(
       if( pPrior ) pPrior->pNext = pNew;
       pNew->pNext = p;
       p->pPrior = pNew;
+      SELECTTRACE(2,pParse,p,
+         ("compound-subquery flattener creates %s.%p as peer\n",
+         pNew->zSelName, pNew));
     }
     if( db->mallocFailed ) return 1;
   }
@@ -105018,8 +110185,23 @@ static int flattenSubquery(
       pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
     }
     if( pSub->pOrderBy ){
+      /* At this point, any non-zero iOrderByCol values indicate that the
+      ** ORDER BY column expression is identical to the iOrderByCol'th
+      ** expression returned by SELECT statement pSub. Since these values
+      ** do not necessarily correspond to columns in SELECT statement pParent,
+      ** zero them before transfering the ORDER BY clause.
+      **
+      ** Not doing this may cause an error if a subsequent call to this
+      ** function attempts to flatten a compound sub-query into pParent
+      ** (the only way this can happen is if the compound sub-query is
+      ** currently part of pSub->pSrc). See ticket [d11a6e908f].  */
+      ExprList *pOrderBy = pSub->pOrderBy;
+      for(i=0; i<pOrderBy->nExpr; i++){
+        pOrderBy->a[i].u.x.iOrderByCol = 0;
+      }
       assert( pParent->pOrderBy==0 );
-      pParent->pOrderBy = pSub->pOrderBy;
+      assert( pSub->pPrior==0 );
+      pParent->pOrderBy = pOrderBy;
       pSub->pOrderBy = 0;
     }else if( pParent->pOrderBy ){
       substExprList(db, pParent->pOrderBy, iParent, pSub->pEList);
@@ -105065,6 +110247,13 @@ static int flattenSubquery(
   */
   sqlite3SelectDelete(db, pSub1);
 
+#if SELECTTRACE_ENABLED
+  if( sqlite3SelectTrace & 0x100 ){
+    sqlite3DebugPrintf("After flattening:\n");
+    sqlite3TreeViewSelect(0, p, 0);
+  }
+#endif
+
   return 1;
 }
 #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
@@ -105111,7 +110300,7 @@ static u8 minMaxQuery(AggInfo *pAggInfo, ExprList **ppMinMax){
 
 /*
 ** The select statement passed as the first argument is an aggregate query.
-** The second argment is the associated aggregate-info object. This 
+** The second argument is the associated aggregate-info object. This 
 ** function tests if the SELECT is of the form:
 **
 **   SELECT count(*) FROM <tbl>
@@ -105229,7 +110418,10 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){
   pNew->pOrderBy = 0;
   p->pPrior = 0;
   p->pNext = 0;
+  p->pWith = 0;
   p->selFlags &= ~SF_Compound;
+  assert( (p->selFlags & SF_Converted)==0 );
+  p->selFlags |= SF_Converted;
   assert( pNew->pPrior!=0 );
   pNew->pPrior->pNext = pNew;
   pNew->pLimit = 0;
@@ -105381,7 +110573,7 @@ static int withExpand(
     for(pLeft=pSel; pLeft->pPrior; pLeft=pLeft->pPrior);
     pEList = pLeft->pEList;
     if( pCte->pCols ){
-      if( pEList->nExpr!=pCte->pCols->nExpr ){
+      if( pEList && pEList->nExpr!=pCte->pCols->nExpr ){
         sqlite3ErrorMsg(pParse, "table %s has %d values for %d columns",
             pCte->zName, pEList->nExpr, pCte->pCols->nExpr
         );
@@ -105441,10 +110633,10 @@ static void selectPopWith(Walker *pWalker, Select *p){
 **         fill pTabList->a[].pSelect with a copy of the SELECT statement
 **         that implements the view.  A copy is made of the view's SELECT
 **         statement so that we can freely modify or delete that statement
-**         without worrying about messing up the presistent representation
+**         without worrying about messing up the persistent representation
 **         of the view.
 **
-**    (3)  Add terms to the WHERE clause to accomodate the NATURAL keyword
+**    (3)  Add terms to the WHERE clause to accommodate the NATURAL keyword
 **         on joins and the ON and USING clause of joins.
 **
 **    (4)  Scan the list of columns in the result set (pEList) looking
@@ -105472,7 +110664,9 @@ static int selectExpander(Walker *pWalker, Select *p){
   }
   pTabList = p->pSrc;
   pEList = p->pEList;
-  sqlite3WithPush(pParse, findRightmost(p)->pWith, 0);
+  if( pWalker->xSelectCallback2==selectPopWith ){
+    sqlite3WithPush(pParse, findRightmost(p)->pWith, 0);
+  }
 
   /* Make sure cursor numbers have been assigned to all entries in
   ** the FROM clause of the SELECT statement.
@@ -105506,7 +110700,7 @@ static int selectExpander(Walker *pWalker, Select *p){
       /* A sub-query in the FROM clause of a SELECT */
       assert( pSel!=0 );
       assert( pFrom->pTab==0 );
-      sqlite3WalkSelect(pWalker, pSel);
+      if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort;
       pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table));
       if( pTab==0 ) return WRC_Abort;
       pTab->nRef = 1;
@@ -105535,6 +110729,7 @@ static int selectExpander(Walker *pWalker, Select *p){
         if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
         assert( pFrom->pSelect==0 );
         pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
+        sqlite3SelectSetName(pFrom->pSelect, pTab->zName);
         sqlite3WalkSelect(pWalker, pFrom->pSelect);
       }
 #endif
@@ -105762,7 +110957,9 @@ static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
     sqlite3WalkSelect(&w, pSelect);
   }
   w.xSelectCallback = selectExpander;
-  w.xSelectCallback2 = selectPopWith;
+  if( (pSelect->selFlags & SF_MultiValue)==0 ){
+    w.xSelectCallback2 = selectPopWith;
+  }
   sqlite3WalkSelect(&w, pSelect);
 }
 
@@ -105946,7 +111143,8 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
     }
     if( pF->iDistinct>=0 ){
       addrNext = sqlite3VdbeMakeLabel(v);
-      assert( nArg==1 );
+      testcase( nArg==0 );  /* Error condition */
+      testcase( nArg>1 );   /* Also an error */
       codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg);
     }
     if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
@@ -106069,6 +111267,13 @@ SQLITE_PRIVATE int sqlite3Select(
   }
   if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
   memset(&sAggInfo, 0, sizeof(sAggInfo));
+#if SELECTTRACE_ENABLED
+  pParse->nSelectIndent++;
+  SELECTTRACE(1,pParse,p, ("begin processing:\n"));
+  if( sqlite3SelectTrace & 0x100 ){
+    sqlite3TreeViewSelect(0, p, 0);
+  }
+#endif
 
   assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistFifo );
   assert( p->pOrderBy==0 || pDest->eDest!=SRT_Fifo );
@@ -106095,6 +111300,13 @@ SQLITE_PRIVATE int sqlite3Select(
   }
   isAgg = (p->selFlags & SF_Aggregate)!=0;
   assert( pEList!=0 );
+#if SELECTTRACE_ENABLED
+  if( sqlite3SelectTrace & 0x100 ){
+    SELECTTRACE(0x100,pParse,p, ("after name resolution:\n"));
+    sqlite3TreeViewSelect(0, p, 0);
+  }
+#endif
+
 
   /* Begin generating code.
   */
@@ -106225,6 +111437,10 @@ SQLITE_PRIVATE int sqlite3Select(
   if( p->pPrior ){
     rc = multiSelect(pParse, p, pDest);
     explainSetInteger(pParse->iSelectId, iRestoreSelectId);
+#if SELECTTRACE_ENABLED
+    SELECTTRACE(1,pParse,p,("end compound-select processing\n"));
+    pParse->nSelectIndent--;
+#endif
     return rc;
   }
 #endif
@@ -106237,7 +111453,7 @@ SQLITE_PRIVATE int sqlite3Select(
   **
   ** is transformed to:
   **
-  **     SELECT xyz FROM ... GROUP BY xyz
+  **     SELECT xyz FROM ... GROUP BY xyz ORDER BY xyz
   **
   ** The second form is preferred as a single index (or temp-table) may be 
   ** used for both the ORDER BY and DISTINCT processing. As originally 
@@ -106250,7 +111466,6 @@ SQLITE_PRIVATE int sqlite3Select(
     p->selFlags &= ~SF_Distinct;
     p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
     pGroupBy = p->pGroupBy;
-    sSort.pOrderBy = 0;
     /* Notice that even thought SF_Distinct has been cleared from p->selFlags,
     ** the sDistinct.isTnct is still set.  Hence, isTnct represents the
     ** original setting of the SF_Distinct flag, not the current setting */
@@ -106266,12 +111481,13 @@ SQLITE_PRIVATE int sqlite3Select(
   */
   if( sSort.pOrderBy ){
     KeyInfo *pKeyInfo;
-    pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, 0);
+    pKeyInfo = keyInfoFromExprList(pParse, sSort.pOrderBy, 0, pEList->nExpr);
     sSort.iECursor = pParse->nTab++;
     sSort.addrSortIndex =
       sqlite3VdbeAddOp4(v, OP_OpenEphemeral,
-                           sSort.iECursor, sSort.pOrderBy->nExpr+2, 0,
-                           (char*)pKeyInfo, P4_KEYINFO);
+          sSort.iECursor, sSort.pOrderBy->nExpr+1+pEList->nExpr, 0,
+          (char*)pKeyInfo, P4_KEYINFO
+      );
   }else{
     sSort.addrSortIndex = -1;
   }
@@ -106402,7 +111618,7 @@ SQLITE_PRIVATE int sqlite3Select(
     sNC.pSrcList = pTabList;
     sNC.pAggInfo = &sAggInfo;
     sAggInfo.mnReg = pParse->nMem+1;
-    sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr+1 : 0;
+    sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0;
     sAggInfo.pGroupBy = pGroupBy;
     sqlite3ExprAnalyzeAggList(&sNC, pEList);
     sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy);
@@ -106439,7 +111655,7 @@ SQLITE_PRIVATE int sqlite3Select(
       ** will be converted into a Noop.  
       */
       sAggInfo.sortingIdx = pParse->nTab++;
-      pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0, 0);
+      pKeyInfo = keyInfoFromExprList(pParse, pGroupBy, 0, sAggInfo.nColumn);
       addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, 
           sAggInfo.sortingIdx, sAggInfo.nSortingColumn, 
           0, (char*)pKeyInfo, P4_KEYINFO);
@@ -106495,8 +111711,8 @@ SQLITE_PRIVATE int sqlite3Select(
 
         groupBySort = 1;
         nGroupBy = pGroupBy->nExpr;
-        nCol = nGroupBy + 1;
-        j = nGroupBy+1;
+        nCol = nGroupBy;
+        j = nGroupBy;
         for(i=0; i<sAggInfo.nColumn; i++){
           if( sAggInfo.aCol[i].iSorterColumn>=j ){
             nCol++;
@@ -106506,8 +111722,7 @@ SQLITE_PRIVATE int sqlite3Select(
         regBase = sqlite3GetTempRange(pParse, nCol);
         sqlite3ExprCacheClear(pParse);
         sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0);
-        sqlite3VdbeAddOp2(v, OP_Sequence, sAggInfo.sortingIdx,regBase+nGroupBy);
-        j = nGroupBy+1;
+        j = nGroupBy;
         for(i=0; i<sAggInfo.nColumn; i++){
           struct AggInfo_col *pCol = &sAggInfo.aCol[i];
           if( pCol->iSorterColumn>=j ){
@@ -106560,12 +111775,11 @@ SQLITE_PRIVATE int sqlite3Select(
       addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
       sqlite3ExprCacheClear(pParse);
       if( groupBySort ){
-        sqlite3VdbeAddOp2(v, OP_SorterData, sAggInfo.sortingIdx, sortOut);
+        sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx, sortOut,sortPTab);
       }
       for(j=0; j<pGroupBy->nExpr; j++){
         if( groupBySort ){
           sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j);
-          if( j==0 ) sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE);
         }else{
           sAggInfo.directMode = 1;
           sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
@@ -106805,10 +112019,9 @@ SQLITE_PRIVATE int sqlite3Select(
   */
   sqlite3VdbeResolveLabel(v, iEnd);
 
-  /* The SELECT was successfully coded.   Set the return code to 0
-  ** to indicate no errors.
-  */
-  rc = 0;
+  /* The SELECT has been coded. If there is an error in the Parse structure,
+  ** set the return code to 1. Otherwise 0. */
+  rc = (pParse->nErr>0);
 
   /* Control jumps to here if an error is encountered above, or upon
   ** successful coding of the SELECT.
@@ -106824,103 +112037,106 @@ select_end:
 
   sqlite3DbFree(db, sAggInfo.aCol);
   sqlite3DbFree(db, sAggInfo.aFunc);
+#if SELECTTRACE_ENABLED
+  SELECTTRACE(1,pParse,p,("end processing\n"));
+  pParse->nSelectIndent--;
+#endif
   return rc;
 }
 
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
+#ifdef SQLITE_DEBUG
 /*
 ** Generate a human-readable description of a the Select object.
 */
-static void explainOneSelect(Vdbe *pVdbe, Select *p){
-  sqlite3ExplainPrintf(pVdbe, "SELECT ");
-  if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
-    if( p->selFlags & SF_Distinct ){
-      sqlite3ExplainPrintf(pVdbe, "DISTINCT ");
-    }
-    if( p->selFlags & SF_Aggregate ){
-      sqlite3ExplainPrintf(pVdbe, "agg_flag ");
-    }
-    sqlite3ExplainNL(pVdbe);
-    sqlite3ExplainPrintf(pVdbe, "   ");
-  }
-  sqlite3ExplainExprList(pVdbe, p->pEList);
-  sqlite3ExplainNL(pVdbe);
+SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
+  int n = 0;
+  pView = sqlite3TreeViewPush(pView, moreToFollow);
+  sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p)",
+    ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
+    ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p
+  );
+  if( p->pSrc && p->pSrc->nSrc ) n++;
+  if( p->pWhere ) n++;
+  if( p->pGroupBy ) n++;
+  if( p->pHaving ) n++;
+  if( p->pOrderBy ) n++;
+  if( p->pLimit ) n++;
+  if( p->pOffset ) n++;
+  if( p->pPrior ) n++;
+  sqlite3TreeViewExprList(pView, p->pEList, (n--)>0, "result-set");
   if( p->pSrc && p->pSrc->nSrc ){
     int i;
-    sqlite3ExplainPrintf(pVdbe, "FROM ");
-    sqlite3ExplainPush(pVdbe);
+    pView = sqlite3TreeViewPush(pView, (n--)>0);
+    sqlite3TreeViewLine(pView, "FROM");
     for(i=0; i<p->pSrc->nSrc; i++){
       struct SrcList_item *pItem = &p->pSrc->a[i];
-      sqlite3ExplainPrintf(pVdbe, "{%d,*} = ", pItem->iCursor);
-      if( pItem->pSelect ){
-        sqlite3ExplainSelect(pVdbe, pItem->pSelect);
-        if( pItem->pTab ){
-          sqlite3ExplainPrintf(pVdbe, " (tabname=%s)", pItem->pTab->zName);
-        }
+      StrAccum x;
+      char zLine[100];
+      sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
+      sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor);
+      if( pItem->zDatabase ){
+        sqlite3XPrintf(&x, 0, " %s.%s", pItem->zDatabase, pItem->zName);
       }else if( pItem->zName ){
-        sqlite3ExplainPrintf(pVdbe, "%s", pItem->zName);
+        sqlite3XPrintf(&x, 0, " %s", pItem->zName);
+      }
+      if( pItem->pTab ){
+        sqlite3XPrintf(&x, 0, " tabname=%Q", pItem->pTab->zName);
       }
       if( pItem->zAlias ){
-        sqlite3ExplainPrintf(pVdbe, " (AS %s)", pItem->zAlias);
+        sqlite3XPrintf(&x, 0, " (AS %s)", pItem->zAlias);
       }
       if( pItem->jointype & JT_LEFT ){
-        sqlite3ExplainPrintf(pVdbe, " LEFT-JOIN");
+        sqlite3XPrintf(&x, 0, " LEFT-JOIN");
       }
-      sqlite3ExplainNL(pVdbe);
+      sqlite3StrAccumFinish(&x);
+      sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1); 
+      if( pItem->pSelect ){
+        sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
+      }
+      sqlite3TreeViewPop(pView);
     }
-    sqlite3ExplainPop(pVdbe);
+    sqlite3TreeViewPop(pView);
   }
   if( p->pWhere ){
-    sqlite3ExplainPrintf(pVdbe, "WHERE ");
-    sqlite3ExplainExpr(pVdbe, p->pWhere);
-    sqlite3ExplainNL(pVdbe);
+    sqlite3TreeViewItem(pView, "WHERE", (n--)>0);
+    sqlite3TreeViewExpr(pView, p->pWhere, 0);
+    sqlite3TreeViewPop(pView);
   }
   if( p->pGroupBy ){
-    sqlite3ExplainPrintf(pVdbe, "GROUPBY ");
-    sqlite3ExplainExprList(pVdbe, p->pGroupBy);
-    sqlite3ExplainNL(pVdbe);
+    sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY");
   }
   if( p->pHaving ){
-    sqlite3ExplainPrintf(pVdbe, "HAVING ");
-    sqlite3ExplainExpr(pVdbe, p->pHaving);
-    sqlite3ExplainNL(pVdbe);
+    sqlite3TreeViewItem(pView, "HAVING", (n--)>0);
+    sqlite3TreeViewExpr(pView, p->pHaving, 0);
+    sqlite3TreeViewPop(pView);
   }
   if( p->pOrderBy ){
-    sqlite3ExplainPrintf(pVdbe, "ORDERBY ");
-    sqlite3ExplainExprList(pVdbe, p->pOrderBy);
-    sqlite3ExplainNL(pVdbe);
+    sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY");
   }
   if( p->pLimit ){
-    sqlite3ExplainPrintf(pVdbe, "LIMIT ");
-    sqlite3ExplainExpr(pVdbe, p->pLimit);
-    sqlite3ExplainNL(pVdbe);
+    sqlite3TreeViewItem(pView, "LIMIT", (n--)>0);
+    sqlite3TreeViewExpr(pView, p->pLimit, 0);
+    sqlite3TreeViewPop(pView);
   }
   if( p->pOffset ){
-    sqlite3ExplainPrintf(pVdbe, "OFFSET ");
-    sqlite3ExplainExpr(pVdbe, p->pOffset);
-    sqlite3ExplainNL(pVdbe);
+    sqlite3TreeViewItem(pView, "OFFSET", (n--)>0);
+    sqlite3TreeViewExpr(pView, p->pOffset, 0);
+    sqlite3TreeViewPop(pView);
   }
-}
-SQLITE_PRIVATE void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){
-  if( p==0 ){
-    sqlite3ExplainPrintf(pVdbe, "(null-select)");
-    return;
-  }
-  sqlite3ExplainPush(pVdbe);
-  while( p ){
-    explainOneSelect(pVdbe, p);
-    p = p->pNext;
-    if( p==0 ) break;
-    sqlite3ExplainNL(pVdbe);
-    sqlite3ExplainPrintf(pVdbe, "%s\n", selectOpName(p->op));
+  if( p->pPrior ){
+    const char *zOp = "UNION";
+    switch( p->op ){
+      case TK_ALL:         zOp = "UNION ALL";  break;
+      case TK_INTERSECT:   zOp = "INTERSECT";  break;
+      case TK_EXCEPT:      zOp = "EXCEPT";     break;
+    }
+    sqlite3TreeViewItem(pView, zOp, (n--)>0);
+    sqlite3TreeViewSelect(pView, p->pPrior, 0);
+    sqlite3TreeViewPop(pView);
   }
-  sqlite3ExplainPrintf(pVdbe, "END");
-  sqlite3ExplainPop(pVdbe);
+  sqlite3TreeViewPop(pView);
 }
-
-/* End of the structure debug printing code
-*****************************************************************************/
-#endif /* defined(SQLITE_ENABLE_TREE_EXPLAIN) */
+#endif /* SQLITE_DEBUG */
 
 /************** End of select.c **********************************************/
 /************** Begin file table.c *******************************************/
@@ -106954,10 +112170,10 @@ SQLITE_PRIVATE void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){
 typedef struct TabResult {
   char **azResult;   /* Accumulated output */
   char *zErrMsg;     /* Error message text, if an error occurs */
-  int nAlloc;        /* Slots allocated for azResult[] */
-  int nRow;          /* Number of rows in the result */
-  int nColumn;       /* Number of columns in the result */
-  int nData;         /* Slots used in azResult[].  (nRow+1)*nColumn */
+  u32 nAlloc;        /* Slots allocated for azResult[] */
+  u32 nRow;          /* Number of rows in the result */
+  u32 nColumn;       /* Number of columns in the result */
+  u32 nData;         /* Slots used in azResult[].  (nRow+1)*nColumn */
   int rc;            /* Return code from sqlite3_exec() */
 } TabResult;
 
@@ -106983,7 +112199,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
   if( p->nData + need > p->nAlloc ){
     char **azNew;
     p->nAlloc = p->nAlloc*2 + need;
-    azNew = sqlite3_realloc( p->azResult, sizeof(char*)*p->nAlloc );
+    azNew = sqlite3_realloc64( p->azResult, sizeof(char*)*p->nAlloc );
     if( azNew==0 ) goto malloc_failed;
     p->azResult = azNew;
   }
@@ -106998,7 +112214,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
       if( z==0 ) goto malloc_failed;
       p->azResult[p->nData++] = z;
     }
-  }else if( p->nColumn!=nCol ){
+  }else if( (int)p->nColumn!=nCol ){
     sqlite3_free(p->zErrMsg);
     p->zErrMsg = sqlite3_mprintf(
        "sqlite3_get_table() called with two or more incompatible queries"
@@ -107015,7 +112231,7 @@ static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){
         z = 0;
       }else{
         int n = sqlite3Strlen30(argv[i])+1;
-        z = sqlite3_malloc( n );
+        z = sqlite3_malloc64( n );
         if( z==0 ) goto malloc_failed;
         memcpy(z, argv[i], n);
       }
@@ -107040,7 +112256,7 @@ malloc_failed:
 ** Instead, the entire table should be passed to sqlite3_free_table() when
 ** the calling procedure is finished using it.
 */
-SQLITE_API int sqlite3_get_table(
+SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
   sqlite3 *db,                /* The database on which the SQL executes */
   const char *zSql,           /* The SQL to be executed */
   char ***pazResult,          /* Write the result table here */
@@ -107051,6 +112267,9 @@ SQLITE_API int sqlite3_get_table(
   int rc;
   TabResult res;
 
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !sqlite3SafetyCheckOk(db) || pazResult==0 ) return SQLITE_MISUSE_BKPT;
+#endif
   *pazResult = 0;
   if( pnColumn ) *pnColumn = 0;
   if( pnRow ) *pnRow = 0;
@@ -107061,7 +112280,7 @@ SQLITE_API int sqlite3_get_table(
   res.nData = 1;
   res.nAlloc = 20;
   res.rc = SQLITE_OK;
-  res.azResult = sqlite3_malloc(sizeof(char*)*res.nAlloc );
+  res.azResult = sqlite3_malloc64(sizeof(char*)*res.nAlloc );
   if( res.azResult==0 ){
      db->errCode = SQLITE_NOMEM;
      return SQLITE_NOMEM;
@@ -107089,7 +112308,7 @@ SQLITE_API int sqlite3_get_table(
   }
   if( res.nAlloc>res.nData ){
     char **azNew;
-    azNew = sqlite3_realloc( res.azResult, sizeof(char*)*res.nData );
+    azNew = sqlite3_realloc64( res.azResult, sizeof(char*)*res.nData );
     if( azNew==0 ){
       sqlite3_free_table(&res.azResult[1]);
       db->errCode = SQLITE_NOMEM;
@@ -107106,8 +112325,8 @@ SQLITE_API int sqlite3_get_table(
 /*
 ** This routine frees the space the sqlite3_get_table() malloced.
 */
-SQLITE_API void sqlite3_free_table(
-  char **azResult            /* Result returned from from sqlite3_get_table() */
+SQLITE_API void SQLITE_STDCALL sqlite3_free_table(
+  char **azResult            /* Result returned from sqlite3_get_table() */
 ){
   if( azResult ){
     int i, n;
@@ -107251,7 +112470,7 @@ SQLITE_PRIVATE void sqlite3BeginTrigger(
   **                                                 ^^^^^^^^
   **
   ** To maintain backwards compatibility, ignore the database
-  ** name on pTableName if we are reparsing our of SQLITE_MASTER.
+  ** name on pTableName if we are reparsing out of SQLITE_MASTER.
   */
   if( db->init.busy && iDb!=1 ){
     sqlite3DbFree(db, pTableName->a[0].zDatabase);
@@ -107304,8 +112523,7 @@ SQLITE_PRIVATE void sqlite3BeginTrigger(
     goto trigger_cleanup;
   }
   assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
-  if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),
-                      zName, sqlite3Strlen30(zName)) ){
+  if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){
     if( !noErr ){
       sqlite3ErrorMsg(pParse, "trigger %T already exists", pName);
     }else{
@@ -107318,7 +112536,6 @@ SQLITE_PRIVATE void sqlite3BeginTrigger(
   /* Do not create a trigger on a system table */
   if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
     sqlite3ErrorMsg(pParse, "cannot create trigger on system table");
-    pParse->nErr++;
     goto trigger_cleanup;
   }
 
@@ -107448,13 +112665,12 @@ SQLITE_PRIVATE void sqlite3FinishTrigger(
     Trigger *pLink = pTrig;
     Hash *pHash = &db->aDb[iDb].pSchema->trigHash;
     assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
-    pTrig = sqlite3HashInsert(pHash, zName, sqlite3Strlen30(zName), pTrig);
+    pTrig = sqlite3HashInsert(pHash, zName, pTrig);
     if( pTrig ){
       db->mallocFailed = 1;
     }else if( pLink->pSchema==pLink->pTabSchema ){
       Table *pTab;
-      int n = sqlite3Strlen30(pLink->table);
-      pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table, n);
+      pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table);
       assert( pTab!=0 );
       pLink->pNext = pTab->pTrigger;
       pTab->pTrigger = pLink;
@@ -107499,12 +112715,12 @@ static TriggerStep *triggerStepAllocate(
 ){
   TriggerStep *pTriggerStep;
 
-  pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n);
+  pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
   if( pTriggerStep ){
     char *z = (char*)&pTriggerStep[1];
     memcpy(z, pName->z, pName->n);
-    pTriggerStep->target.z = z;
-    pTriggerStep->target.n = pName->n;
+    sqlite3Dequote(z);
+    pTriggerStep->zTarget = z;
     pTriggerStep->op = op;
   }
   return pTriggerStep;
@@ -107613,7 +112829,6 @@ SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr)
   int i;
   const char *zDb;
   const char *zName;
-  int nName;
   sqlite3 *db = pParse->db;
 
   if( db->mallocFailed ) goto drop_trigger_cleanup;
@@ -107624,13 +112839,12 @@ SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr)
   assert( pName->nSrc==1 );
   zDb = pName->a[0].zDatabase;
   zName = pName->a[0].zName;
-  nName = sqlite3Strlen30(zName);
   assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) );
   for(i=OMIT_TEMPDB; i<db->nDb; i++){
     int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
     if( zDb && sqlite3StrICmp(db->aDb[j].zName, zDb) ) continue;
     assert( sqlite3SchemaMutexHeld(db, j, 0) );
-    pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName, nName);
+    pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName);
     if( pTrigger ) break;
   }
   if( !pTrigger ){
@@ -107653,8 +112867,7 @@ drop_trigger_cleanup:
 ** is set on.
 */
 static Table *tableOfTrigger(Trigger *pTrigger){
-  int n = sqlite3Strlen30(pTrigger->table);
-  return sqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table, n);
+  return sqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table);
 }
 
 
@@ -107726,7 +112939,7 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const ch
 
   assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
   pHash = &(db->aDb[iDb].pSchema->trigHash);
-  pTrigger = sqlite3HashInsert(pHash, zName, sqlite3Strlen30(zName), 0);
+  pTrigger = sqlite3HashInsert(pHash, zName, 0);
   if( ALWAYS(pTrigger) ){
     if( pTrigger->pSchema==pTrigger->pTabSchema ){
       Table *pTab = tableOfTrigger(pTrigger);
@@ -107790,7 +113003,7 @@ SQLITE_PRIVATE Trigger *sqlite3TriggersExist(
 }
 
 /*
-** Convert the pStep->target token into a SrcList and return a pointer
+** Convert the pStep->zTarget string into a SrcList and return a pointer
 ** to that SrcList.
 **
 ** This routine adds a specific database name, if needed, to the target when
@@ -107803,17 +113016,17 @@ static SrcList *targetSrcList(
   Parse *pParse,       /* The parsing context */
   TriggerStep *pStep   /* The trigger containing the target token */
 ){
+  sqlite3 *db = pParse->db;
   int iDb;             /* Index of the database to use */
   SrcList *pSrc;       /* SrcList to be returned */
 
-  pSrc = sqlite3SrcListAppend(pParse->db, 0, &pStep->target, 0);
+  pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
   if( pSrc ){
     assert( pSrc->nSrc>0 );
-    assert( pSrc->a!=0 );
-    iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
+    pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget);
+    iDb = sqlite3SchemaToIndex(db, pStep->pTrig->pSchema);
     if( iDb==0 || iDb>=2 ){
-      sqlite3 *db = pParse->db;
-      assert( iDb<pParse->db->nDb );
+      assert( iDb<db->nDb );
       pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
     }
   }
@@ -107925,6 +113138,7 @@ static void transferParseError(Parse *pTo, Parse *pFrom){
   if( pTo->nErr==0 ){
     pTo->zErrMsg = pFrom->zErrMsg;
     pTo->nErr = pFrom->nErr;
+    pTo->rc = pFrom->rc;
   }else{
     sqlite3DbFree(pFrom->db, pFrom->zErrMsg);
   }
@@ -108577,7 +113791,7 @@ SQLITE_PRIVATE void sqlite3Update(
   }
 
   /* If we are trying to update a view, realize that view into
-  ** a ephemeral table.
+  ** an ephemeral table.
   */
 #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
   if( isView ){
@@ -108681,8 +113895,8 @@ SQLITE_PRIVATE void sqlite3Update(
 
   /* Top of the update loop */
   if( okOnePass ){
-    if( aToOpen[iDataCur-iBaseCur] ){
-      assert( pPk!=0 );
+    if( aToOpen[iDataCur-iBaseCur] && !isView ){
+      assert( pPk );
       sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey, nKey);
       VdbeCoverageNeverTaken(v);
     }
@@ -108738,7 +113952,7 @@ SQLITE_PRIVATE void sqlite3Update(
   }
 
   /* Populate the array of registers beginning at regNew with the new
-  ** row data. This array is used to check constaints, create the new
+  ** row data. This array is used to check constants, create the new
   ** table and index records, and as the values for any new.* references
   ** made by triggers.
   **
@@ -108918,7 +114132,7 @@ update_cleanup:
   return;
 }
 /* Make sure "isView" and other macros defined above are undefined. Otherwise
-** thely may interfere with compilation of other functions in this file
+** they may interfere with compilation of other functions in this file
 ** (or in another file, if this file becomes part of the amalgamation).  */
 #ifdef isView
  #undef isView
@@ -108931,7 +114145,7 @@ update_cleanup:
 /*
 ** Generate code for an UPDATE of a virtual table.
 **
-** The strategy is that we create an ephemerial table that contains
+** The strategy is that we create an ephemeral table that contains
 ** for each row to be changed:
 **
 **   (A)  The original rowid of that row.
@@ -108939,7 +114153,7 @@ update_cleanup:
 **   (C)  The content of every column in the row.
 **
 ** Then we loop over this ephemeral table and for each row in
-** the ephermeral table call VUpdate.
+** the ephemeral table call VUpdate.
 **
 ** When finished, drop the ephemeral table.
 **
@@ -109112,14 +114326,14 @@ static int execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
 ** step (3) requires additional temporary disk space approximately equal
 ** to the size of the original database for the rollback journal.
 ** Hence, temporary disk space that is approximately 2x the size of the
-** orginal database is required.  Every page of the database is written
+** original database is required.  Every page of the database is written
 ** approximately 3 times:  Once for step (2) and twice for step (3).
 ** Two writes per page are required in step (3) because the original
 ** database content must be written into the rollback journal prior to
 ** overwriting the database with the vacuumed content.
 **
 ** Only 1x temporary space and only 1x writes would be required if
-** the copy of step (3) were replace by deleting the original database
+** the copy of step (3) were replaced by deleting the original database
 ** and renaming the transient database as the original.  But that will
 ** not work if other processes are attached to the original database.
 ** And a power loss in between deleting the original and renaming the
@@ -109209,7 +114423,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
   ** cause problems for the call to BtreeSetPageSize() below.  */
   sqlite3BtreeCommit(pTemp);
 
-  nRes = sqlite3BtreeGetReserve(pMain);
+  nRes = sqlite3BtreeGetOptimalReserve(pMain);
 
   /* A VACUUM cannot change the pagesize of an encrypted database. */
 #ifdef SQLITE_HAS_CODEC
@@ -109275,6 +114489,8 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
   ** an "INSERT INTO vacuum_db.xxx SELECT * FROM main.xxx;" to copy
   ** the contents to the temporary database.
   */
+  assert( (db->flags & SQLITE_Vacuum)==0 );
+  db->flags |= SQLITE_Vacuum;
   rc = execExecSql(db, pzErrMsg,
       "SELECT 'INSERT INTO vacuum_db.' || quote(name) "
       "|| ' SELECT * FROM main.' || quote(name) || ';'"
@@ -109282,6 +114498,8 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){
       "WHERE type = 'table' AND name!='sqlite_sequence' "
       "  AND coalesce(rootpage,1)>0"
   );
+  assert( (db->flags & SQLITE_Vacuum)!=0 );
+  db->flags &= ~SQLITE_Vacuum;
   if( rc!=SQLITE_OK ) goto end_of_vacuum;
 
   /* Copy over the sequence table
@@ -109420,6 +114638,8 @@ end_of_vacuum:
 struct VtabCtx {
   VTable *pVTable;    /* The virtual table being constructed */
   Table *pTab;        /* The Table object to which the virtual table belongs */
+  VtabCtx *pPrior;    /* Parent context (if any) */
+  int bDeclared;      /* True after sqlite3_declare_vtab() is called */
 };
 
 /*
@@ -109439,7 +114659,7 @@ static int createModule(
 
   sqlite3_mutex_enter(db->mutex);
   nName = sqlite3Strlen30(zName);
-  if( sqlite3HashFind(&db->aModule, zName, nName) ){
+  if( sqlite3HashFind(&db->aModule, zName) ){
     rc = SQLITE_MISUSE_BKPT;
   }else{
     Module *pMod;
@@ -109452,7 +114672,7 @@ static int createModule(
       pMod->pModule = pModule;
       pMod->pAux = pAux;
       pMod->xDestroy = xDestroy;
-      pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,nName,(void*)pMod);
+      pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod);
       assert( pDel==0 || pDel==pMod );
       if( pDel ){
         db->mallocFailed = 1;
@@ -109471,25 +114691,31 @@ static int createModule(
 /*
 ** External API function used to create a new virtual-table module.
 */
-SQLITE_API int sqlite3_create_module(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_module(
   sqlite3 *db,                    /* Database in which module is registered */
   const char *zName,              /* Name assigned to this module */
   const sqlite3_module *pModule,  /* The definition of the module */
   void *pAux                      /* Context pointer for xCreate/xConnect */
 ){
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
+#endif
   return createModule(db, zName, pModule, pAux, 0);
 }
 
 /*
 ** External API function used to create a new virtual-table module.
 */
-SQLITE_API int sqlite3_create_module_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_module_v2(
   sqlite3 *db,                    /* Database in which module is registered */
   const char *zName,              /* Name assigned to this module */
   const sqlite3_module *pModule,  /* The definition of the module */
   void *pAux,                     /* Context pointer for xCreate/xConnect */
   void (*xDestroy)(void *)        /* Module destructor function */
 ){
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT;
+#endif
   return createModule(db, zName, pModule, pAux, xDestroy);
 }
 
@@ -109722,7 +114948,12 @@ SQLITE_PRIVATE void sqlite3VtabBeginParse(
   addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
   addModuleArgument(db, pTable, 0);
   addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
-  pParse->sNameToken.n = (int)(&pModuleName->z[pModuleName->n] - pName1->z);
+  assert( (pParse->sNameToken.z==pName2->z && pName2->z!=0)
+       || (pParse->sNameToken.z==pName1->z && pName2->z==0)
+  );
+  pParse->sNameToken.n = (int)(
+      &pModuleName->z[pModuleName->n] - pParse->sNameToken.z
+  );
 
 #ifndef SQLITE_OMIT_AUTHORIZATION
   /* Creating a virtual table invokes the authorization callback twice.
@@ -109774,6 +115005,7 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
     char *zStmt;
     char *zWhere;
     int iDb;
+    int iReg;
     Vdbe *v;
 
     /* Compute the complete text of the CREATE VIRTUAL TABLE statement */
@@ -109808,8 +115040,10 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
     sqlite3VdbeAddOp2(v, OP_Expire, 0, 0);
     zWhere = sqlite3MPrintf(db, "name='%q' AND type='table'", pTab->zName);
     sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere);
-    sqlite3VdbeAddOp4(v, OP_VCreate, iDb, 0, 0, 
-                         pTab->zName, sqlite3Strlen30(pTab->zName) + 1);
+
+    iReg = ++pParse->nMem;
+    sqlite3VdbeAddOp4(v, OP_String8, 0, iReg, 0, pTab->zName, 0);
+    sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg);
   }
 
   /* If we are rereading the sqlite_master table create the in-memory
@@ -109821,9 +115055,8 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
     Table *pOld;
     Schema *pSchema = pTab->pSchema;
     const char *zName = pTab->zName;
-    int nName = sqlite3Strlen30(zName);
     assert( sqlite3SchemaMutexHeld(db, 0, pSchema) );
-    pOld = sqlite3HashInsert(&pSchema->tblHash, zName, nName, pTab);
+    pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab);
     if( pOld ){
       db->mallocFailed = 1;
       assert( pTab==pOld );  /* Malloc must have failed inside HashInsert() */
@@ -109853,7 +115086,7 @@ SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse *pParse, Token *p){
     pArg->z = p->z;
     pArg->n = p->n;
   }else{
-    assert(pArg->z < p->z);
+    assert(pArg->z <= p->z);
     pArg->n = (int)(&p->z[p->n] - pArg->z);
   }
 }
@@ -109870,15 +115103,27 @@ static int vtabCallConstructor(
   int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**),
   char **pzErr
 ){
-  VtabCtx sCtx, *pPriorCtx;
+  VtabCtx sCtx;
   VTable *pVTable;
   int rc;
   const char *const*azArg = (const char *const*)pTab->azModuleArg;
   int nArg = pTab->nModuleArg;
   char *zErr = 0;
-  char *zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
+  char *zModuleName;
   int iDb;
+  VtabCtx *pCtx;
+
+  /* Check that the virtual-table is not already being initialized */
+  for(pCtx=db->pVtabCtx; pCtx; pCtx=pCtx->pPrior){
+    if( pCtx->pTab==pTab ){
+      *pzErr = sqlite3MPrintf(db, 
+          "vtable constructor called recursively: %s", pTab->zName
+      );
+      return SQLITE_LOCKED;
+    }
+  }
 
+  zModuleName = sqlite3MPrintf(db, "%s", pTab->zName);
   if( !zModuleName ){
     return SQLITE_NOMEM;
   }
@@ -109899,11 +115144,13 @@ static int vtabCallConstructor(
   assert( xConstruct );
   sCtx.pTab = pTab;
   sCtx.pVTable = pVTable;
-  pPriorCtx = db->pVtabCtx;
+  sCtx.pPrior = db->pVtabCtx;
+  sCtx.bDeclared = 0;
   db->pVtabCtx = &sCtx;
   rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
-  db->pVtabCtx = pPriorCtx;
+  db->pVtabCtx = sCtx.pPrior;
   if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
+  assert( sCtx.pTab==pTab );
 
   if( SQLITE_OK!=rc ){
     if( zErr==0 ){
@@ -109916,15 +115163,17 @@ static int vtabCallConstructor(
   }else if( ALWAYS(pVTable->pVtab) ){
     /* Justification of ALWAYS():  A correct vtab constructor must allocate
     ** the sqlite3_vtab object if successful.  */
+    memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0]));
     pVTable->pVtab->pModule = pMod->pModule;
     pVTable->nRef = 1;
-    if( sCtx.pTab ){
+    if( sCtx.bDeclared==0 ){
       const char *zFormat = "vtable constructor did not declare schema: %s";
       *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
       sqlite3VtabUnlock(pVTable);
       rc = SQLITE_ERROR;
     }else{
       int iCol;
+      u8 oooHidden = 0;
       /* If everything went according to plan, link the new VTable structure
       ** into the linked list headed by pTab->pVTable. Then loop through the 
       ** columns of the table to see if any of them contain the token "hidden".
@@ -109937,7 +115186,10 @@ static int vtabCallConstructor(
         char *zType = pTab->aCol[iCol].zType;
         int nType;
         int i = 0;
-        if( !zType ) continue;
+        if( !zType ){
+          pTab->tabFlags |= oooHidden;
+          continue;
+        }
         nType = sqlite3Strlen30(zType);
         if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){
           for(i=0; i<nType; i++){
@@ -109960,6 +115212,9 @@ static int vtabCallConstructor(
             zType[i-1] = '\0';
           }
           pTab->aCol[iCol].colFlags |= COLFLAG_HIDDEN;
+          oooHidden = TF_OOOHidden;
+        }else{
+          pTab->tabFlags |= oooHidden;
         }
       }
     }
@@ -109989,7 +115244,7 @@ SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){
 
   /* Locate the required virtual table module */
   zMod = pTab->azModuleArg[0];
-  pMod = (Module*)sqlite3HashFind(&db->aModule, zMod, sqlite3Strlen30(zMod));
+  pMod = (Module*)sqlite3HashFind(&db->aModule, zMod);
 
   if( !pMod ){
     const char *zModule = pTab->azModuleArg[0];
@@ -110057,7 +115312,7 @@ SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab,
 
   /* Locate the required virtual table module */
   zMod = pTab->azModuleArg[0];
-  pMod = (Module*)sqlite3HashFind(&db->aModule, zMod, sqlite3Strlen30(zMod));
+  pMod = (Module*)sqlite3HashFind(&db->aModule, zMod);
 
   /* If the module has been registered and includes a Create method, 
   ** invoke it now. If the module has not been registered, return an 
@@ -110087,19 +115342,26 @@ SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab,
 ** valid to call this function from within the xCreate() or xConnect() of a
 ** virtual table module.
 */
-SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
+SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
+  VtabCtx *pCtx;
   Parse *pParse;
-
   int rc = SQLITE_OK;
   Table *pTab;
   char *zErr = 0;
 
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){
+    return SQLITE_MISUSE_BKPT;
+  }
+#endif
   sqlite3_mutex_enter(db->mutex);
-  if( !db->pVtabCtx || !(pTab = db->pVtabCtx->pTab) ){
-    sqlite3Error(db, SQLITE_MISUSE, 0);
+  pCtx = db->pVtabCtx;
+  if( !pCtx || pCtx->bDeclared ){
+    sqlite3Error(db, SQLITE_MISUSE);
     sqlite3_mutex_leave(db->mutex);
     return SQLITE_MISUSE_BKPT;
   }
+  pTab = pCtx->pTab;
   assert( (pTab->tabFlags & TF_Virtual)!=0 );
 
   pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
@@ -110122,9 +115384,9 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
         pParse->pNewTable->nCol = 0;
         pParse->pNewTable->aCol = 0;
       }
-      db->pVtabCtx->pTab = 0;
+      pCtx->bDeclared = 1;
     }else{
-      sqlite3Error(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
+      sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
       sqlite3DbFree(db, zErr);
       rc = SQLITE_ERROR;
     }
@@ -110157,11 +115419,15 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab
 
   pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName);
   if( ALWAYS(pTab!=0 && pTab->pVTable!=0) ){
-    VTable *p = vtabDisconnectAll(db, pTab);
-
-    assert( rc==SQLITE_OK );
+    VTable *p;
+    for(p=pTab->pVTable; p; p=p->pNext){
+      assert( p->pVtab );
+      if( p->pVtab->nRef>0 ){
+        return SQLITE_LOCKED;
+      }
+    }
+    p = vtabDisconnectAll(db, pTab);
     rc = p->pMod->pModule->xDestroy(p->pVtab);
-
     /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */
     if( rc==SQLITE_OK ){
       assert( pTab->pVTable==p && p->pNext==0 );
@@ -110312,7 +115578,7 @@ SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){
   int rc = SQLITE_OK;
 
   assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN );
-  assert( iSavepoint>=0 );
+  assert( iSavepoint>=-1 );
   if( db->aVTrans ){
     int i;
     for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){
@@ -110430,7 +115696,7 @@ SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
     if( pTab==pToplevel->apVtabLock[i] ) return;
   }
   n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]);
-  apVtabLock = sqlite3_realloc(pToplevel->apVtabLock, n);
+  apVtabLock = sqlite3_realloc64(pToplevel->apVtabLock, n);
   if( apVtabLock ){
     pToplevel->apVtabLock = apVtabLock;
     pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab;
@@ -110446,10 +115712,13 @@ SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
 ** The results of this routine are undefined unless it is called from
 ** within an xUpdate method.
 */
-SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *db){
+SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *db){
   static const unsigned char aMap[] = { 
     SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE 
   };
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+#endif
   assert( OE_Rollback==1 && OE_Abort==2 && OE_Fail==3 );
   assert( OE_Ignore==4 && OE_Replace==5 );
   assert( db->vtabOnConflict>=1 && db->vtabOnConflict<=5 );
@@ -110461,12 +115730,14 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *db){
 ** the SQLite core with additional information about the behavior
 ** of the virtual table being implemented.
 */
-SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
+SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3 *db, int op, ...){
   va_list ap;
   int rc = SQLITE_OK;
 
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
+#endif
   sqlite3_mutex_enter(db->mutex);
-
   va_start(ap, op);
   switch( op ){
     case SQLITE_VTAB_CONSTRAINT_SUPPORT: {
@@ -110485,7 +115756,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){
   }
   va_end(ap);
 
-  if( rc!=SQLITE_OK ) sqlite3Error(db, rc, 0);
+  if( rc!=SQLITE_OK ) sqlite3Error(db, rc);
   sqlite3_mutex_leave(db->mutex);
   return rc;
 }
@@ -110585,6 +115856,8 @@ struct WhereLevel {
   int addrCont;         /* Jump here to continue with the next loop cycle */
   int addrFirst;        /* First instruction of interior of the loop */
   int addrBody;         /* Beginning of the body of this loop */
+  int iLikeRepCntr;     /* LIKE range processing counter register */
+  int addrLikeRep;      /* LIKE range processing address */
   u8 iFrom;             /* Which entry in the FROM clause */
   u8 op, p3, p5;        /* Opcode, P3 & P5 of the opcode that ends the loop */
   int p1, p2;           /* Operands of the opcode used to ends the loop */
@@ -110601,6 +115874,9 @@ struct WhereLevel {
   } u;
   struct WhereLoop *pWLoop;  /* The selected WhereLoop object */
   Bitmask notReady;          /* FROM entries not usable at this level */
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+  int addrVisit;        /* Address at which row is visited */
+#endif
 };
 
 /*
@@ -110631,7 +115907,6 @@ struct WhereLoop {
   union {
     struct {               /* Information for internal btree tables */
       u16 nEq;               /* Number of equality constraints */
-      u16 nSkip;             /* Number of initial index columns to skip */
       Index *pIndex;         /* Index used, or NULL */
     } btree;
     struct {               /* Information for virtual tables */
@@ -110644,12 +115919,13 @@ struct WhereLoop {
   } u;
   u32 wsFlags;          /* WHERE_* flags describing the plan */
   u16 nLTerm;           /* Number of entries in aLTerm[] */
+  u16 nSkip;            /* Number of NULL aLTerm[] entries */
   /**** whereLoopXfer() copies fields above ***********************/
 # define WHERE_LOOP_XFER_SZ offsetof(WhereLoop,nLSlot)
   u16 nLSlot;           /* Number of slots allocated for aLTerm[] */
   WhereTerm **aLTerm;   /* WhereTerms used */
   WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */
-  WhereTerm *aLTermSpace[4];  /* Initial aLTerm[] space */
+  WhereTerm *aLTermSpace[3];  /* Initial aLTerm[] space */
 };
 
 /* This object holds the prerequisites and the cost of running a
@@ -110692,7 +115968,7 @@ static int whereLoopResize(sqlite3*, WhereLoop*, int);
 ** 1.  Then using those as a basis to compute the N best WherePath objects
 ** of length 2.  And so forth until the length of WherePaths equals the
 ** number of nodes in the FROM clause.  The best (lowest cost) WherePath
-** at the end is the choosen query plan.
+** at the end is the chosen query plan.
 */
 struct WherePath {
   Bitmask maskLoop;     /* Bitmask of all WhereLoop objects in this path */
@@ -110766,7 +116042,7 @@ struct WhereTerm {
   } u;
   LogEst truthProb;       /* Probability of truth for this expression */
   u16 eOperator;          /* A WO_xx value describing <op> */
-  u8 wtFlags;             /* TERM_xxx bit flags.  See below */
+  u16 wtFlags;            /* TERM_xxx bit flags.  See below */
   u8 nChild;              /* Number of children that must disable us */
   WhereClause *pWC;       /* The clause this term is part of */
   Bitmask prereqRight;    /* Bitmask of tables used by pExpr->pRight */
@@ -110788,6 +116064,9 @@ struct WhereTerm {
 #else
 #  define TERM_VNULL    0x00   /* Disabled if not using stat3 */
 #endif
+#define TERM_LIKEOPT    0x100  /* Virtual terms from the LIKE optimization */
+#define TERM_LIKECOND   0x200  /* Conditionally this LIKE operator term */
+#define TERM_LIKE       0x400  /* The original LIKE operator */
 
 /*
 ** An instance of the WhereScan object is used as an iterator for locating
@@ -110975,6 +116254,7 @@ struct WhereInfo {
 #define WHERE_AUTO_INDEX   0x00004000  /* Uses an ephemeral index */
 #define WHERE_SKIPSCAN     0x00008000  /* Uses the skip-scan algorithm */
 #define WHERE_UNQ_WANTED   0x00010000  /* WHERE_ONEROW would have been helpful*/
+#define WHERE_PARTIALIDX   0x00020000  /* The automatic index is partial */
 
 /************** End of whereInt.h ********************************************/
 /************** Continuing where we left off in where.c **********************/
@@ -111162,7 +116442,7 @@ static void whereClauseClear(WhereClause *pWC){
 ** calling this routine.  Such pointers may be reinitialized by referencing
 ** the pWC->a[] array.
 */
-static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
+static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){
   WhereTerm *pTerm;
   int idx;
   testcase( wtFlags & TERM_VIRTUAL );
@@ -111182,10 +116462,11 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
       sqlite3DbFree(db, pOld);
     }
     pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
+    memset(&pWC->a[pWC->nTerm], 0, sizeof(pWC->a[0])*(pWC->nSlot-pWC->nTerm));
   }
   pTerm = &pWC->a[idx = pWC->nTerm++];
   if( p && ExprHasProperty(p, EP_Unlikely) ){
-    pTerm->truthProb = sqlite3LogEst(p->iTable) - 99;
+    pTerm->truthProb = sqlite3LogEst(p->iTable) - 270;
   }else{
     pTerm->truthProb = 1;
   }
@@ -111214,13 +116495,14 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
 ** all terms of the WHERE clause.
 */
 static void whereSplit(WhereClause *pWC, Expr *pExpr, u8 op){
+  Expr *pE2 = sqlite3ExprSkipCollate(pExpr);
   pWC->op = op;
-  if( pExpr==0 ) return;
-  if( pExpr->op!=op ){
+  if( pE2==0 ) return;
+  if( pE2->op!=op ){
     whereClauseInsert(pWC, pExpr, 0);
   }else{
-    whereSplit(pWC, pExpr->pLeft, op);
-    whereSplit(pWC, pExpr->pRight, op);
+    whereSplit(pWC, pE2->pLeft, op);
+    whereSplit(pWC, pE2->pRight, op);
   }
 }
 
@@ -111325,11 +116607,6 @@ static int allowedOp(int op){
 }
 
 /*
-** Swap two objects of type TYPE.
-*/
-#define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
-
-/*
 ** Commute a comparison operator.  Expressions of the form "X op Y"
 ** are converted into "Y op X".
 **
@@ -111591,7 +116868,11 @@ static void exprAnalyzeAll(
 ** so and false if not.
 **
 ** In order for the operator to be optimizible, the RHS must be a string
-** literal that does not begin with a wildcard.  
+** literal that does not begin with a wildcard.  The LHS must be a column
+** that may only be NULL, a string, or a BLOB, never a number. (This means
+** that virtual tables cannot participate in the LIKE optimization.)  If the
+** collating sequence for the column on the LHS must be appropriate for
+** the operator.
 */
 static int isLikeOrGlob(
   Parse *pParse,    /* Parsing and code generating context */
@@ -111620,7 +116901,7 @@ static int isLikeOrGlob(
   pLeft = pList->a[1].pExpr;
   if( pLeft->op!=TK_COLUMN 
    || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT 
-   || IsVirtual(pLeft->pTab)
+   || IsVirtual(pLeft->pTab)  /* Value might be numeric */
   ){
     /* IMP: R-02065-49465 The left-hand side of the LIKE or GLOB operator must
     ** be the name of an indexed column with TEXT affinity. */
@@ -111661,7 +116942,7 @@ static int isLikeOrGlob(
           ** value of the variable means there is no need to invoke the LIKE
           ** function, then no OP_Variable will be added to the program.
           ** This causes problems for the sqlite3_bind_parameter_name()
-          ** API. To workaround them, add a dummy OP_Variable here.
+          ** API. To work around them, add a dummy OP_Variable here.
           */ 
           int r1 = sqlite3GetTempReg(pParse);
           sqlite3ExprCodeTarget(pParse, pRight, r1);
@@ -111721,6 +117002,88 @@ static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
   }
 }
 
+/*
+** Mark term iChild as being a child of term iParent
+*/
+static void markTermAsChild(WhereClause *pWC, int iChild, int iParent){
+  pWC->a[iChild].iParent = iParent;
+  pWC->a[iChild].truthProb = pWC->a[iParent].truthProb;
+  pWC->a[iParent].nChild++;
+}
+
+/*
+** Return the N-th AND-connected subterm of pTerm.  Or if pTerm is not
+** a conjunction, then return just pTerm when N==0.  If N is exceeds
+** the number of available subterms, return NULL.
+*/
+static WhereTerm *whereNthSubterm(WhereTerm *pTerm, int N){
+  if( pTerm->eOperator!=WO_AND ){
+    return N==0 ? pTerm : 0;
+  }
+  if( N<pTerm->u.pAndInfo->wc.nTerm ){
+    return &pTerm->u.pAndInfo->wc.a[N];
+  }
+  return 0;
+}
+
+/*
+** Subterms pOne and pTwo are contained within WHERE clause pWC.  The
+** two subterms are in disjunction - they are OR-ed together.
+**
+** If these two terms are both of the form:  "A op B" with the same
+** A and B values but different operators and if the operators are
+** compatible (if one is = and the other is <, for example) then
+** add a new virtual AND term to pWC that is the combination of the
+** two.
+**
+** Some examples:
+**
+**    x<y OR x=y    -->     x<=y
+**    x=y OR x=y    -->     x=y
+**    x<=y OR x<y   -->     x<=y
+**
+** The following is NOT generated:
+**
+**    x<y OR x>y    -->     x!=y     
+*/
+static void whereCombineDisjuncts(
+  SrcList *pSrc,         /* the FROM clause */
+  WhereClause *pWC,      /* The complete WHERE clause */
+  WhereTerm *pOne,       /* First disjunct */
+  WhereTerm *pTwo        /* Second disjunct */
+){
+  u16 eOp = pOne->eOperator | pTwo->eOperator;
+  sqlite3 *db;           /* Database connection (for malloc) */
+  Expr *pNew;            /* New virtual expression */
+  int op;                /* Operator for the combined expression */
+  int idxNew;            /* Index in pWC of the next virtual term */
+
+  if( (pOne->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return;
+  if( (pTwo->eOperator & (WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE))==0 ) return;
+  if( (eOp & (WO_EQ|WO_LT|WO_LE))!=eOp
+   && (eOp & (WO_EQ|WO_GT|WO_GE))!=eOp ) return;
+  assert( pOne->pExpr->pLeft!=0 && pOne->pExpr->pRight!=0 );
+  assert( pTwo->pExpr->pLeft!=0 && pTwo->pExpr->pRight!=0 );
+  if( sqlite3ExprCompare(pOne->pExpr->pLeft, pTwo->pExpr->pLeft, -1) ) return;
+  if( sqlite3ExprCompare(pOne->pExpr->pRight, pTwo->pExpr->pRight, -1) )return;
+  /* If we reach this point, it means the two subterms can be combined */
+  if( (eOp & (eOp-1))!=0 ){
+    if( eOp & (WO_LT|WO_LE) ){
+      eOp = WO_LE;
+    }else{
+      assert( eOp & (WO_GT|WO_GE) );
+      eOp = WO_GE;
+    }
+  }
+  db = pWC->pWInfo->pParse->db;
+  pNew = sqlite3ExprDup(db, pOne->pExpr, 0);
+  if( pNew==0 ) return;
+  for(op=TK_EQ; eOp!=(WO_EQ<<(op-TK_EQ)); op++){ assert( op<TK_GE ); }
+  pNew->op = op;
+  idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
+  exprAnalyze(pSrc, pWC, idxNew);
+}
+
 #if !defined(SQLITE_OMIT_OR_OPTIMIZATION) && !defined(SQLITE_OMIT_SUBQUERY)
 /*
 ** Analyze a term that consists of two or more OR-connected
@@ -111745,6 +117108,7 @@ static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
 **     (C)     t1.x=t2.y OR (t1.x=t2.z AND t1.y=15)
 **     (D)     x=expr1 OR (y>11 AND y<22 AND z LIKE '*hello*')
 **     (E)     (p.a=1 AND q.b=2 AND r.c=3) OR (p.x=4 AND q.y=5 AND r.z=6)
+**     (F)     x>A OR (x=A AND y>=B)
 **
 ** CASE 1:
 **
@@ -111761,6 +117125,16 @@ static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
 **
 ** CASE 2:
 **
+** If there are exactly two disjuncts one side has x>A and the other side
+** has x=A (for the same x and A) then add a new virtual conjunct term to the
+** WHERE clause of the form "x>=A".  Example:
+**
+**      x>A OR (x=A AND y>B)    adds:    x>=A
+**
+** The added conjunct can sometimes be helpful in query planning.
+**
+** CASE 3:
+**
 ** If all subterms are indexable by a single table T, then set
 **
 **     WhereTerm.eOperator              =  WO_OR
@@ -111781,7 +117155,7 @@ static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
 ** appropriate for indexing exist.
 **
 ** All examples A through E above satisfy case 2.  But if a term
-** also statisfies case 1 (such as B) we know that the optimizer will
+** also satisfies case 1 (such as B) we know that the optimizer will
 ** always prefer case 1, so in that case we pretend that case 2 is not
 ** satisfied.
 **
@@ -111887,12 +117261,26 @@ static void exprAnalyzeOrTerm(
   }
 
   /*
-  ** Record the set of tables that satisfy case 2.  The set might be
+  ** Record the set of tables that satisfy case 3.  The set might be
   ** empty.
   */
   pOrInfo->indexable = indexable;
   pTerm->eOperator = indexable==0 ? 0 : WO_OR;
 
+  /* For a two-way OR, attempt to implementation case 2.
+  */
+  if( indexable && pOrWc->nTerm==2 ){
+    int iOne = 0;
+    WhereTerm *pOne;
+    while( (pOne = whereNthSubterm(&pOrWc->a[0],iOne++))!=0 ){
+      int iTwo = 0;
+      WhereTerm *pTwo;
+      while( (pTwo = whereNthSubterm(&pOrWc->a[1],iTwo++))!=0 ){
+        whereCombineDisjuncts(pSrc, pWC, pOne, pTwo);
+      }
+    }
+  }
+
   /*
   ** chngToIN holds a set of tables that *might* satisfy case 1.  But
   ** we have to do some additional checking to see if case 1 really
@@ -111939,7 +117327,7 @@ static void exprAnalyzeOrTerm(
         }
         if( (chngToIN & getMask(&pWInfo->sMaskSet, pOrTerm->leftCursor))==0 ){
           /* This term must be of the form t1.a==t2.b where t2 is in the
-          ** chngToIN set but t1 is not.  This term will be either preceeded
+          ** chngToIN set but t1 is not.  This term will be either preceded
           ** or follwed by an inverted copy (t2.b==t1.a).  Skip this term 
           ** and use its inversion. */
           testcase( pOrTerm->wtFlags & TERM_COPIED );
@@ -112018,12 +117406,11 @@ static void exprAnalyzeOrTerm(
         testcase( idxNew==0 );
         exprAnalyze(pSrc, pWC, idxNew);
         pTerm = &pWC->a[idxTerm];
-        pWC->a[idxNew].iParent = idxTerm;
-        pTerm->nChild = 1;
+        markTermAsChild(pWC, idxNew, idxTerm);
       }else{
         sqlite3ExprListDelete(db, pList);
       }
-      pTerm->eOperator = WO_NOOP;  /* case 1 trumps case 2 */
+      pTerm->eOperator = WO_NOOP;  /* case 1 trumps case 3 */
     }
   }
 }
@@ -112061,7 +117448,7 @@ static void exprAnalyze(
   Bitmask extraRight = 0;          /* Extra dependencies on LEFT JOIN */
   Expr *pStr1 = 0;                 /* RHS of LIKE/GLOB operator */
   int isComplete = 0;              /* RHS of LIKE/GLOB ends with wildcard */
-  int noCase = 0;                  /* LIKE/GLOB distinguishes case */
+  int noCase = 0;                  /* uppercase equivalent to lowercase */
   int op;                          /* Top-level operator.  pExpr->op */
   Parse *pParse = pWInfo->pParse;  /* Parsing context */
   sqlite3 *db = pParse->db;        /* Database connection */
@@ -112121,9 +117508,8 @@ static void exprAnalyze(
         idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
         if( idxNew==0 ) return;
         pNew = &pWC->a[idxNew];
-        pNew->iParent = idxTerm;
+        markTermAsChild(pWC, idxNew, idxTerm);
         pTerm = &pWC->a[idxTerm];
-        pTerm->nChild = 1;
         pTerm->wtFlags |= TERM_COPIED;
         if( pExpr->op==TK_EQ
          && !ExprHasProperty(pExpr, EP_FromJoin)
@@ -112180,9 +117566,8 @@ static void exprAnalyze(
       testcase( idxNew==0 );
       exprAnalyze(pSrc, pWC, idxNew);
       pTerm = &pWC->a[idxTerm];
-      pWC->a[idxNew].iParent = idxTerm;
+      markTermAsChild(pWC, idxNew, idxTerm);
     }
-    pTerm->nChild = 2;
   }
 #endif /* SQLITE_OMIT_BETWEEN_OPTIMIZATION */
 
@@ -112201,12 +117586,15 @@ static void exprAnalyze(
   /* Add constraints to reduce the search space on a LIKE or GLOB
   ** operator.
   **
-  ** A like pattern of the form "x LIKE 'abc%'" is changed into constraints
+  ** A like pattern of the form "x LIKE 'aBc%'" is changed into constraints
   **
-  **          x>='abc' AND x<'abd' AND x LIKE 'abc%'
+  **          x>='ABC' AND x<'abd' AND x LIKE 'aBc%'
   **
   ** The last character of the prefix "abc" is incremented to form the
-  ** termination condition "abd".
+  ** termination condition "abd".  If case is not significant (the default
+  ** for LIKE) then the lower-bound is made all uppercase and the upper-
+  ** bound is made all lowercase so that the bounds also work when comparing
+  ** BLOBs.
   */
   if( pWC->op==TK_AND 
    && isLikeOrGlob(pParse, pExpr, &pStr1, &isComplete, &noCase)
@@ -112217,10 +117605,26 @@ static void exprAnalyze(
     Expr *pNewExpr2;
     int idxNew1;
     int idxNew2;
-    Token sCollSeqName;  /* Name of collating sequence */
+    const char *zCollSeqName;     /* Name of collating sequence */
+    const u16 wtFlags = TERM_LIKEOPT | TERM_VIRTUAL | TERM_DYNAMIC;
 
     pLeft = pExpr->x.pList->a[1].pExpr;
     pStr2 = sqlite3ExprDup(db, pStr1, 0);
+
+    /* Convert the lower bound to upper-case and the upper bound to
+    ** lower-case (upper-case is less than lower-case in ASCII) so that
+    ** the range constraints also work for BLOBs
+    */
+    if( noCase && !pParse->db->mallocFailed ){
+      int i;
+      char c;
+      pTerm->wtFlags |= TERM_LIKE;
+      for(i=0; (c = pStr1->u.zToken[i])!=0; i++){
+        pStr1->u.zToken[i] = sqlite3Toupper(c);
+        pStr2->u.zToken[i] = sqlite3Tolower(c);
+      }
+    }
+
     if( !db->mallocFailed ){
       u8 c, *pC;       /* Last character before the first wildcard */
       pC = (u8*)&pStr2->u.zToken[sqlite3Strlen30(pStr2->u.zToken)-1];
@@ -112237,29 +117641,27 @@ static void exprAnalyze(
       }
       *pC = c + 1;
     }
-    sCollSeqName.z = noCase ? "NOCASE" : "BINARY";
-    sCollSeqName.n = 6;
+    zCollSeqName = noCase ? "NOCASE" : "BINARY";
     pNewExpr1 = sqlite3ExprDup(db, pLeft, 0);
-    pNewExpr1 = sqlite3PExpr(pParse, TK_GE, 
-           sqlite3ExprAddCollateToken(pParse,pNewExpr1,&sCollSeqName),
+    pNewExpr1 = sqlite3PExpr(pParse, TK_GE,
+           sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName),
            pStr1, 0);
     transferJoinMarkings(pNewExpr1, pExpr);
-    idxNew1 = whereClauseInsert(pWC, pNewExpr1, TERM_VIRTUAL|TERM_DYNAMIC);
+    idxNew1 = whereClauseInsert(pWC, pNewExpr1, wtFlags);
     testcase( idxNew1==0 );
     exprAnalyze(pSrc, pWC, idxNew1);
     pNewExpr2 = sqlite3ExprDup(db, pLeft, 0);
     pNewExpr2 = sqlite3PExpr(pParse, TK_LT,
-           sqlite3ExprAddCollateToken(pParse,pNewExpr2,&sCollSeqName),
+           sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName),
            pStr2, 0);
     transferJoinMarkings(pNewExpr2, pExpr);
-    idxNew2 = whereClauseInsert(pWC, pNewExpr2, TERM_VIRTUAL|TERM_DYNAMIC);
+    idxNew2 = whereClauseInsert(pWC, pNewExpr2, wtFlags);
     testcase( idxNew2==0 );
     exprAnalyze(pSrc, pWC, idxNew2);
     pTerm = &pWC->a[idxTerm];
     if( isComplete ){
-      pWC->a[idxNew1].iParent = idxTerm;
-      pWC->a[idxNew2].iParent = idxTerm;
-      pTerm->nChild = 2;
+      markTermAsChild(pWC, idxNew1, idxTerm);
+      markTermAsChild(pWC, idxNew2, idxTerm);
     }
   }
 #endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */
@@ -112292,9 +117694,8 @@ static void exprAnalyze(
       pNewTerm->leftCursor = pLeft->iTable;
       pNewTerm->u.leftColumn = pLeft->iColumn;
       pNewTerm->eOperator = WO_MATCH;
-      pNewTerm->iParent = idxTerm;
+      markTermAsChild(pWC, idxNew, idxTerm);
       pTerm = &pWC->a[idxTerm];
-      pTerm->nChild = 1;
       pTerm->wtFlags |= TERM_COPIED;
       pNewTerm->prereqAll = pTerm->prereqAll;
     }
@@ -112315,7 +117716,7 @@ static void exprAnalyze(
   if( pExpr->op==TK_NOTNULL
    && pExpr->pLeft->op==TK_COLUMN
    && pExpr->pLeft->iColumn>=0
-   && OptimizationEnabled(db, SQLITE_Stat3)
+   && OptimizationEnabled(db, SQLITE_Stat34)
   ){
     Expr *pNewExpr;
     Expr *pLeft = pExpr->pLeft;
@@ -112334,9 +117735,8 @@ static void exprAnalyze(
       pNewTerm->leftCursor = pLeft->iTable;
       pNewTerm->u.leftColumn = pLeft->iColumn;
       pNewTerm->eOperator = WO_GT;
-      pNewTerm->iParent = idxTerm;
+      markTermAsChild(pWC, idxNew, idxTerm);
       pTerm = &pWC->a[idxTerm];
-      pTerm->nChild = 1;
       pTerm->wtFlags |= TERM_COPIED;
       pNewTerm->prereqAll = pTerm->prereqAll;
     }
@@ -112350,7 +117750,7 @@ static void exprAnalyze(
 }
 
 /*
-** This function searches pList for a entry that matches the iCol-th column
+** This function searches pList for an entry that matches the iCol-th column
 ** of index pIdx.
 **
 ** If such an expression is found, its index in pList->a[] is returned. If
@@ -112373,7 +117773,7 @@ static int findIndexCol(
      && p->iTable==iBase
     ){
       CollSeq *pColl = sqlite3ExprCollSeq(pParse, pList->a[i].pExpr);
-      if( ALWAYS(pColl) && 0==sqlite3StrICmp(pColl->zName, zColl) ){
+      if( pColl && 0==sqlite3StrICmp(pColl->zName, zColl) ){
         return i;
       }
     }
@@ -112556,6 +117956,8 @@ static void constructAutomaticIndex(
   Bitmask idxCols;            /* Bitmap of columns used for indexing */
   Bitmask extraCols;          /* Bitmap of additional columns */
   u8 sentWarning = 0;         /* True if a warnning has been issued */
+  Expr *pPartial = 0;         /* Partial Index Expression */
+  int iContinue = 0;          /* Jump here to skip excluded rows */
 
   /* Generate code to skip over the creation and initialization of the
   ** transient index on 2nd and subsequent iterations of the loop. */
@@ -112571,6 +117973,17 @@ static void constructAutomaticIndex(
   pLoop = pLevel->pWLoop;
   idxCols = 0;
   for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
+    Expr *pExpr = pTerm->pExpr;
+    assert( !ExprHasProperty(pExpr, EP_FromJoin)    /* prereq always non-zero */
+         || pExpr->iRightJoinTable!=pSrc->iCursor   /*   for the right-hand   */
+         || pLoop->prereq!=0 );                     /*   table of a LEFT JOIN */
+    if( pLoop->prereq==0
+     && (pTerm->wtFlags & TERM_VIRTUAL)==0
+     && !ExprHasProperty(pExpr, EP_FromJoin)
+     && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){
+      pPartial = sqlite3ExprAnd(pParse->db, pPartial,
+                                sqlite3ExprDup(pParse->db, pExpr, 0));
+    }
     if( termCanDriveIndex(pTerm, pSrc, notReady) ){
       int iCol = pTerm->u.leftColumn;
       Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
@@ -112583,7 +117996,9 @@ static void constructAutomaticIndex(
         sentWarning = 1;
       }
       if( (idxCols & cMask)==0 ){
-        if( whereLoopResize(pParse->db, pLoop, nKeyCol+1) ) return;
+        if( whereLoopResize(pParse->db, pLoop, nKeyCol+1) ){
+          goto end_auto_index_create;
+        }
         pLoop->aLTerm[nKeyCol++] = pTerm;
         idxCols |= cMask;
       }
@@ -112603,7 +118018,7 @@ static void constructAutomaticIndex(
   ** if they go out of sync.
   */
   extraCols = pSrc->colUsed & (~idxCols | MASKBIT(BMS-1));
-  mxBitCol = (pTable->nCol >= BMS-1) ? BMS-1 : pTable->nCol;
+  mxBitCol = MIN(BMS-1,pTable->nCol);
   testcase( pTable->nCol==BMS-1 );
   testcase( pTable->nCol==BMS-2 );
   for(i=0; i<mxBitCol; i++){
@@ -112612,11 +118027,10 @@ static void constructAutomaticIndex(
   if( pSrc->colUsed & MASKBIT(BMS-1) ){
     nKeyCol += pTable->nCol - BMS + 1;
   }
-  pLoop->wsFlags |= WHERE_COLUMN_EQ | WHERE_IDX_ONLY;
 
   /* Construct the Index object to describe this index */
   pIdx = sqlite3AllocateIndexObject(pParse->db, nKeyCol+1, 0, &zNotUsed);
-  if( pIdx==0 ) return;
+  if( pIdx==0 ) goto end_auto_index_create;
   pLoop->u.btree.pIndex = pIdx;
   pIdx->zName = "auto-index";
   pIdx->pTable = pTable;
@@ -112633,7 +118047,7 @@ static void constructAutomaticIndex(
         idxCols |= cMask;
         pIdx->aiColumn[n] = pTerm->u.leftColumn;
         pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
-        pIdx->azColl[n] = ALWAYS(pColl) ? pColl->zName : "BINARY";
+        pIdx->azColl[n] = pColl ? pColl->zName : "BINARY";
         n++;
       }
     }
@@ -112668,18 +118082,29 @@ static void constructAutomaticIndex(
   VdbeComment((v, "for %s", pTable->zName));
 
   /* Fill the automatic index with content */
+  sqlite3ExprCachePush(pParse);
   addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
+  if( pPartial ){
+    iContinue = sqlite3VdbeMakeLabel(v);
+    sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL);
+    pLoop->wsFlags |= WHERE_PARTIALIDX;
+  }
   regRecord = sqlite3GetTempReg(pParse);
   sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0);
   sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
   sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
+  if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
   sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
   sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
   sqlite3VdbeJumpHere(v, addrTop);
   sqlite3ReleaseTempReg(pParse, regRecord);
+  sqlite3ExprCachePop(pParse);
   
   /* Jump here when skipping the initialization */
   sqlite3VdbeJumpHere(v, addrInit);
+
+end_auto_index_create:
+  sqlite3ExprDelete(pParse->db, pPartial);
 }
 #endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
 
@@ -112839,18 +118264,21 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){
 }
 #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */
 
-
 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
 /*
 ** Estimate the location of a particular key among all keys in an
 ** index.  Store the results in aStat as follows:
 **
-**    aStat[0]      Est. number of rows less than pVal
-**    aStat[1]      Est. number of rows equal to pVal
+**    aStat[0]      Est. number of rows less than pRec
+**    aStat[1]      Est. number of rows equal to pRec
 **
-** Return SQLITE_OK on success.
+** Return the index of the sample that is the smallest sample that
+** is greater than or equal to pRec. Note that this index is not an index
+** into the aSample[] array - it is an index into a virtual set of samples
+** based on the contents of aSample[] and the number of fields in record 
+** pRec. 
 */
-static void whereKeyStats(
+static int whereKeyStats(
   Parse *pParse,              /* Database connection */
   Index *pIdx,                /* Index to consider domain of */
   UnpackedRecord *pRec,       /* Vector of values to consider */
@@ -112859,67 +118287,158 @@ static void whereKeyStats(
 ){
   IndexSample *aSample = pIdx->aSample;
   int iCol;                   /* Index of required stats in anEq[] etc. */
+  int i;                      /* Index of first sample >= pRec */
+  int iSample;                /* Smallest sample larger than or equal to pRec */
   int iMin = 0;               /* Smallest sample not yet tested */
-  int i = pIdx->nSample;      /* Smallest sample larger than or equal to pRec */
   int iTest;                  /* Next sample to test */
   int res;                    /* Result of comparison operation */
+  int nField;                 /* Number of fields in pRec */
+  tRowcnt iLower = 0;         /* anLt[] + anEq[] of largest sample pRec is > */
 
 #ifndef SQLITE_DEBUG
   UNUSED_PARAMETER( pParse );
 #endif
   assert( pRec!=0 );
-  iCol = pRec->nField - 1;
   assert( pIdx->nSample>0 );
-  assert( pRec->nField>0 && iCol<pIdx->nSampleCol );
+  assert( pRec->nField>0 && pRec->nField<=pIdx->nSampleCol );
+
+  /* Do a binary search to find the first sample greater than or equal
+  ** to pRec. If pRec contains a single field, the set of samples to search
+  ** is simply the aSample[] array. If the samples in aSample[] contain more
+  ** than one fields, all fields following the first are ignored.
+  **
+  ** If pRec contains N fields, where N is more than one, then as well as the
+  ** samples in aSample[] (truncated to N fields), the search also has to
+  ** consider prefixes of those samples. For example, if the set of samples
+  ** in aSample is:
+  **
+  **     aSample[0] = (a, 5) 
+  **     aSample[1] = (a, 10) 
+  **     aSample[2] = (b, 5) 
+  **     aSample[3] = (c, 100) 
+  **     aSample[4] = (c, 105)
+  **
+  ** Then the search space should ideally be the samples above and the 
+  ** unique prefixes [a], [b] and [c]. But since that is hard to organize, 
+  ** the code actually searches this set:
+  **
+  **     0: (a) 
+  **     1: (a, 5) 
+  **     2: (a, 10) 
+  **     3: (a, 10) 
+  **     4: (b) 
+  **     5: (b, 5) 
+  **     6: (c) 
+  **     7: (c, 100) 
+  **     8: (c, 105)
+  **     9: (c, 105)
+  **
+  ** For each sample in the aSample[] array, N samples are present in the
+  ** effective sample array. In the above, samples 0 and 1 are based on 
+  ** sample aSample[0]. Samples 2 and 3 on aSample[1] etc.
+  **
+  ** Often, sample i of each block of N effective samples has (i+1) fields.
+  ** Except, each sample may be extended to ensure that it is greater than or
+  ** equal to the previous sample in the array. For example, in the above, 
+  ** sample 2 is the first sample of a block of N samples, so at first it 
+  ** appears that it should be 1 field in size. However, that would make it 
+  ** smaller than sample 1, so the binary search would not work. As a result, 
+  ** it is extended to two fields. The duplicates that this creates do not 
+  ** cause any problems.
+  */
+  nField = pRec->nField;
+  iCol = 0;
+  iSample = pIdx->nSample * nField;
   do{
-    iTest = (iMin+i)/2;
-    res = sqlite3VdbeRecordCompare(aSample[iTest].n, aSample[iTest].p, pRec, 0);
+    int iSamp;                    /* Index in aSample[] of test sample */
+    int n;                        /* Number of fields in test sample */
+
+    iTest = (iMin+iSample)/2;
+    iSamp = iTest / nField;
+    if( iSamp>0 ){
+      /* The proposed effective sample is a prefix of sample aSample[iSamp].
+      ** Specifically, the shortest prefix of at least (1 + iTest%nField) 
+      ** fields that is greater than the previous effective sample.  */
+      for(n=(iTest % nField) + 1; n<nField; n++){
+        if( aSample[iSamp-1].anLt[n-1]!=aSample[iSamp].anLt[n-1] ) break;
+      }
+    }else{
+      n = iTest + 1;
+    }
+
+    pRec->nField = n;
+    res = sqlite3VdbeRecordCompare(aSample[iSamp].n, aSample[iSamp].p, pRec);
     if( res<0 ){
+      iLower = aSample[iSamp].anLt[n-1] + aSample[iSamp].anEq[n-1];
+      iMin = iTest+1;
+    }else if( res==0 && n<nField ){
+      iLower = aSample[iSamp].anLt[n-1];
       iMin = iTest+1;
+      res = -1;
     }else{
-      i = iTest;
+      iSample = iTest;
+      iCol = n-1;
     }
-  }while( res && iMin<i );
+  }while( res && iMin<iSample );
+  i = iSample / nField;
 
 #ifdef SQLITE_DEBUG
   /* The following assert statements check that the binary search code
   ** above found the right answer. This block serves no purpose other
   ** than to invoke the asserts.  */
-  if( res==0 ){
-    /* If (res==0) is true, then sample $i must be equal to pRec */
-    assert( i<pIdx->nSample );
-    assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec, 0)
-         || pParse->db->mallocFailed );
-  }else{
-    /* Otherwise, pRec must be smaller than sample $i and larger than
-    ** sample ($i-1).  */
-    assert( i==pIdx->nSample 
-         || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec, 0)>0
-         || pParse->db->mallocFailed );
-    assert( i==0
-         || sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec, 0)<0
-         || pParse->db->mallocFailed );
+  if( pParse->db->mallocFailed==0 ){
+    if( res==0 ){
+      /* If (res==0) is true, then pRec must be equal to sample i. */
+      assert( i<pIdx->nSample );
+      assert( iCol==nField-1 );
+      pRec->nField = nField;
+      assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec) 
+           || pParse->db->mallocFailed 
+      );
+    }else{
+      /* Unless i==pIdx->nSample, indicating that pRec is larger than
+      ** all samples in the aSample[] array, pRec must be smaller than the
+      ** (iCol+1) field prefix of sample i.  */
+      assert( i<=pIdx->nSample && i>=0 );
+      pRec->nField = iCol+1;
+      assert( i==pIdx->nSample 
+           || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0
+           || pParse->db->mallocFailed );
+
+      /* if i==0 and iCol==0, then record pRec is smaller than all samples
+      ** in the aSample[] array. Otherwise, if (iCol>0) then pRec must
+      ** be greater than or equal to the (iCol) field prefix of sample i.
+      ** If (i>0), then pRec must also be greater than sample (i-1).  */
+      if( iCol>0 ){
+        pRec->nField = iCol;
+        assert( sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)<=0
+             || pParse->db->mallocFailed );
+      }
+      if( i>0 ){
+        pRec->nField = nField;
+        assert( sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0
+             || pParse->db->mallocFailed );
+      }
+    }
   }
 #endif /* ifdef SQLITE_DEBUG */
 
-  /* At this point, aSample[i] is the first sample that is greater than
-  ** or equal to pVal.  Or if i==pIdx->nSample, then all samples are less
-  ** than pVal.  If aSample[i]==pVal, then res==0.
-  */
   if( res==0 ){
+    /* Record pRec is equal to sample i */
+    assert( iCol==nField-1 );
     aStat[0] = aSample[i].anLt[iCol];
     aStat[1] = aSample[i].anEq[iCol];
   }else{
-    tRowcnt iLower, iUpper, iGap;
-    if( i==0 ){
-      iLower = 0;
-      iUpper = aSample[0].anLt[iCol];
+    /* At this point, the (iCol+1) field prefix of aSample[i] is the first 
+    ** sample that is greater than pRec. Or, if i==pIdx->nSample then pRec
+    ** is larger than all samples in the array. */
+    tRowcnt iUpper, iGap;
+    if( i>=pIdx->nSample ){
+      iUpper = sqlite3LogEstToInt(pIdx->aiRowLogEst[0]);
     }else{
-      i64 nRow0 = sqlite3LogEstToInt(pIdx->aiRowLogEst[0]);
-      iUpper = i>=pIdx->nSample ? nRow0 : aSample[i].anLt[iCol];
-      iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol];
+      iUpper = aSample[i].anLt[iCol];
     }
-    aStat[1] = pIdx->aAvgEq[iCol];
+
     if( iLower>=iUpper ){
       iGap = 0;
     }else{
@@ -112931,7 +118450,12 @@ static void whereKeyStats(
       iGap = iGap/3;
     }
     aStat[0] = iLower + iGap;
+    aStat[1] = pIdx->aAvgEq[iCol];
   }
+
+  /* Restore the pRec->nField value before returning.  */
+  pRec->nField = nField;
+  return i;
 }
 #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
 
@@ -113082,7 +118606,7 @@ static int whereRangeSkipScanEst(
 ** If either of the upper or lower bound is not present, then NULL is passed in
 ** place of the corresponding WhereTerm.
 **
-** The value in (pBuilder->pNew->u.btree.nEq) is the index of the index
+** The value in (pBuilder->pNew->u.btree.nEq) is the number of the index
 ** column subject to the range constraint. Or, equivalently, the number of
 ** equality constraints optimized by the proposed index scan. For example,
 ** assuming index p is on t1(a, b), and the SQL query is:
@@ -113098,9 +118622,9 @@ static int whereRangeSkipScanEst(
 **
 ** When this function is called, *pnOut is set to the sqlite3LogEst() of the
 ** number of rows that the index scan is expected to visit without 
-** considering the range constraints. If nEq is 0, this is the number of 
+** considering the range constraints. If nEq is 0, then *pnOut is the number of 
 ** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced)
-** to account for the range contraints pLower and pUpper.
+** to account for the range constraints pLower and pUpper.
 ** 
 ** In the absence of sqlite_stat4 ANALYZE data, or if such data cannot be
 ** used, a single range inequality reduces the search space by a factor of 4. 
@@ -113122,10 +118646,7 @@ static int whereRangeScanEst(
   Index *p = pLoop->u.btree.pIndex;
   int nEq = pLoop->u.btree.nEq;
 
-  if( p->nSample>0
-   && nEq<p->nSampleCol
-   && OptimizationEnabled(pParse->db, SQLITE_Stat3) 
-  ){
+  if( p->nSample>0 && nEq<p->nSampleCol ){
     if( nEq==pBuilder->nRecValid ){
       UnpackedRecord *pRec = pBuilder->pRec;
       tRowcnt a[2];
@@ -113141,16 +118662,24 @@ static int whereRangeScanEst(
       ** is not a simple variable or literal value), the lower bound of the
       ** range is $P. Due to a quirk in the way whereKeyStats() works, even
       ** if $L is available, whereKeyStats() is called for both ($P) and 
-      ** ($P:$L) and the larger of the two returned values used.
+      ** ($P:$L) and the larger of the two returned values is used.
       **
       ** Similarly, iUpper is to be set to the estimate of the number of rows
       ** less than the upper bound of the range query. Where the upper bound
       ** is either ($P) or ($P:$U). Again, even if $U is available, both values
       ** of iUpper are requested of whereKeyStats() and the smaller used.
+      **
+      ** The number of rows between the two bounds is then just iUpper-iLower.
       */
-      tRowcnt iLower;
-      tRowcnt iUpper;
+      tRowcnt iLower;     /* Rows less than the lower bound */
+      tRowcnt iUpper;     /* Rows less than the upper bound */
+      int iLwrIdx = -2;   /* aSample[] for the lower bound */
+      int iUprIdx = -1;   /* aSample[] for the upper bound */
 
+      if( pRec ){
+        testcase( pRec->nField!=pBuilder->nRecValid );
+        pRec->nField = pBuilder->nRecValid;
+      }
       if( nEq==p->nKeyCol ){
         aff = SQLITE_AFF_INTEGER;
       }else{
@@ -113159,7 +118688,7 @@ static int whereRangeScanEst(
       /* Determine iLower and iUpper using ($P) only. */
       if( nEq==0 ){
         iLower = 0;
-        iUpper = sqlite3LogEstToInt(p->aiRowLogEst[0]);
+        iUpper = p->nRowEst0;
       }else{
         /* Note: this call could be optimized away - since the same values must 
         ** have been requested when testing key $P in whereEqualScanEst().  */
@@ -113168,18 +118697,26 @@ static int whereRangeScanEst(
         iUpper = a[0] + a[1];
       }
 
+      assert( pLower==0 || (pLower->eOperator & (WO_GT|WO_GE))!=0 );
+      assert( pUpper==0 || (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
+      assert( p->aSortOrder!=0 );
+      if( p->aSortOrder[nEq] ){
+        /* The roles of pLower and pUpper are swapped for a DESC index */
+        SWAP(WhereTerm*, pLower, pUpper);
+      }
+
       /* If possible, improve on the iLower estimate using ($P:$L). */
       if( pLower ){
         int bOk;                    /* True if value is extracted from pExpr */
         Expr *pExpr = pLower->pExpr->pRight;
-        assert( (pLower->eOperator & (WO_GT|WO_GE))!=0 );
         rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
         if( rc==SQLITE_OK && bOk ){
           tRowcnt iNew;
-          whereKeyStats(pParse, p, pRec, 0, a);
-          iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0);
+          iLwrIdx = whereKeyStats(pParse, p, pRec, 0, a);
+          iNew = a[0] + ((pLower->eOperator & (WO_GT|WO_LE)) ? a[1] : 0);
           if( iNew>iLower ) iLower = iNew;
           nOut--;
+          pLower = 0;
         }
       }
 
@@ -113187,14 +118724,14 @@ static int whereRangeScanEst(
       if( pUpper ){
         int bOk;                    /* True if value is extracted from pExpr */
         Expr *pExpr = pUpper->pExpr->pRight;
-        assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
         rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
         if( rc==SQLITE_OK && bOk ){
           tRowcnt iNew;
-          whereKeyStats(pParse, p, pRec, 1, a);
-          iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0);
+          iUprIdx = whereKeyStats(pParse, p, pRec, 1, a);
+          iNew = a[0] + ((pUpper->eOperator & (WO_GT|WO_LE)) ? a[1] : 0);
           if( iNew<iUpper ) iUpper = iNew;
           nOut--;
+          pUpper = 0;
         }
       }
 
@@ -113202,16 +118739,19 @@ static int whereRangeScanEst(
       if( rc==SQLITE_OK ){
         if( iUpper>iLower ){
           nNew = sqlite3LogEst(iUpper - iLower);
+          /* TUNING:  If both iUpper and iLower are derived from the same
+          ** sample, then assume they are 4x more selective.  This brings
+          ** the estimated selectivity more in line with what it would be
+          ** if estimated without the use of STAT3/4 tables. */
+          if( iLwrIdx==iUprIdx ) nNew -= 20;  assert( 20==sqlite3LogEst(4) );
         }else{
           nNew = 10;        assert( 10==sqlite3LogEst(2) );
         }
         if( nNew<nOut ){
           nOut = nNew;
         }
-        pLoop->nOut = (LogEst)nOut;
-        WHERETRACE(0x10, ("range scan regions: %u..%u  est=%d\n",
+        WHERETRACE(0x10, ("STAT4 range scan: %u..%u  est=%d\n",
                            (u32)iLower, (u32)iUpper, nOut));
-        return SQLITE_OK;
       }
     }else{
       int bDone = 0;
@@ -113222,22 +118762,31 @@ static int whereRangeScanEst(
 #else
   UNUSED_PARAMETER(pParse);
   UNUSED_PARAMETER(pBuilder);
-#endif
   assert( pLower || pUpper );
+#endif
   assert( pUpper==0 || (pUpper->wtFlags & TERM_VNULL)==0 );
   nNew = whereRangeAdjust(pLower, nOut);
   nNew = whereRangeAdjust(pUpper, nNew);
 
-  /* TUNING: If there is both an upper and lower limit, assume the range is
+  /* TUNING: If there is both an upper and lower limit and neither limit
+  ** has an application-defined likelihood(), assume the range is
   ** reduced by an additional 75%. This means that, by default, an open-ended
   ** range query (e.g. col > ?) is assumed to match 1/4 of the rows in the
   ** index. While a closed range (e.g. col BETWEEN ? AND ?) is estimated to
   ** match 1/64 of the index. */ 
-  if( pLower && pUpper ) nNew -= 20;
+  if( pLower && pLower->truthProb>0 && pUpper && pUpper->truthProb>0 ){
+    nNew -= 20;
+  }
 
   nOut -= (pLower!=0) + (pUpper!=0);
   if( nNew<10 ) nNew = 10;
   if( nNew<nOut ) nOut = nNew;
+#if defined(WHERETRACE_ENABLED)
+  if( pLoop->nOut>nOut ){
+    WHERETRACE(0x10,("Range scan lowers nOut from %d to %d\n",
+                    pLoop->nOut, nOut));
+  }
+#endif
   pLoop->nOut = (LogEst)nOut;
   return rc;
 }
@@ -113350,7 +118899,7 @@ static int whereInScanEst(
   if( rc==SQLITE_OK ){
     if( nRowEst > nRow0 ) nRowEst = nRow0;
     *pnRow = nRowEst;
-    WHERETRACE(0x10,("IN row estimate: est=%g\n", nRowEst));
+    WHERETRACE(0x10,("IN row estimate: est=%d\n", nRowEst));
   }
   assert( pBuilder->nRecValid==nRecValid );
   return rc;
@@ -113379,20 +118928,43 @@ static int whereInScanEst(
 ** but joins might run a little slower.  The trick is to disable as much
 ** as we can without disabling too much.  If we disabled in (1), we'd get
 ** the wrong answer.  See ticket #813.
+**
+** If all the children of a term are disabled, then that term is also
+** automatically disabled.  In this way, terms get disabled if derived
+** virtual terms are tested first.  For example:
+**
+**      x GLOB 'abc*' AND x>='abc' AND x<'acd'
+**      \___________/     \______/     \_____/
+**         parent          child1       child2
+**
+** Only the parent term was in the original WHERE clause.  The child1
+** and child2 terms were added by the LIKE optimization.  If both of
+** the virtual child terms are valid, then testing of the parent can be 
+** skipped.
+**
+** Usually the parent term is marked as TERM_CODED.  But if the parent
+** term was originally TERM_LIKE, then the parent gets TERM_LIKECOND instead.
+** The TERM_LIKECOND marking indicates that the term should be coded inside
+** a conditional such that is only evaluated on the second pass of a
+** LIKE-optimization loop, when scanning BLOBs instead of strings.
 */
 static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
-  if( pTerm
+  int nLoop = 0;
+  while( pTerm
       && (pTerm->wtFlags & TERM_CODED)==0
       && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
       && (pLevel->notReady & pTerm->prereqAll)==0
   ){
-    pTerm->wtFlags |= TERM_CODED;
-    if( pTerm->iParent>=0 ){
-      WhereTerm *pOther = &pTerm->pWC->a[pTerm->iParent];
-      if( (--pOther->nChild)==0 ){
-        disableTerm(pLevel, pOther);
-      }
+    if( nLoop && (pTerm->wtFlags & TERM_LIKE)!=0 ){
+      pTerm->wtFlags |= TERM_LIKECOND;
+    }else{
+      pTerm->wtFlags |= TERM_CODED;
     }
+    if( pTerm->iParent<0 ) break;
+    pTerm = &pTerm->pWC->a[pTerm->iParent];
+    pTerm->nChild--;
+    if( pTerm->nChild!=0 ) break;
+    nLoop++;
   }
 }
 
@@ -113587,7 +119159,7 @@ static int codeAllEqualityTerms(
   pLoop = pLevel->pWLoop;
   assert( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 );
   nEq = pLoop->u.btree.nEq;
-  nSkip = pLoop->u.btree.nSkip;
+  nSkip = pLoop->nSkip;
   pIdx = pLoop->u.btree.pIndex;
   assert( pIdx!=0 );
 
@@ -113686,9 +119258,8 @@ static void explainAppendTerm(
 
 /*
 ** Argument pLevel describes a strategy for scanning table pTab. This 
-** function returns a pointer to a string buffer containing a description
-** of the subset of table rows scanned by the strategy in the form of an
-** SQL expression. Or, if all rows are scanned, NULL is returned.
+** function appends text to pStr that describes the subset of table
+** rows scanned by the strategy in the form of an SQL expression.
 **
 ** For example, if the query:
 **
@@ -113698,58 +119269,49 @@ static void explainAppendTerm(
 ** string similar to:
 **
 **   "a=? AND b>?"
-**
-** The returned pointer points to memory obtained from sqlite3DbMalloc().
-** It is the responsibility of the caller to free the buffer when it is
-** no longer required.
 */
-static char *explainIndexRange(sqlite3 *db, WhereLoop *pLoop, Table *pTab){
+static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop, Table *pTab){
   Index *pIndex = pLoop->u.btree.pIndex;
   u16 nEq = pLoop->u.btree.nEq;
-  u16 nSkip = pLoop->u.btree.nSkip;
+  u16 nSkip = pLoop->nSkip;
   int i, j;
   Column *aCol = pTab->aCol;
   i16 *aiColumn = pIndex->aiColumn;
-  StrAccum txt;
 
-  if( nEq==0 && (pLoop->wsFlags & (WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ){
-    return 0;
-  }
-  sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
-  txt.db = db;
-  sqlite3StrAccumAppend(&txt, " (", 2);
+  if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return;
+  sqlite3StrAccumAppend(pStr, " (", 2);
   for(i=0; i<nEq; i++){
     char *z = aiColumn[i] < 0 ? "rowid" : aCol[aiColumn[i]].zName;
     if( i>=nSkip ){
-      explainAppendTerm(&txt, i, z, "=");
+      explainAppendTerm(pStr, i, z, "=");
     }else{
-      if( i ) sqlite3StrAccumAppend(&txt, " AND ", 5);
-      sqlite3StrAccumAppend(&txt, "ANY(", 4);
-      sqlite3StrAccumAppendAll(&txt, z);
-      sqlite3StrAccumAppend(&txt, ")", 1);
+      if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);
+      sqlite3XPrintf(pStr, 0, "ANY(%s)", z);
     }
   }
 
   j = i;
   if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
     char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
-    explainAppendTerm(&txt, i++, z, ">");
+    explainAppendTerm(pStr, i++, z, ">");
   }
   if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
     char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
-    explainAppendTerm(&txt, i, z, "<");
+    explainAppendTerm(pStr, i, z, "<");
   }
-  sqlite3StrAccumAppend(&txt, ")", 1);
-  return sqlite3StrAccumFinish(&txt);
+  sqlite3StrAccumAppend(pStr, ")", 1);
 }
 
 /*
 ** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN
-** command. If the query being compiled is an EXPLAIN QUERY PLAN, a single
-** record is added to the output to describe the table scan strategy in 
-** pLevel.
+** command, or if either SQLITE_DEBUG or SQLITE_ENABLE_STMT_SCANSTATUS was
+** defined at compile-time. If it is not a no-op, a single OP_Explain opcode 
+** is added to the output to describe the table scan strategy in pLevel.
+**
+** If an OP_Explain opcode is added to the VM, its address is returned.
+** Otherwise, if no OP_Explain is coded, zero is returned.
 */
-static void explainOneScan(
+static int explainOneScan(
   Parse *pParse,                  /* Parse context */
   SrcList *pTabList,              /* Table list this loop refers to */
   WhereLevel *pLevel,             /* Scan to write OP_Explain opcode for */
@@ -113757,82 +119319,162 @@ static void explainOneScan(
   int iFrom,                      /* Value for "from" column of output */
   u16 wctrlFlags                  /* Flags passed to sqlite3WhereBegin() */
 ){
-#ifndef SQLITE_DEBUG
+  int ret = 0;
+#if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS)
   if( pParse->explain==2 )
 #endif
   {
     struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom];
     Vdbe *v = pParse->pVdbe;      /* VM being constructed */
     sqlite3 *db = pParse->db;     /* Database handle */
-    char *zMsg;                   /* Text to add to EQP output */
     int iId = pParse->iSelectId;  /* Select id (left-most output column) */
     int isSearch;                 /* True for a SEARCH. False for SCAN. */
     WhereLoop *pLoop;             /* The controlling WhereLoop object */
     u32 flags;                    /* Flags that describe this loop */
+    char *zMsg;                   /* Text to add to EQP output */
+    StrAccum str;                 /* EQP output string */
+    char zBuf[100];               /* Initial space for EQP output string */
 
     pLoop = pLevel->pWLoop;
     flags = pLoop->wsFlags;
-    if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return;
+    if( (flags&WHERE_MULTI_OR) || (wctrlFlags&WHERE_ONETABLE_ONLY) ) return 0;
 
     isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
             || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
             || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
 
-    zMsg = sqlite3MPrintf(db, "%s", isSearch?"SEARCH":"SCAN");
+    sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
+    sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
     if( pItem->pSelect ){
-      zMsg = sqlite3MAppendf(db, zMsg, "%s SUBQUERY %d", zMsg,pItem->iSelectId);
+      sqlite3XPrintf(&str, 0, " SUBQUERY %d", pItem->iSelectId);
     }else{
-      zMsg = sqlite3MAppendf(db, zMsg, "%s TABLE %s", zMsg, pItem->zName);
+      sqlite3XPrintf(&str, 0, " TABLE %s", pItem->zName);
     }
 
     if( pItem->zAlias ){
-      zMsg = sqlite3MAppendf(db, zMsg, "%s AS %s", zMsg, pItem->zAlias);
+      sqlite3XPrintf(&str, 0, " AS %s", pItem->zAlias);
     }
-    if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0
-     && ALWAYS(pLoop->u.btree.pIndex!=0)
-    ){
-      const char *zFmt;
-      Index *pIdx = pLoop->u.btree.pIndex;
-      char *zWhere = explainIndexRange(db, pLoop, pItem->pTab);
+    if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
+      const char *zFmt = 0;
+      Index *pIdx;
+
+      assert( pLoop->u.btree.pIndex!=0 );
+      pIdx = pLoop->u.btree.pIndex;
       assert( !(flags&WHERE_AUTO_INDEX) || (flags&WHERE_IDX_ONLY) );
       if( !HasRowid(pItem->pTab) && IsPrimaryKeyIndex(pIdx) ){
-        zFmt = zWhere ? "%s USING PRIMARY KEY%.0s%s" : "%s%.0s%s";
+        if( isSearch ){
+          zFmt = "PRIMARY KEY";
+        }
+      }else if( flags & WHERE_PARTIALIDX ){
+        zFmt = "AUTOMATIC PARTIAL COVERING INDEX";
       }else if( flags & WHERE_AUTO_INDEX ){
-        zFmt = "%s USING AUTOMATIC COVERING INDEX%.0s%s";
+        zFmt = "AUTOMATIC COVERING INDEX";
       }else if( flags & WHERE_IDX_ONLY ){
-        zFmt = "%s USING COVERING INDEX %s%s";
+        zFmt = "COVERING INDEX %s";
       }else{
-        zFmt = "%s USING INDEX %s%s";
+        zFmt = "INDEX %s";
+      }
+      if( zFmt ){
+        sqlite3StrAccumAppend(&str, " USING ", 7);
+        sqlite3XPrintf(&str, 0, zFmt, pIdx->zName);
+        explainIndexRange(&str, pLoop, pItem->pTab);
       }
-      zMsg = sqlite3MAppendf(db, zMsg, zFmt, zMsg, pIdx->zName, zWhere);
-      sqlite3DbFree(db, zWhere);
     }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
-      zMsg = sqlite3MAppendf(db, zMsg, "%s USING INTEGER PRIMARY KEY", zMsg);
-
+      const char *zRange;
       if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
-        zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid=?)", zMsg);
+        zRange = "(rowid=?)";
       }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
-        zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>? AND rowid<?)", zMsg);
+        zRange = "(rowid>? AND rowid<?)";
       }else if( flags&WHERE_BTM_LIMIT ){
-        zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid>?)", zMsg);
-      }else if( ALWAYS(flags&WHERE_TOP_LIMIT) ){
-        zMsg = sqlite3MAppendf(db, zMsg, "%s (rowid<?)", zMsg);
+        zRange = "(rowid>?)";
+      }else{
+        assert( flags&WHERE_TOP_LIMIT);
+        zRange = "(rowid<?)";
       }
+      sqlite3StrAccumAppendAll(&str, " USING INTEGER PRIMARY KEY ");
+      sqlite3StrAccumAppendAll(&str, zRange);
     }
 #ifndef SQLITE_OMIT_VIRTUALTABLE
     else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
-      zMsg = sqlite3MAppendf(db, zMsg, "%s VIRTUAL TABLE INDEX %d:%s", zMsg,
+      sqlite3XPrintf(&str, 0, " VIRTUAL TABLE INDEX %d:%s",
                   pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
     }
 #endif
-    zMsg = sqlite3MAppendf(db, zMsg, "%s", zMsg);
-    sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg, P4_DYNAMIC);
+#ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
+    if( pLoop->nOut>=10 ){
+      sqlite3XPrintf(&str, 0, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut));
+    }else{
+      sqlite3StrAccumAppend(&str, " (~1 row)", 9);
+    }
+#endif
+    zMsg = sqlite3StrAccumFinish(&str);
+    ret = sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg,P4_DYNAMIC);
   }
+  return ret;
 }
 #else
-# define explainOneScan(u,v,w,x,y,z)
+# define explainOneScan(u,v,w,x,y,z) 0
 #endif /* SQLITE_OMIT_EXPLAIN */
 
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+/*
+** Configure the VM passed as the first argument with an
+** sqlite3_stmt_scanstatus() entry corresponding to the scan used to 
+** implement level pLvl. Argument pSrclist is a pointer to the FROM 
+** clause that the scan reads data from.
+**
+** If argument addrExplain is not 0, it must be the address of an 
+** OP_Explain instruction that describes the same loop.
+*/
+static void addScanStatus(
+  Vdbe *v,                        /* Vdbe to add scanstatus entry to */
+  SrcList *pSrclist,              /* FROM clause pLvl reads data from */
+  WhereLevel *pLvl,               /* Level to add scanstatus() entry for */
+  int addrExplain                 /* Address of OP_Explain (or 0) */
+){
+  const char *zObj = 0;
+  WhereLoop *pLoop = pLvl->pWLoop;
+  if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0  &&  pLoop->u.btree.pIndex!=0 ){
+    zObj = pLoop->u.btree.pIndex->zName;
+  }else{
+    zObj = pSrclist->a[pLvl->iFrom].zName;
+  }
+  sqlite3VdbeScanStatus(
+      v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj
+  );
+}
+#else
+# define addScanStatus(a, b, c, d) ((void)d)
+#endif
+
+/*
+** If the most recently coded instruction is a constant range contraint
+** that originated from the LIKE optimization, then change the P3 to be
+** pLoop->iLikeRepCntr and set P5.
+**
+** The LIKE optimization trys to evaluate "x LIKE 'abc%'" as a range
+** expression: "x>='ABC' AND x<'abd'".  But this requires that the range
+** scan loop run twice, once for strings and a second time for BLOBs.
+** The OP_String opcodes on the second pass convert the upper and lower
+** bound string contants to blobs.  This routine makes the necessary changes
+** to the OP_String opcodes for that to happen.
+*/
+static void whereLikeOptimizationStringFixup(
+  Vdbe *v,                /* prepared statement under construction */
+  WhereLevel *pLevel,     /* The loop that contains the LIKE operator */
+  WhereTerm *pTerm        /* The upper or lower bound just coded */
+){
+  if( pTerm->wtFlags & TERM_LIKEOPT ){
+    VdbeOp *pOp;
+    assert( pLevel->iLikeRepCntr>0 );
+    pOp = sqlite3VdbeGetOp(v, -1);
+    assert( pOp!=0 );
+    assert( pOp->opcode==OP_String8 
+            || pTerm->pWC->pWInfo->pParse->db->mallocFailed );
+    pOp->p3 = pLevel->iLikeRepCntr;
+    pOp->p5 = 1;
+  }
+}
 
 /*
 ** Generate code for the start of the iLevel-th loop in the WHERE clause
@@ -114133,7 +119775,7 @@ static Bitmask codeOneLoopStart(
 
     pIdx = pLoop->u.btree.pIndex;
     iIdxCur = pLevel->iIdxCur;
-    assert( nEq>=pLoop->u.btree.nSkip );
+    assert( nEq>=pLoop->nSkip );
 
     /* If this loop satisfies a sort order (pOrderBy) request that 
     ** was passed to this function to implement a "SELECT min(x) ..." 
@@ -114150,7 +119792,7 @@ static Bitmask codeOneLoopStart(
      && pWInfo->nOBSat>0
      && (pIdx->nKeyCol>nEq)
     ){
-      assert( pLoop->u.btree.nSkip==0 );
+      assert( pLoop->nSkip==0 );
       bSeekPastNull = 1;
       nExtraReg = 1;
     }
@@ -114162,10 +119804,25 @@ static Bitmask codeOneLoopStart(
     if( pLoop->wsFlags & WHERE_BTM_LIMIT ){
       pRangeStart = pLoop->aLTerm[j++];
       nExtraReg = 1;
+      /* Like optimization range constraints always occur in pairs */
+      assert( (pRangeStart->wtFlags & TERM_LIKEOPT)==0 || 
+              (pLoop->wsFlags & WHERE_TOP_LIMIT)!=0 );
     }
     if( pLoop->wsFlags & WHERE_TOP_LIMIT ){
       pRangeEnd = pLoop->aLTerm[j++];
       nExtraReg = 1;
+      if( (pRangeEnd->wtFlags & TERM_LIKEOPT)!=0 ){
+        assert( pRangeStart!=0 );                     /* LIKE opt constraints */
+        assert( pRangeStart->wtFlags & TERM_LIKEOPT );   /* occur in pairs */
+        pLevel->iLikeRepCntr = ++pParse->nMem;
+        testcase( bRev );
+        testcase( pIdx->aSortOrder[nEq]==SQLITE_SO_DESC );
+        sqlite3VdbeAddOp2(v, OP_Integer,
+                          bRev ^ (pIdx->aSortOrder[nEq]==SQLITE_SO_DESC),
+                          pLevel->iLikeRepCntr);
+        VdbeComment((v, "LIKE loop counter"));
+        pLevel->addrLikeRep = sqlite3VdbeCurrentAddr(v);
+      }
       if( pRangeStart==0
        && (j = pIdx->aiColumn[nEq])>=0 
        && pIdx->pTable->aCol[j].notNull==0
@@ -114208,6 +119865,7 @@ static Bitmask codeOneLoopStart(
     if( pRangeStart ){
       Expr *pRight = pRangeStart->pExpr->pRight;
       sqlite3ExprCode(pParse, pRight, regBase+nEq);
+      whereLikeOptimizationStringFixup(v, pLevel, pRangeStart);
       if( (pRangeStart->wtFlags & TERM_VNULL)==0
        && sqlite3ExprCanBeNull(pRight)
       ){
@@ -114253,6 +119911,7 @@ static Bitmask codeOneLoopStart(
       Expr *pRight = pRangeEnd->pExpr->pRight;
       sqlite3ExprCacheRemove(pParse, regBase+nEq, 1);
       sqlite3ExprCode(pParse, pRight, regBase+nEq);
+      whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd);
       if( (pRangeEnd->wtFlags & TERM_VNULL)==0
        && sqlite3ExprCanBeNull(pRight)
       ){
@@ -114367,7 +120026,7 @@ static Bitmask codeOneLoopStart(
     **       B: <after the loop>
     **
     ** Added 2014-05-26: If the table is a WITHOUT ROWID table, then
-    ** use an ephermeral index instead of a RowSet to record the primary
+    ** use an ephemeral index instead of a RowSet to record the primary
     ** keys of the rows we have already seen.
     **
     */
@@ -114418,7 +120077,7 @@ static Bitmask codeOneLoopStart(
     }
 
     /* Initialize the rowset register to contain NULL. An SQL NULL is 
-    ** equivalent to an empty rowset.  Or, create an ephermeral index
+    ** equivalent to an empty rowset.  Or, create an ephemeral index
     ** capable of holding primary keys in the case of a WITHOUT ROWID.
     **
     ** Also initialize regReturn to contain the address of the instruction 
@@ -114463,10 +120122,9 @@ static Bitmask codeOneLoopStart(
         Expr *pExpr = pWC->a[iTerm].pExpr;
         if( &pWC->a[iTerm] == pTerm ) continue;
         if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
-        testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
-        testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL );
-        if( pWC->a[iTerm].wtFlags & (TERM_ORINFO|TERM_VIRTUAL) ) continue;
+        if( (pWC->a[iTerm].wtFlags & TERM_VIRTUAL)!=0 ) continue;
         if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
+        testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
         pExpr = sqlite3ExprDup(db, pExpr, 0);
         pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
       }
@@ -114479,8 +120137,10 @@ static Bitmask codeOneLoopStart(
     ** eliminating duplicates from other WHERE clauses, the action for each
     ** sub-WHERE clause is to to invoke the main loop body as a subroutine.
     */
-    wctrlFlags =  WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY |
-                  WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY;
+    wctrlFlags =  WHERE_OMIT_OPEN_CLOSE
+                | WHERE_FORCE_TABLE
+                | WHERE_ONETABLE_ONLY
+                | WHERE_NO_AUTOINDEX;
     for(ii=0; ii<pOrWc->nTerm; ii++){
       WhereTerm *pOrTerm = &pOrWc->a[ii];
       if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
@@ -114492,14 +120152,17 @@ static Bitmask codeOneLoopStart(
           pOrExpr = pAndExpr;
         }
         /* Loop through table entries that match term pOrTerm. */
+        WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
         pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
                                       wctrlFlags, iCovCur);
         assert( pSubWInfo || pParse->nErr || db->mallocFailed );
         if( pSubWInfo ){
           WhereLoop *pSubLoop;
-          explainOneScan(
+          int addrExplain = explainOneScan(
               pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
           );
+          addScanStatus(v, pOrTab, &pSubWInfo->a[0], addrExplain);
+
           /* This is the sub-WHERE clause body.  First skip over
           ** duplicate rows from prior sub-WHERE clauses, and record the
           ** rowid (or PRIMARY KEY) for the current row so that the same
@@ -114630,11 +120293,16 @@ static Bitmask codeOneLoopStart(
     }
   }
 
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+  pLevel->addrVisit = sqlite3VdbeCurrentAddr(v);
+#endif
+
   /* Insert code to test every subexpression that can be completely
   ** computed using the current set of tables.
   */
   for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
     Expr *pE;
+    int skipLikeAddr = 0;
     testcase( pTerm->wtFlags & TERM_VIRTUAL );
     testcase( pTerm->wtFlags & TERM_CODED );
     if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
@@ -114649,7 +120317,13 @@ static Bitmask codeOneLoopStart(
     if( pLevel->iLeftJoin && !ExprHasProperty(pE, EP_FromJoin) ){
       continue;
     }
+    if( pTerm->wtFlags & TERM_LIKECOND ){
+      assert( pLevel->iLikeRepCntr>0 );
+      skipLikeAddr = sqlite3VdbeAddOp1(v, OP_IfNot, pLevel->iLikeRepCntr);
+      VdbeCoverage(v);
+    }
     sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL);
+    if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr);
     pTerm->wtFlags |= TERM_CODED;
   }
 
@@ -114711,21 +120385,26 @@ static Bitmask codeOneLoopStart(
   return pLevel->notReady;
 }
 
-#if defined(WHERETRACE_ENABLED) && defined(SQLITE_ENABLE_TREE_EXPLAIN)
+#ifdef WHERETRACE_ENABLED
 /*
-** Generate "Explanation" text for a WhereTerm.
+** Print the content of a WhereTerm object
 */
-static void whereExplainTerm(Vdbe *v, WhereTerm *pTerm){
-  char zType[4];
-  memcpy(zType, "...", 4);
-  if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
-  if( pTerm->eOperator & WO_EQUIV  ) zType[1] = 'E';
-  if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
-  sqlite3ExplainPrintf(v, "%s ", zType);
-  sqlite3ExplainExpr(v, pTerm->pExpr);
+static void whereTermPrint(WhereTerm *pTerm, int iTerm){
+  if( pTerm==0 ){
+    sqlite3DebugPrintf("TERM-%-3d NULL\n", iTerm);
+  }else{
+    char zType[4];
+    memcpy(zType, "...", 4);
+    if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
+    if( pTerm->eOperator & WO_EQUIV  ) zType[1] = 'E';
+    if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
+    sqlite3DebugPrintf("TERM-%-3d %p %s cursor=%-3d prob=%-3d op=0x%03x\n",
+                       iTerm, pTerm, zType, pTerm->leftCursor, pTerm->truthProb,
+                       pTerm->eOperator);
+    sqlite3TreeViewExpr(0, pTerm->pExpr, 0);
+  }
 }
-#endif /* WHERETRACE_ENABLED && SQLITE_ENABLE_TREE_EXPLAIN */
-
+#endif
 
 #ifdef WHERETRACE_ENABLED
 /*
@@ -114741,8 +120420,8 @@ static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){
   sqlite3DebugPrintf(" %12s",
                      pItem->zAlias ? pItem->zAlias : pTab->zName);
   if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){
-     const char *zName;
-     if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){
+    const char *zName;
+    if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){
       if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){
         int i = sqlite3Strlen30(zName) - 1;
         while( zName[i]!='_' ) i--;
@@ -114763,29 +120442,18 @@ static void whereLoopPrint(WhereLoop *p, WhereClause *pWC){
     sqlite3DebugPrintf(" %-19s", z);
     sqlite3_free(z);
   }
-  sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm);
+  if( p->wsFlags & WHERE_SKIPSCAN ){
+    sqlite3DebugPrintf(" f %05x %d-%d", p->wsFlags, p->nLTerm,p->nSkip);
+  }else{
+    sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm);
+  }
   sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
-#ifdef SQLITE_ENABLE_TREE_EXPLAIN
-  /* If the 0x100 bit of wheretracing is set, then show all of the constraint
-  ** expressions in the WhereLoop.aLTerm[] array.
-  */
-  if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){  /* WHERETRACE 0x100 */
+  if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){
     int i;
-    Vdbe *v = pWInfo->pParse->pVdbe;
-    sqlite3ExplainBegin(v);
     for(i=0; i<p->nLTerm; i++){
-      WhereTerm *pTerm = p->aLTerm[i];
-      if( pTerm==0 ) continue;
-      sqlite3ExplainPrintf(v, "  (%d) #%-2d ", i+1, (int)(pTerm-pWC->a));
-      sqlite3ExplainPush(v);
-      whereExplainTerm(v, pTerm);
-      sqlite3ExplainPop(v);
-      sqlite3ExplainNL(v);
+      whereTermPrint(p->aLTerm[i], i);
     }
-    sqlite3ExplainFinish(v);
-    sqlite3DebugPrintf("%s", sqlite3VdbeExplanation(v));
   }
-#endif
 }
 #endif
 
@@ -114811,7 +120479,6 @@ static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){
       p->u.vtab.idxStr = 0;
     }else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){
       sqlite3DbFree(db, p->u.btree.pIndex->zColAff);
-      sqlite3KeyInfoUnref(p->u.btree.pIndex->pKeyInfo);
       sqlite3DbFree(db, p->u.btree.pIndex);
       p->u.btree.pIndex = 0;
     }
@@ -114875,6 +120542,13 @@ static void whereLoopDelete(sqlite3 *db, WhereLoop *p){
 */
 static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
   if( ALWAYS(pWInfo) ){
+    int i;
+    for(i=0; i<pWInfo->nLevel; i++){
+      WhereLevel *pLevel = &pWInfo->a[i];
+      if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){
+        sqlite3DbFree(db, pLevel->u.in.aInLoop);
+      }
+    }
     whereClauseClear(&pWInfo->sWC);
     while( pWInfo->pLoops ){
       WhereLoop *p = pWInfo->pLoops;
@@ -114886,10 +120560,11 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
 }
 
 /*
-** Return TRUE if both of the following are true:
+** Return TRUE if all of the following are true:
 **
 **   (1)  X has the same or lower cost that Y
 **   (2)  X is a proper subset of Y
+**   (3)  X skips at least as many columns as Y
 **
 ** By "proper subset" we mean that X uses fewer WHERE clause terms
 ** than Y and that every WHERE clause term used by X is also used
@@ -114897,19 +120572,25 @@ static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
 **
 ** If X is a proper subset of Y then Y is a better choice and ought
 ** to have a lower cost.  This routine returns TRUE when that cost 
-** relationship is inverted and needs to be adjusted.
+** relationship is inverted and needs to be adjusted.  The third rule
+** was added because if X uses skip-scan less than Y it still might
+** deserve a lower cost even if it is a proper subset of Y.
 */
 static int whereLoopCheaperProperSubset(
   const WhereLoop *pX,       /* First WhereLoop to compare */
   const WhereLoop *pY        /* Compare against this WhereLoop */
 ){
   int i, j;
-  if( pX->nLTerm >= pY->nLTerm ) return 0; /* X is not a subset of Y */
+  if( pX->nLTerm-pX->nSkip >= pY->nLTerm-pY->nSkip ){
+    return 0; /* X is not a subset of Y */
+  }
+  if( pY->nSkip > pX->nSkip ) return 0;
   if( pX->rRun >= pY->rRun ){
     if( pX->rRun > pY->rRun ) return 0;    /* X costs more than Y */
     if( pX->nOut > pY->nOut ) return 0;    /* X costs more than Y */
   }
   for(i=pX->nLTerm-1; i>=0; i--){
+    if( pX->aLTerm[i]==0 ) continue;
     for(j=pY->nLTerm-1; j>=0; j--){
       if( pY->aLTerm[j]==pX->aLTerm[i] ) break;
     }
@@ -114931,33 +120612,24 @@ static int whereLoopCheaperProperSubset(
 ** To say "WhereLoop X is a proper subset of Y" means that X uses fewer
 ** WHERE clause terms than Y and that every WHERE clause term used by X is
 ** also used by Y.
-**
-** This adjustment is omitted for SKIPSCAN loops.  In a SKIPSCAN loop, the
-** WhereLoop.nLTerm field is not an accurate measure of the number of WHERE
-** clause terms covered, since some of the first nLTerm entries in aLTerm[]
-** will be NULL (because they are skipped).  That makes it more difficult
-** to compare the loops.  We could add extra code to do the comparison, and
-** perhaps we will someday.  But SKIPSCAN is sufficiently uncommon, and this
-** adjustment is sufficient minor, that it is very difficult to construct
-** a test case where the extra code would improve the query plan.  Better
-** to avoid the added complexity and just omit cost adjustments to SKIPSCAN
-** loops.
 */
 static void whereLoopAdjustCost(const WhereLoop *p, WhereLoop *pTemplate){
   if( (pTemplate->wsFlags & WHERE_INDEXED)==0 ) return;
-  if( (pTemplate->wsFlags & WHERE_SKIPSCAN)!=0 ) return;
   for(; p; p=p->pNextLoop){
     if( p->iTab!=pTemplate->iTab ) continue;
     if( (p->wsFlags & WHERE_INDEXED)==0 ) continue;
-    if( (p->wsFlags & WHERE_SKIPSCAN)!=0 ) continue;
     if( whereLoopCheaperProperSubset(p, pTemplate) ){
       /* Adjust pTemplate cost downward so that it is cheaper than its 
-      ** subset p */
+      ** subset p. */
+      WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n",
+                       pTemplate->rRun, pTemplate->nOut, p->rRun, p->nOut-1));
       pTemplate->rRun = p->rRun;
       pTemplate->nOut = p->nOut - 1;
     }else if( whereLoopCheaperProperSubset(pTemplate, p) ){
       /* Adjust pTemplate cost upward so that it is costlier than p since
       ** pTemplate is a proper subset of p */
+      WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n",
+                       pTemplate->rRun, pTemplate->nOut, p->rRun, p->nOut+1));
       pTemplate->rRun = p->rRun;
       pTemplate->nOut = p->nOut + 1;
     }
@@ -115002,8 +120674,9 @@ static WhereLoop **whereLoopFindLesser(
 
     /* Any loop using an appliation-defined index (or PRIMARY KEY or
     ** UNIQUE constraint) with one or more == constraints is better
-    ** than an automatic index. */
+    ** than an automatic index. Unless it is a skip-scan. */
     if( (p->wsFlags & WHERE_AUTO_INDEX)!=0
+     && (pTemplate->nSkip)==0
      && (pTemplate->wsFlags & WHERE_INDEXED)!=0
      && (pTemplate->wsFlags & WHERE_COLUMN_EQ)!=0
      && (p->prereq & pTemplate->prereq)==pTemplate->prereq
@@ -115098,7 +120771,7 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
     ** than pTemplate, so just ignore pTemplate */
 #if WHERETRACE_ENABLED /* 0x8 */
     if( sqlite3WhereTrace & 0x8 ){
-      sqlite3DebugPrintf("ins-noop: ");
+      sqlite3DebugPrintf("   skip: ");
       whereLoopPrint(pTemplate, pBuilder->pWC);
     }
 #endif
@@ -115114,10 +120787,10 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
 #if WHERETRACE_ENABLED /* 0x8 */
   if( sqlite3WhereTrace & 0x8 ){
     if( p!=0 ){
-      sqlite3DebugPrintf("ins-del:  ");
+      sqlite3DebugPrintf("replace: ");
       whereLoopPrint(p, pBuilder->pWC);
     }
-    sqlite3DebugPrintf("ins-new:  ");
+    sqlite3DebugPrintf("    add: ");
     whereLoopPrint(pTemplate, pBuilder->pWC);
   }
 #endif
@@ -115141,7 +120814,7 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
       *ppTail = pToDel->pNextLoop;
 #if WHERETRACE_ENABLED /* 0x8 */
       if( sqlite3WhereTrace & 0x8 ){
-        sqlite3DebugPrintf("ins-del:  ");
+        sqlite3DebugPrintf(" delete: ");
         whereLoopPrint(pToDel, pBuilder->pWC);
       }
 #endif
@@ -115162,19 +120835,42 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
 ** Adjust the WhereLoop.nOut value downward to account for terms of the
 ** WHERE clause that reference the loop but which are not used by an
 ** index.
-**
-** In the current implementation, the first extra WHERE clause term reduces
-** the number of output rows by a factor of 10 and each additional term
-** reduces the number of output rows by sqrt(2).
-*/
-static void whereLoopOutputAdjust(WhereClause *pWC, WhereLoop *pLoop){
+*
+** For every WHERE clause term that is not used by the index
+** and which has a truth probability assigned by one of the likelihood(),
+** likely(), or unlikely() SQL functions, reduce the estimated number
+** of output rows by the probability specified.
+**
+** TUNING:  For every WHERE clause term that is not used by the index
+** and which does not have an assigned truth probability, heuristics
+** described below are used to try to estimate the truth probability.
+** TODO --> Perhaps this is something that could be improved by better
+** table statistics.
+**
+** Heuristic 1:  Estimate the truth probability as 93.75%.  The 93.75%
+** value corresponds to -1 in LogEst notation, so this means decrement
+** the WhereLoop.nOut field for every such WHERE clause term.
+**
+** Heuristic 2:  If there exists one or more WHERE clause terms of the
+** form "x==EXPR" and EXPR is not a constant 0 or 1, then make sure the
+** final output row estimate is no greater than 1/4 of the total number
+** of rows in the table.  In other words, assume that x==EXPR will filter
+** out at least 3 out of 4 rows.  If EXPR is -1 or 0 or 1, then maybe the
+** "x" column is boolean or else -1 or 0 or 1 is a common default value
+** on the "x" column and so in that case only cap the output row estimate
+** at 1/2 instead of 1/4.
+*/
+static void whereLoopOutputAdjust(
+  WhereClause *pWC,      /* The WHERE clause */
+  WhereLoop *pLoop,      /* The loop to adjust downward */
+  LogEst nRow            /* Number of rows in the entire table */
+){
   WhereTerm *pTerm, *pX;
   Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf);
-  int i, j;
+  int i, j, k;
+  LogEst iReduce = 0;    /* pLoop->nOut should not exceed nRow-iReduce */
 
-  if( !OptimizationEnabled(pWC->pWInfo->pParse->db, SQLITE_AdjustOutEst) ){
-    return;
-  }
+  assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 );
   for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){
     if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break;
     if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue;
@@ -115186,9 +120882,27 @@ static void whereLoopOutputAdjust(WhereClause *pWC, WhereLoop *pLoop){
       if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break;
     }
     if( j<0 ){
-      pLoop->nOut += (pTerm->truthProb<=0 ? pTerm->truthProb : -1);
+      if( pTerm->truthProb<=0 ){
+        /* If a truth probability is specified using the likelihood() hints,
+        ** then use the probability provided by the application. */
+        pLoop->nOut += pTerm->truthProb;
+      }else{
+        /* In the absence of explicit truth probabilities, use heuristics to
+        ** guess a reasonable truth probability. */
+        pLoop->nOut--;
+        if( pTerm->eOperator&WO_EQ ){
+          Expr *pRight = pTerm->pExpr->pRight;
+          if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){
+            k = 10;
+          }else{
+            k = 20;
+          }
+          if( iReduce<k ) iReduce = k;
+        }
+      }
     }
   }
+  if( pLoop->nOut > nRow-iReduce )  pLoop->nOut = nRow - iReduce;
 }
 
 /*
@@ -115229,11 +120943,12 @@ static int whereLoopAddBtreeIndex(
   Bitmask saved_prereq;           /* Original value of pNew->prereq */
   u16 saved_nLTerm;               /* Original value of pNew->nLTerm */
   u16 saved_nEq;                  /* Original value of pNew->u.btree.nEq */
-  u16 saved_nSkip;                /* Original value of pNew->u.btree.nSkip */
+  u16 saved_nSkip;                /* Original value of pNew->nSkip */
   u32 saved_wsFlags;              /* Original value of pNew->wsFlags */
   LogEst saved_nOut;              /* Original value of pNew->nOut */
   int iCol;                       /* Index of the column in the table */
   int rc = SQLITE_OK;             /* Return code */
+  LogEst rSize;                   /* Number of rows in the table */
   LogEst rLogSize;                /* Logarithm of table size */
   WhereTerm *pTop = 0, *pBtm = 0; /* Top and bottom range constraints */
 
@@ -115257,41 +120972,14 @@ static int whereLoopAddBtreeIndex(
   pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, iCol,
                         opMask, pProbe);
   saved_nEq = pNew->u.btree.nEq;
-  saved_nSkip = pNew->u.btree.nSkip;
+  saved_nSkip = pNew->nSkip;
   saved_nLTerm = pNew->nLTerm;
   saved_wsFlags = pNew->wsFlags;
   saved_prereq = pNew->prereq;
   saved_nOut = pNew->nOut;
   pNew->rSetup = 0;
-  rLogSize = estLog(pProbe->aiRowLogEst[0]);
-
-  /* Consider using a skip-scan if there are no WHERE clause constraints
-  ** available for the left-most terms of the index, and if the average
-  ** number of repeats in the left-most terms is at least 18. 
-  **
-  ** The magic number 18 is selected on the basis that scanning 17 rows
-  ** is almost always quicker than an index seek (even though if the index
-  ** contains fewer than 2^17 rows we assume otherwise in other parts of
-  ** the code). And, even if it is not, it should not be too much slower. 
-  ** On the other hand, the extra seeks could end up being significantly
-  ** more expensive.  */
-  assert( 42==sqlite3LogEst(18) );
-  if( pTerm==0
-   && saved_nEq==saved_nSkip
-   && saved_nEq+1<pProbe->nKeyCol
-   && pProbe->aiRowLogEst[saved_nEq+1]>=42  /* TUNING: Minimum for skip-scan */
-   && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
-  ){
-    LogEst nIter;
-    pNew->u.btree.nEq++;
-    pNew->u.btree.nSkip++;
-    pNew->aLTerm[pNew->nLTerm++] = 0;
-    pNew->wsFlags |= WHERE_SKIPSCAN;
-    nIter = pProbe->aiRowLogEst[saved_nEq] - pProbe->aiRowLogEst[saved_nEq+1];
-    pNew->nOut -= nIter;
-    whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul);
-    pNew->nOut = saved_nOut;
-  }
+  rSize = pProbe->aiRowLogEst[0];
+  rLogSize = estLog(rSize);
   for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){
     u16 eOp = pTerm->eOperator;   /* Shorthand for pTerm->eOperator */
     LogEst rCostIdx;
@@ -115307,6 +120995,10 @@ static int whereLoopAddBtreeIndex(
     }
     if( pTerm->prereqRight & pNew->maskSelf ) continue;
 
+    /* Do not allow the upper bound of a LIKE optimization range constraint
+    ** to mix with a lower range bound from some other source */
+    if( pTerm->wtFlags & TERM_LIKEOPT && pTerm->eOperator==WO_LT ) continue;
+
     pNew->wsFlags = saved_wsFlags;
     pNew->u.btree.nEq = saved_nEq;
     pNew->nLTerm = saved_nLTerm;
@@ -115336,7 +121028,7 @@ static int whereLoopAddBtreeIndex(
     }else if( eOp & (WO_EQ) ){
       pNew->wsFlags |= WHERE_COLUMN_EQ;
       if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1) ){
-        if( iCol>=0 && !IsUniqueIndex(pProbe) ){
+        if( iCol>=0 && pProbe->uniqNotNull==0 ){
           pNew->wsFlags |= WHERE_UNQ_WANTED;
         }else{
           pNew->wsFlags |= WHERE_ONEROW;
@@ -115350,6 +121042,17 @@ static int whereLoopAddBtreeIndex(
       pNew->wsFlags |= WHERE_COLUMN_RANGE|WHERE_BTM_LIMIT;
       pBtm = pTerm;
       pTop = 0;
+      if( pTerm->wtFlags & TERM_LIKEOPT ){
+        /* Range contraints that come from the LIKE optimization are
+        ** always used in pairs. */
+        pTop = &pTerm[1];
+        assert( (pTop-(pTerm->pWC->a))<pTerm->pWC->nTerm );
+        assert( pTop->wtFlags & TERM_LIKEOPT );
+        assert( pTop->eOperator==WO_LT );
+        if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */
+        pNew->aLTerm[pNew->nLTerm++] = pTop;
+        pNew->wsFlags |= WHERE_TOP_LIMIT;
+      }
     }else{
       assert( eOp & (WO_LT|WO_LE) );
       testcase( eOp & WO_LT );
@@ -115386,7 +121089,6 @@ static int whereLoopAddBtreeIndex(
         if( nInMul==0 
          && pProbe->nSample 
          && pNew->u.btree.nEq<=pProbe->nSampleCol
-         && OptimizationEnabled(db, SQLITE_Stat3) 
          && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect))
         ){
           Expr *pExpr = pTerm->pExpr;
@@ -115433,7 +121135,7 @@ static int whereLoopAddBtreeIndex(
     nOutUnadjusted = pNew->nOut;
     pNew->rRun += nInMul + nIn;
     pNew->nOut += nInMul + nIn;
-    whereLoopOutputAdjust(pBuilder->pWC, pNew);
+    whereLoopOutputAdjust(pBuilder->pWC, pNew, rSize);
     rc = whereLoopInsert(pBuilder, pNew);
 
     if( pNew->wsFlags & WHERE_COLUMN_RANGE ){
@@ -115454,10 +121156,45 @@ static int whereLoopAddBtreeIndex(
   }
   pNew->prereq = saved_prereq;
   pNew->u.btree.nEq = saved_nEq;
-  pNew->u.btree.nSkip = saved_nSkip;
+  pNew->nSkip = saved_nSkip;
   pNew->wsFlags = saved_wsFlags;
   pNew->nOut = saved_nOut;
   pNew->nLTerm = saved_nLTerm;
+
+  /* Consider using a skip-scan if there are no WHERE clause constraints
+  ** available for the left-most terms of the index, and if the average
+  ** number of repeats in the left-most terms is at least 18. 
+  **
+  ** The magic number 18 is selected on the basis that scanning 17 rows
+  ** is almost always quicker than an index seek (even though if the index
+  ** contains fewer than 2^17 rows we assume otherwise in other parts of
+  ** the code). And, even if it is not, it should not be too much slower. 
+  ** On the other hand, the extra seeks could end up being significantly
+  ** more expensive.  */
+  assert( 42==sqlite3LogEst(18) );
+  if( saved_nEq==saved_nSkip
+   && saved_nEq+1<pProbe->nKeyCol
+   && pProbe->noSkipScan==0
+   && pProbe->aiRowLogEst[saved_nEq+1]>=42  /* TUNING: Minimum for skip-scan */
+   && (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
+  ){
+    LogEst nIter;
+    pNew->u.btree.nEq++;
+    pNew->nSkip++;
+    pNew->aLTerm[pNew->nLTerm++] = 0;
+    pNew->wsFlags |= WHERE_SKIPSCAN;
+    nIter = pProbe->aiRowLogEst[saved_nEq] - pProbe->aiRowLogEst[saved_nEq+1];
+    pNew->nOut -= nIter;
+    /* TUNING:  Because uncertainties in the estimates for skip-scan queries,
+    ** add a 1.375 fudge factor to make skip-scan slightly less likely. */
+    nIter += 5;
+    whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nIter + nInMul);
+    pNew->nOut = saved_nOut;
+    pNew->u.btree.nEq = saved_nEq;
+    pNew->nSkip = saved_nSkip;
+    pNew->wsFlags = saved_wsFlags;
+  }
+
   return rc;
 }
 
@@ -115483,6 +121220,7 @@ static int indexMightHelpWithOrderBy(
     Expr *pExpr = sqlite3ExprSkipCollate(pOB->a[ii].pExpr);
     if( pExpr->op!=TK_COLUMN ) return 0;
     if( pExpr->iTable==iCursor ){
+      if( pExpr->iColumn<0 ) return 1;
       for(jj=0; jj<pIndex->nKeyCol; jj++){
         if( pExpr->iColumn==pIndex->aiColumn[jj] ) return 1;
       }
@@ -115516,7 +121254,12 @@ static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
   int i;
   WhereTerm *pTerm;
   for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
-    if( sqlite3ExprImpliesExpr(pTerm->pExpr, pWhere, iTab) ) return 1;
+    Expr *pExpr = pTerm->pExpr;
+    if( sqlite3ExprImpliesExpr(pExpr, pWhere, iTab) 
+     && (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab)
+    ){
+      return 1;
+    }
   }
   return 0;
 }
@@ -115620,6 +121363,7 @@ static int whereLoopAddBtree(
 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
   /* Automatic indexes */
   if( !pBuilder->pOrSet
+   && (pWInfo->wctrlFlags & WHERE_NO_AUTOINDEX)==0
    && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
    && pSrc->pIndex==0
    && !pSrc->viaCoroutine
@@ -115635,18 +121379,26 @@ static int whereLoopAddBtree(
       if( pTerm->prereqRight & pNew->maskSelf ) continue;
       if( termCanDriveIndex(pTerm, pSrc, 0) ){
         pNew->u.btree.nEq = 1;
-        pNew->u.btree.nSkip = 0;
+        pNew->nSkip = 0;
         pNew->u.btree.pIndex = 0;
         pNew->nLTerm = 1;
         pNew->aLTerm[0] = pTerm;
         /* TUNING: One-time cost for computing the automatic index is
-        ** approximately 7*N*log2(N) where N is the number of rows in
-        ** the table being indexed. */
-        pNew->rSetup = rLogSize + rSize + 28;  assert( 28==sqlite3LogEst(7) );
+        ** estimated to be X*N*log2(N) where N is the number of rows in
+        ** the table being indexed and where X is 7 (LogEst=28) for normal
+        ** tables or 1.375 (LogEst=4) for views and subqueries.  The value
+        ** of X is smaller for views and subqueries so that the query planner
+        ** will be more aggressive about generating automatic indexes for
+        ** those objects, since there is no opportunity to add schema
+        ** indexes on subqueries and views. */
+        pNew->rSetup = rLogSize + rSize + 4;
+        if( pTab->pSelect==0 && (pTab->tabFlags & TF_Ephemeral)==0 ){
+          pNew->rSetup += 24;
+        }
         ApplyCostMultiplier(pNew->rSetup, pTab->costMult);
         /* TUNING: Each index lookup yields 20 rows in the table.  This
         ** is more than the usual guess of 10 rows, since we have no way
-        ** of knowning how selective the index will ultimately be.  It would
+        ** of knowing how selective the index will ultimately be.  It would
         ** not be unreasonable to make this value much larger. */
         pNew->nOut = 43;  assert( 43==sqlite3LogEst(20) );
         pNew->rRun = sqlite3LogEstAdd(rLogSize,pNew->nOut);
@@ -115662,12 +121414,13 @@ static int whereLoopAddBtree(
   */
   for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){
     if( pProbe->pPartIdxWhere!=0
-     && !whereUsablePartialIndex(pNew->iTab, pWC, pProbe->pPartIdxWhere) ){
+     && !whereUsablePartialIndex(pSrc->iCursor, pWC, pProbe->pPartIdxWhere) ){
+      testcase( pNew->iTab!=pSrc->iCursor );  /* See ticket [98d973b8f5] */
       continue;  /* Partial index inappropriate for this query */
     }
     rSize = pProbe->aiRowLogEst[0];
     pNew->u.btree.nEq = 0;
-    pNew->u.btree.nSkip = 0;
+    pNew->nSkip = 0;
     pNew->nLTerm = 0;
     pNew->iSortIdx = 0;
     pNew->rSetup = 0;
@@ -115686,7 +121439,7 @@ static int whereLoopAddBtree(
       /* TUNING: Cost of full table scan is (N*3.0). */
       pNew->rRun = rSize + 16;
       ApplyCostMultiplier(pNew->rRun, pTab->costMult);
-      whereLoopOutputAdjust(pWC, pNew);
+      whereLoopOutputAdjust(pWC, pNew, rSize);
       rc = whereLoopInsert(pBuilder, pNew);
       pNew->nOut = rSize;
       if( rc ) break;
@@ -115722,7 +121475,7 @@ static int whereLoopAddBtree(
           pNew->rRun = sqlite3LogEstAdd(pNew->rRun, rSize+16);
         }
         ApplyCostMultiplier(pNew->rRun, pTab->costMult);
-        whereLoopOutputAdjust(pWC, pNew);
+        whereLoopOutputAdjust(pWC, pNew, rSize);
         rc = whereLoopInsert(pBuilder, pNew);
         pNew->nOut = rSize;
         if( rc ) break;
@@ -115929,7 +121682,6 @@ static int whereLoopAddOr(WhereLoopBuilder *pBuilder, Bitmask mExtra){
   struct SrcList_item *pItem;
   
   pWC = pBuilder->pWC;
-  if( pWInfo->wctrlFlags & WHERE_AND_ONLY ) return SQLITE_OK;
   pWCEnd = pWC->a + pWC->nTerm;
   pNew = pBuilder->pNew;
   memset(&sSum, 0, sizeof(sSum));
@@ -115950,6 +121702,7 @@ static int whereLoopAddOr(WhereLoopBuilder *pBuilder, Bitmask mExtra){
       sSubBuild.pOrderBy = 0;
       sSubBuild.pOrSet = &sCur;
 
+      WHERETRACE(0x200, ("Begin processing OR-clause %p\n", pTerm));
       for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
         if( (pOrTerm->eOperator & WO_AND)!=0 ){
           sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc;
@@ -115964,6 +121717,15 @@ static int whereLoopAddOr(WhereLoopBuilder *pBuilder, Bitmask mExtra){
           continue;
         }
         sCur.n = 0;
+#ifdef WHERETRACE_ENABLED
+        WHERETRACE(0x200, ("OR-term %d of %p has %d subterms:\n", 
+                   (int)(pOrTerm-pOrWC->a), pTerm, sSubBuild.pWC->nTerm));
+        if( sqlite3WhereTrace & 0x400 ){
+          for(i=0; i<sSubBuild.pWC->nTerm; i++){
+            whereTermPrint(&sSubBuild.pWC->a[i], i);
+          }
+        }
+#endif
 #ifndef SQLITE_OMIT_VIRTUALTABLE
         if( IsVirtual(pItem->pTab) ){
           rc = whereLoopAddVirtual(&sSubBuild, mExtra);
@@ -115972,6 +121734,9 @@ static int whereLoopAddOr(WhereLoopBuilder *pBuilder, Bitmask mExtra){
         {
           rc = whereLoopAddBtree(&sSubBuild, mExtra);
         }
+        if( rc==SQLITE_OK ){
+          rc = whereLoopAddOr(&sSubBuild, mExtra);
+        }
         assert( rc==SQLITE_OK || sCur.n==0 );
         if( sCur.n==0 ){
           sSum.n = 0;
@@ -116016,6 +121781,7 @@ static int whereLoopAddOr(WhereLoopBuilder *pBuilder, Bitmask mExtra){
         pNew->prereq = sSum.a[i].prereq;
         rc = whereLoopInsert(pBuilder, pNew);
       }
+      WHERETRACE(0x200, ("End processing OR-clause %p\n", pTerm));
     }
   }
   return rc;
@@ -116075,7 +121841,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){
 ** strict.  With GROUP BY and DISTINCT the only requirement is that
 ** equivalent rows appear immediately adjacent to one another.  GROUP BY
 ** and DISTINCT do not require rows to appear in any particular order as long
-** as equivelent rows are grouped together.  Thus for GROUP BY and DISTINCT
+** as equivalent rows are grouped together.  Thus for GROUP BY and DISTINCT
 ** the pOrderBy terms can be matched in any order.  With ORDER BY, the 
 ** pOrderBy terms must be matched in strict left-to-right order.
 */
@@ -116204,7 +121970,7 @@ static i8 wherePathSatisfiesOrderBy(
 
         /* Skip over == and IS NULL terms */
         if( j<pLoop->u.btree.nEq
-         && pLoop->u.btree.nSkip==0
+         && pLoop->nSkip==0
          && ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL))!=0
         ){
           if( i & WO_ISNULL ){
@@ -116259,7 +122025,7 @@ static i8 wherePathSatisfiesOrderBy(
           isMatch = 1;
           break;
         }
-        if( isMatch && (pWInfo->wctrlFlags & WHERE_GROUPBY)==0 ){
+        if( isMatch && (wctrlFlags & WHERE_GROUPBY)==0 ){
           /* Make sure the sort order is compatible in an ORDER BY clause.
           ** Sort order is irrelevant for a GROUP BY clause. */
           if( revSet ){
@@ -116481,10 +122247,10 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
 
   /* Seed the search with a single WherePath containing zero WhereLoops.
   **
-  ** TUNING: Do not let the number of iterations go above 25.  If the cost
-  ** of computing an automatic index is not paid back within the first 25
+  ** TUNING: Do not let the number of iterations go above 28.  If the cost
+  ** of computing an automatic index is not paid back within the first 28
   ** rows, then do not use the automatic index. */
-  aFrom[0].nRow = MIN(pParse->nQueryLoop, 46);  assert( 46==sqlite3LogEst(25) );
+  aFrom[0].nRow = MIN(pParse->nQueryLoop, 48);  assert( 48==sqlite3LogEst(28) );
   nFrom = 1;
   assert( aFrom[0].isOrdered==0 );
   if( nOrderBy ){
@@ -116658,7 +122424,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
     }
 
 #ifdef WHERETRACE_ENABLED  /* >=2 */
-    if( sqlite3WhereTrace>=2 ){
+    if( sqlite3WhereTrace & 0x02 ){
       sqlite3DebugPrintf("---- after round %d ----\n", iLoop);
       for(ii=0, pTo=aTo; ii<nTo; ii++, pTo++){
         sqlite3DebugPrintf(" %s cost=%-3d nrow=%-3d order=%c",
@@ -116722,14 +122488,17 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
       pWInfo->revMask = pFrom->revLoop;
     }
     if( (pWInfo->wctrlFlags & WHERE_SORTBYGROUP)
-        && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr
+        && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr && nLoop>0
     ){
-      Bitmask notUsed = 0;
+      Bitmask revMask = 0;
       int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, 
-          pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &notUsed
+          pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &revMask
       );
       assert( pWInfo->sorted==0 );
-      pWInfo->sorted = (nOrder==pWInfo->pOrderBy->nExpr);
+      if( nOrder==pWInfo->pOrderBy->nExpr ){
+        pWInfo->sorted = 1;
+        pWInfo->revMask = revMask;
+      }
     }
   }
 
@@ -116774,7 +122543,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
   pWC = &pWInfo->sWC;
   pLoop = pBuilder->pNew;
   pLoop->wsFlags = 0;
-  pLoop->u.btree.nSkip = 0;
+  pLoop->nSkip = 0;
   pTerm = findTerm(pWC, iCur, -1, 0, WO_EQ, 0);
   if( pTerm ){
     pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW;
@@ -116786,7 +122555,6 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){
   }else{
     for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
       assert( pLoop->aLTermSpace==pLoop->aLTerm );
-      assert( ArraySize(pLoop->aLTermSpace)==4 );
       if( !IsUniqueIndex(pIdx)
        || pIdx->pPartIdxWhere!=0 
        || pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace) 
@@ -117082,23 +122850,16 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
 
   /* Construct the WhereLoop objects */
   WHERETRACE(0xffff,("*** Optimizer Start ***\n"));
+#if defined(WHERETRACE_ENABLED)
   /* Display all terms of the WHERE clause */
-#if defined(WHERETRACE_ENABLED) && defined(SQLITE_ENABLE_TREE_EXPLAIN)
   if( sqlite3WhereTrace & 0x100 ){
     int i;
-    Vdbe *v = pParse->pVdbe;
-    sqlite3ExplainBegin(v);
     for(i=0; i<sWLB.pWC->nTerm; i++){
-      sqlite3ExplainPrintf(v, "#%-2d ", i);
-      sqlite3ExplainPush(v);
-      whereExplainTerm(v, &sWLB.pWC->a[i]);
-      sqlite3ExplainPop(v);
-      sqlite3ExplainNL(v);
+      whereTermPrint(&sWLB.pWC->a[i], i);
     }
-    sqlite3ExplainFinish(v);
-    sqlite3DebugPrintf("%s", sqlite3VdbeExplanation(v));
   }
 #endif
+
   if( nTabList!=1 || whereShortCut(&sWLB)==0 ){
     rc = whereLoopAddAll(&sWLB);
     if( rc ) goto whereBeginError;
@@ -117132,7 +122893,6 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
   }
 #ifdef WHERETRACE_ENABLED /* !=0 */
   if( sqlite3WhereTrace ){
-    int ii;
     sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut);
     if( pWInfo->nOBSat>0 ){
       sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask);
@@ -117287,6 +123047,12 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
       if( op ){
         sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb);
         sqlite3VdbeSetP4KeyInfo(pParse, pIx);
+        if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0
+         && (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0
+         && (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0
+        ){
+          sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); /* Hint to COMDB2 */
+        }
         VdbeComment((v, "%s", pIx->zName));
       }
     }
@@ -117302,7 +123068,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
   */
   notReady = ~(Bitmask)0;
   for(ii=0; ii<nTabList; ii++){
+    int addrExplain;
+    int wsFlags;
     pLevel = &pWInfo->a[ii];
+    wsFlags = pLevel->pWLoop->wsFlags;
 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
     if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
       constructAutomaticIndex(pParse, &pWInfo->sWC,
@@ -117310,10 +123079,15 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(
       if( db->mallocFailed ) goto whereBeginError;
     }
 #endif
-    explainOneScan(pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags);
+    addrExplain = explainOneScan(
+        pParse, pTabList, pLevel, ii, pLevel->iFrom, wctrlFlags
+    );
     pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
     notReady = codeOneLoopStart(pWInfo, ii, notReady);
     pWInfo->iContinue = pLevel->addrCont;
+    if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_ONETABLE_ONLY)==0 ){
+      addScanStatus(v, pTabList, pLevel, addrExplain);
+    }
   }
 
   /* Done. */
@@ -117371,7 +123145,6 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
         VdbeCoverageIf(v, pIn->eEndLoopOp==OP_NextIfOpen);
         sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
       }
-      sqlite3DbFree(db, pLevel->u.in.aInLoop);
     }
     sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
     if( pLevel->addrSkip ){
@@ -117380,6 +123153,16 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
       sqlite3VdbeJumpHere(v, pLevel->addrSkip);
       sqlite3VdbeJumpHere(v, pLevel->addrSkip-2);
     }
+    if( pLevel->addrLikeRep ){
+      int op;
+      if( sqlite3VdbeGetOp(v, pLevel->addrLikeRep-1)->p1 ){
+        op = OP_DecrJumpZero;
+      }else{
+        op = OP_JumpZeroIncr;
+      }
+      sqlite3VdbeAddOp2(v, op, pLevel->iLikeRepCntr, pLevel->addrLikeRep);
+      VdbeCoverage(v);
+    }
     if( pLevel->iLeftJoin ){
       addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v);
       assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0
@@ -117573,6 +123356,28 @@ struct TrigEvent { int a; IdList * b; };
 struct AttachKey { int type;  Token key; };
 
 
+  /*
+  ** For a compound SELECT statement, make sure p->pPrior->pNext==p for
+  ** all elements in the list.  And make sure list length does not exceed
+  ** SQLITE_LIMIT_COMPOUND_SELECT.
+  */
+  static void parserDoubleLinkSelect(Parse *pParse, Select *p){
+    if( p->pPrior ){
+      Select *pNext = 0, *pLoop;
+      int mxSelect, cnt = 0;
+      for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){
+        pLoop->pNext = pNext;
+        pLoop->selFlags |= SF_Compound;
+      }
+      if( (p->selFlags & SF_MultiValue)==0 && 
+        (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 &&
+        cnt>mxSelect
+      ){
+        sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
+      }
+    }
+  }
+
   /* This is a utility routine used to set the ExprSpan.zStart and
   ** ExprSpan.zEnd values of pOut so that the span covers the complete
   ** range of text beginning with pStart and going to the end of pEnd.
@@ -117625,7 +123430,7 @@ struct AttachKey { int type;  Token key; };
   ** unary TK_ISNULL or TK_NOTNULL expression. */
   static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){
     sqlite3 *db = pParse->db;
-    if( db->mallocFailed==0 && pY->op==TK_NULL ){
+    if( pY && pA && pY->op==TK_NULL ){
       pA->op = (u8)op;
       sqlite3ExprDelete(db, pA->pRight);
       pA->pRight = 0;
@@ -118852,9 +124657,9 @@ static void yyGrowStack(yyParser *p){
 ** A pointer to a parser.  This pointer is used in subsequent calls
 ** to sqlite3Parser and sqlite3ParserFree.
 */
-SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(size_t)){
+SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(u64)){
   yyParser *pParser;
-  pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
+  pParser = (yyParser*)(*mallocProc)( (u64)sizeof(yyParser) );
   if( pParser ){
     pParser->yyidx = -1;
 #ifdef YYTRACKMAXSTACKDEPTH
@@ -119884,29 +125689,15 @@ static void yy_reduce(
 {
   SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0};
   sqlite3Select(pParse, yymsp[0].minor.yy3, &dest);
-  sqlite3ExplainBegin(pParse->pVdbe);
-  sqlite3ExplainSelect(pParse->pVdbe, yymsp[0].minor.yy3);
-  sqlite3ExplainFinish(pParse->pVdbe);
   sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy3);
 }
         break;
       case 112: /* select ::= with selectnowith */
 {
-  Select *p = yymsp[0].minor.yy3, *pNext, *pLoop;
+  Select *p = yymsp[0].minor.yy3;
   if( p ){
-    int cnt = 0, mxSelect;
     p->pWith = yymsp[-1].minor.yy59;
-    if( p->pPrior ){
-      pNext = 0;
-      for(pLoop=p; pLoop; pNext=pLoop, pLoop=pLoop->pPrior, cnt++){
-        pLoop->pNext = pNext;
-        pLoop->selFlags |= SF_Compound;
-      }
-      mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT];
-      if( mxSelect && cnt>mxSelect ){
-        sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
-      }
-    }
+    parserDoubleLinkSelect(pParse, p);
   }else{
     sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy59);
   }
@@ -119924,12 +125715,14 @@ static void yy_reduce(
     SrcList *pFrom;
     Token x;
     x.n = 0;
+    parserDoubleLinkSelect(pParse, pRhs);
     pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
     pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0);
   }
   if( pRhs ){
     pRhs->op = (u8)yymsp[-1].minor.yy328;
     pRhs->pPrior = yymsp[-2].minor.yy3;
+    pRhs->selFlags &= ~SF_MultiValue;
     if( yymsp[-1].minor.yy328!=TK_ALL ) pParse->hasCompound = 1;
   }else{
     sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy3);
@@ -119943,6 +125736,30 @@ static void yy_reduce(
       case 118: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt 
orderby_opt limit_opt */
 {
   yygotominor.yy3 = 
sqlite3SelectNew(pParse,yymsp[-6].minor.yy14,yymsp[-5].minor.yy65,yymsp[-4].minor.yy132,yymsp[-3].minor.yy14,yymsp[-2].minor.yy132,yymsp[-1].minor.yy14,yymsp[-7].minor.yy381,yymsp[0].minor.yy476.pLimit,yymsp[0].minor.yy476.pOffset);
+#if SELECTTRACE_ENABLED
+  /* Populate the Select.zSelName[] string that is used to help with
+  ** query planner debugging, to differentiate between multiple Select
+  ** objects in a complex query.
+  **
+  ** If the SELECT keyword is immediately followed by a C-style comment
+  ** then extract the first few alphanumeric characters from within that
+  ** comment to be the zSelName value.  Otherwise, the label is #N where
+  ** is an integer that is incremented with each SELECT statement seen.
+  */
+  if( yygotominor.yy3!=0 ){
+    const char *z = yymsp[-8].minor.yy0.z+6;
+    int i;
+    sqlite3_snprintf(sizeof(yygotominor.yy3->zSelName), yygotominor.yy3->zSelName, "#%d",
+                     ++pParse->nSelect);
+    while( z[0]==' ' ) z++;
+    if( z[0]=='/' && z[1]=='*' ){
+      z += 2;
+      while( z[0]==' ' ) z++;
+      for(i=0; sqlite3Isalnum(z[i]); i++){}
+      sqlite3_snprintf(sizeof(yygotominor.yy3->zSelName), yygotominor.yy3->zSelName, "%.*s", i, z);
+    }
+  }
+#endif /* SELECTRACE_ENABLED */
 }
         break;
       case 120: /* values ::= VALUES LP nexprlist RP */
@@ -119952,13 +125769,16 @@ static void yy_reduce(
         break;
       case 121: /* values ::= values COMMA LP exprlist RP */
 {
-  Select *pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values,0,0);
+  Select *pRight, *pLeft = yymsp[-4].minor.yy3;
+  pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy14,0,0,0,0,0,SF_Values|SF_MultiValue,0,0);
+  if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
   if( pRight ){
     pRight->op = TK_ALL;
-    pRight->pPrior = yymsp[-4].minor.yy3;
+    pLeft = yymsp[-4].minor.yy3;
+    pRight->pPrior = pLeft;
     yygotominor.yy3 = pRight;
   }else{
-    yygotominor.yy3 = yymsp[-4].minor.yy3;
+    yygotominor.yy3 = pLeft;
   }
 }
         break;
@@ -120243,7 +126063,7 @@ static void yy_reduce(
         break;
       case 193: /* expr ::= expr COLLATE ID|STRING */
 {
-  yygotominor.yy346.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy346.pExpr, 
&yymsp[0].minor.yy0);
+  yygotominor.yy346.pExpr = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy346.pExpr, 
&yymsp[0].minor.yy0, 1);
   yygotominor.yy346.zStart = yymsp[-2].minor.yy346.zStart;
   yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n];
 }
@@ -120406,7 +126226,7 @@ static void yy_reduce(
       yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy346.pExpr, 0, 0);
       if( yygotominor.yy346.pExpr ){
         yygotominor.yy346.pExpr->x.pList = yymsp[-1].minor.yy14;
-        sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr);
+        sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr);
       }else{
         sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14);
       }
@@ -120421,8 +126241,8 @@ static void yy_reduce(
     yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
     if( yygotominor.yy346.pExpr ){
       yygotominor.yy346.pExpr->x.pSelect = yymsp[-1].minor.yy3;
-      ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect);
-      sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr);
+      ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect|EP_Subquery);
+      sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr);
     }else{
       sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3);
     }
@@ -120435,8 +126255,8 @@ static void yy_reduce(
     yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy346.pExpr, 0, 0);
     if( yygotominor.yy346.pExpr ){
       yygotominor.yy346.pExpr->x.pSelect = yymsp[-1].minor.yy3;
-      ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect);
-      sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr);
+      ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect|EP_Subquery);
+      sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr);
     }else{
       sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3);
     }
@@ -120451,8 +126271,8 @@ static void yy_reduce(
     yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy346.pExpr, 0, 0);
     if( yygotominor.yy346.pExpr ){
       yygotominor.yy346.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
-      ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect);
-      sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr);
+      ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect|EP_Subquery);
+      sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr);
     }else{
       sqlite3SrcListDelete(pParse->db, pSrc);
     }
@@ -120466,8 +126286,8 @@ static void yy_reduce(
     Expr *p = yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0);
     if( p ){
       p->x.pSelect = yymsp[-1].minor.yy3;
-      ExprSetProperty(p, EP_xIsSelect);
-      sqlite3ExprSetHeight(pParse, p);
+      ExprSetProperty(p, EP_xIsSelect|EP_Subquery);
+      sqlite3ExprSetHeightAndFlags(pParse, p);
     }else{
       sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3);
     }
@@ -120480,7 +126300,7 @@ static void yy_reduce(
   yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy132, 0, 0);
   if( yygotominor.yy346.pExpr ){
     yygotominor.yy346.pExpr->x.pList = yymsp[-1].minor.yy132 ? 
sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[-1].minor.yy132) : yymsp[-2].minor.yy14;
-    sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr);
+    sqlite3ExprSetHeightAndFlags(pParse, yygotominor.yy346.pExpr);
   }else{
     sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy14);
     sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy132);
@@ -120523,7 +126343,7 @@ static void yy_reduce(
         break;
       case 244: /* idxlist ::= idxlist COMMA nm collate sortorder */
 {
-  Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
+  Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0, 1);
   yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, p);
   sqlite3ExprListSetName(pParse,yygotominor.yy14,&yymsp[-2].minor.yy0,1);
   sqlite3ExprListCheckLength(pParse, yygotominor.yy14, "index");
@@ -120532,7 +126352,7 @@ static void yy_reduce(
         break;
       case 245: /* idxlist ::= nm collate sortorder */
 {
-  Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0);
+  Expr *p = sqlite3ExprAddCollateToken(pParse, 0, &yymsp[-1].minor.yy0, 1);
   yygotominor.yy14 = sqlite3ExprListAppend(pParse,0, p);
   sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1);
   sqlite3ExprListCheckLength(pParse, yygotominor.yy14, "index");
@@ -121409,7 +127229,7 @@ SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){
 ** end result.
 **
 ** Ticket #1066.  the SQL standard does not allow '$' in the
-** middle of identfiers.  But many SQL implementations do. 
+** middle of identifiers.  But many SQL implementations do. 
 ** SQLite will allow '$' in identifiers for compatibility.
 ** But the feature is undocumented.
 */
@@ -121434,6 +127254,7 @@ SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[] = {
 };
 #define IdChar(C)  (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40]))
 #endif
+SQLITE_PRIVATE int sqlite3IsIdChar(u8 c){ return IdChar(c); }
 
 
 /*
@@ -121721,7 +127542,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
   sqlite3 *db = pParse->db;       /* The database connection */
   int mxSqlLen;                   /* Max length of an SQL string */
 
-
+  assert( zSql!=0 );
   mxSqlLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
   if( db->nVdbeActive==0 ){
     db->u1.isInterrupted = 0;
@@ -121730,7 +127551,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
   pParse->zTail = zSql;
   i = 0;
   assert( pzErrMsg!=0 );
-  pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3Malloc);
+  pEngine = sqlite3ParserAlloc(sqlite3Malloc);
   if( pEngine==0 ){
     db->mallocFailed = 1;
     return SQLITE_NOMEM;
@@ -121761,10 +127582,8 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
         break;
       }
       case TK_ILLEGAL: {
-        sqlite3DbFree(db, *pzErrMsg);
-        *pzErrMsg = sqlite3MPrintf(db, "unrecognized token: \"%T\"",
+        sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"",
                         &pParse->sLastToken);
-        nErr++;
         goto abort_parse;
       }
       case TK_SEMI: {
@@ -121782,17 +127601,22 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr
     }
   }
 abort_parse:
-  if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){
+  assert( nErr==0 );
+  if( zSql[i]==0 && pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
     if( lastTokenParsed!=TK_SEMI ){
       sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
       pParse->zTail = &zSql[i];
     }
-    sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
+    if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
+      sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
+    }
   }
 #ifdef YYTRACKMAXSTACKDEPTH
+  sqlite3_mutex_enter(sqlite3MallocMutex());
   sqlite3StatusSet(SQLITE_STATUS_PARSER_STACK,
       sqlite3ParserStackPeak(pEngine)
   );
+  sqlite3_mutex_leave(sqlite3MallocMutex());
 #endif /* YYDEBUG */
   sqlite3ParserFree(pEngine, sqlite3_free);
   db->lookaside.bEnabled = enableLookaside;
@@ -121846,9 +127670,7 @@ abort_parse:
     pParse->pZombieTab = p->pNextZombie;
     sqlite3DeleteTable(db, p);
   }
-  if( nErr>0 && pParse->rc==SQLITE_OK ){
-    pParse->rc = SQLITE_ERROR;
-  }
+  assert( nErr==0 || pParse->rc!=SQLITE_OK );
   return nErr;
 }
 
@@ -121925,7 +127747,7 @@ SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[];
 **                 a statement.
 **
 **   (4) CREATE    The keyword CREATE has been seen at the beginning of a
-**                 statement, possibly preceeded by EXPLAIN and/or followed by
+**                 statement, possibly preceded by EXPLAIN and/or followed by
 **                 TEMP or TEMPORARY
 **
 **   (5) TRIGGER   We are in the middle of a trigger definition that must be
@@ -121935,7 +127757,7 @@ SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[];
 **                 the end of a trigger definition.
 **
 **   (7) END       We've seen the ";END" of the ";END;" that occurs at the end
-**                 of a trigger difinition.
+**                 of a trigger definition.
 **
 ** Transitions between states above are determined by tokens extracted
 ** from the input.  The following tokens are significant:
@@ -121956,7 +127778,7 @@ SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[];
 ** to recognize the end of a trigger can be omitted.  All we have to do
 ** is look for a semicolon that is not part of an string or comment.
 */
-SQLITE_API int sqlite3_complete(const char *zSql){
+SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *zSql){
   u8 state = 0;   /* Current state, using numbers defined in header comment */
   u8 token;       /* Value of the next token */
 
@@ -121978,7 +127800,7 @@ SQLITE_API int sqlite3_complete(const char *zSql){
   };
 #else
   /* If triggers are not supported by this compile then the statement machine
-  ** used to detect the end of a statement is much simplier
+  ** used to detect the end of a statement is much simpler
   */
   static const u8 trans[3][3] = {
                      /* Token:           */
@@ -121989,6 +127811,13 @@ SQLITE_API int sqlite3_complete(const char *zSql){
   };
 #endif /* SQLITE_OMIT_TRIGGER */
 
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( zSql==0 ){
+    (void)SQLITE_MISUSE_BKPT;
+    return 0;
+  }
+#endif
+
   while( *zSql ){
     switch( *zSql ){
       case ';': {  /* A semicolon */
@@ -122114,10 +127943,10 @@ SQLITE_API int sqlite3_complete(const char *zSql){
 ** above, except that the parameter is required to be UTF-16 encoded, not
 ** UTF-8.
 */
-SQLITE_API int sqlite3_complete16(const void *zSql){
+SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *zSql){
   sqlite3_value *pVal;
   char const *zSql8;
-  int rc = SQLITE_NOMEM;
+  int rc;
 
 #ifndef SQLITE_OMIT_AUTOINIT
   rc = sqlite3_initialize();
@@ -122264,24 +128093,36 @@ SQLITE_API const char sqlite3_version[] = SQLITE_VERSION;
 /* IMPLEMENTATION-OF: R-53536-42575 The sqlite3_libversion() function returns
 ** a pointer to the to the sqlite3_version[] string constant. 
 */
-SQLITE_API const char *sqlite3_libversion(void){ return sqlite3_version; }
+SQLITE_API const char *SQLITE_STDCALL sqlite3_libversion(void){ return sqlite3_version; }
 
 /* IMPLEMENTATION-OF: R-63124-39300 The sqlite3_sourceid() function returns a
 ** pointer to a string constant whose value is the same as the
 ** SQLITE_SOURCE_ID C preprocessor macro. 
 */
-SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
+SQLITE_API const char *SQLITE_STDCALL sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
 
 /* IMPLEMENTATION-OF: R-35210-63508 The sqlite3_libversion_number() function
 ** returns an integer equal to SQLITE_VERSION_NUMBER.
 */
-SQLITE_API int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
+SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
 
 /* 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.
 */
-SQLITE_API int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }
+SQLITE_API int SQLITE_STDCALL 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)
 /*
@@ -122290,7 +128131,7 @@ SQLITE_API int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }
 ** I/O active are written using this function.  These messages
 ** are intended for debugging activity only.
 */
-SQLITE_PRIVATE void (*sqlite3IoTrace)(const char*, ...) = 0;
+SQLITE_API void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...) = 0;
 #endif
 
 /*
@@ -122342,7 +128183,7 @@ SQLITE_API char *sqlite3_data_directory = 0;
 **    *  Recursive calls to this routine from thread X return immediately
 **       without blocking.
 */
-SQLITE_API int sqlite3_initialize(void){
+SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void){
   MUTEX_LOGIC( sqlite3_mutex *pMaster; )       /* The main static mutex */
   int rc;                                      /* Result code */
 #ifdef SQLITE_EXTRA_INIT
@@ -122356,6 +128197,11 @@ SQLITE_API 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
@@ -122498,7 +128344,14 @@ SQLITE_API int sqlite3_initialize(void){
 ** on when SQLite is already shut down.  If SQLite is already shut down
 ** when this routine is invoked, then this routine is a harmless no-op.
 */
-SQLITE_API int sqlite3_shutdown(void){
+SQLITE_API int SQLITE_STDCALL 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);
@@ -122545,7 +128398,7 @@ SQLITE_API int sqlite3_shutdown(void){
 ** threadsafe.  Failure to heed these warnings can lead to unpredictable
 ** behavior.
 */
-SQLITE_API int sqlite3_config(int op, ...){
+SQLITE_API int SQLITE_CDECL sqlite3_config(int op, ...){
   va_list ap;
   int rc = SQLITE_OK;
 
@@ -122557,33 +128410,43 @@ SQLITE_API 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;
@@ -122591,37 +128454,61 @@ SQLITE_API 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-31408-40510 There are three arguments to
+      ** SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned memory, the size
+      ** of each page buffer (sz), and the number of pages (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 */
@@ -122634,11 +128521,18 @@ SQLITE_API 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();
       }
@@ -122646,9 +128540,15 @@ SQLITE_API 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);
@@ -122661,17 +128561,19 @@ SQLITE_API 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
@@ -122704,12 +128606,25 @@ SQLITE_API 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: {
+      /* 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;
     }
@@ -122724,25 +128639,45 @@ SQLITE_API 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;
@@ -122820,7 +128755,13 @@ static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){
 /*
 ** Return the mutex associated with a database connection.
 */
-SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){
+SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3 *db){
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !sqlite3SafetyCheckOk(db) ){
+    (void)SQLITE_MISUSE_BKPT;
+    return 0;
+  }
+#endif
   return db->mutex;
 }
 
@@ -122828,8 +128769,12 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){
 ** Free up as much memory as we can from the given database
 ** connection.
 */
-SQLITE_API int sqlite3_db_release_memory(sqlite3 *db){
+SQLITE_API int SQLITE_STDCALL 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++){
@@ -122847,7 +128792,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3 *db){
 /*
 ** Configuration settings for an individual database connection
 */
-SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){
+SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3 *db, int op, ...){
   va_list ap;
   int rc;
   va_start(ap, op);
@@ -122919,13 +128864,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;
     }
@@ -122959,21 +128911,39 @@ static int nocaseCollatingFunc(
 /*
 ** Return the ROWID of the most recent insert
 */
-SQLITE_API sqlite_int64 sqlite3_last_insert_rowid(sqlite3 *db){
+SQLITE_API sqlite_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3 *db){
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !sqlite3SafetyCheckOk(db) ){
+    (void)SQLITE_MISUSE_BKPT;
+    return 0;
+  }
+#endif
   return db->lastRowid;
 }
 
 /*
 ** Return the number of changes in the most recent call to sqlite3_exec().
 */
-SQLITE_API int sqlite3_changes(sqlite3 *db){
+SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3 *db){
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !sqlite3SafetyCheckOk(db) ){
+    (void)SQLITE_MISUSE_BKPT;
+    return 0;
+  }
+#endif
   return db->nChange;
 }
 
 /*
 ** Return the number of changes since the database handle was opened.
 */
-SQLITE_API int sqlite3_total_changes(sqlite3 *db){
+SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3 *db){
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !sqlite3SafetyCheckOk(db) ){
+    (void)SQLITE_MISUSE_BKPT;
+    return 0;
+  }
+#endif
   return db->nTotalChange;
 }
 
@@ -123080,7 +129050,7 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){
   ** SQLITE_BUSY if the connection can not be closed immediately.
   */
   if( !forceZombie && connectionIsBusy(db) ){
-    sqlite3Error(db, SQLITE_BUSY, "unable to close due to unfinalized "
+    sqlite3ErrorWithMsg(db, SQLITE_BUSY, "unable to close due to unfinalized "
        "statements or unfinished backups");
     sqlite3_mutex_leave(db->mutex);
     return SQLITE_BUSY;
@@ -123109,8 +129079,8 @@ static int sqlite3Close(sqlite3 *db, int forceZombie){
 ** unclosed resources, and arranges for deallocation when the last
 ** prepare statement or sqlite3_backup closes.
 */
-SQLITE_API int sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); }
-SQLITE_API int sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); }
+SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); }
+SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); }
 
 
 /*
@@ -123210,9 +129180,13 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
   sqlite3HashClear(&db->aModule);
 #endif
 
-  sqlite3Error(db, SQLITE_OK, 0); /* Deallocates any cached error strings. */
+  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;
 
@@ -123235,13 +129209,15 @@ SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){
 
 /*
 ** Rollback all database files.  If tripCode is not SQLITE_OK, then
-** any open cursors are invalidated ("tripped" - as in "tripping a circuit
+** 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.
+** attempts to use that cursor.  Read cursors remain open and valid
+** but are "saved" in case the table pages are moved around.
 */
 SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
   int i;
   int inTrans = 0;
+  int schemaChange;
   assert( sqlite3_mutex_held(db->mutex) );
   sqlite3BeginBenignMalloc();
 
@@ -123252,6 +129228,7 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
   ** 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++){
     Btree *p = db->aDb[i].pBt;
@@ -123259,7 +129236,7 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){
       if( sqlite3BtreeIsInTrans(p) ){
         inTrans = 1;
       }
-      sqlite3BtreeRollback(p, tripCode);
+      sqlite3BtreeRollback(p, tripCode, !schemaChange);
     }
   }
   sqlite3VtabRollback(db);
@@ -123286,7 +129263,7 @@ SQLITE_PRIVATE 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)
 SQLITE_PRIVATE const char *sqlite3ErrName(int rc){
   const char *zName = 0;
   int i, origRc = rc;
@@ -123452,7 +129429,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[] =
@@ -123510,11 +129487,14 @@ SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p){
 ** This routine sets the busy callback for an Sqlite database to the
 ** given callback function with the given argument.
 */
-SQLITE_API int sqlite3_busy_handler(
+SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(
   sqlite3 *db,
   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;
@@ -123530,12 +129510,18 @@ SQLITE_API int sqlite3_busy_handler(
 ** given callback function with the given argument. The progress callback will
 ** be invoked every nOps opcodes.
 */
-SQLITE_API void sqlite3_progress_handler(
+SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(
   sqlite3 *db, 
   int nOps,
   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;
@@ -123555,7 +129541,10 @@ SQLITE_API void sqlite3_progress_handler(
 ** This routine installs a default busy handler that waits for the
 ** specified number of milliseconds before returning 0.
 */
-SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){
+SQLITE_API int SQLITE_STDCALL 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;
@@ -123568,7 +129557,13 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){
 /*
 ** Cause any pending operation to stop at its earliest opportunity.
 */
-SQLITE_API void sqlite3_interrupt(sqlite3 *db){
+SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3 *db){
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !sqlite3SafetyCheckOk(db) ){
+    (void)SQLITE_MISUSE_BKPT;
+    return;
+  }
+#endif
   db->u1.isInterrupted = 1;
 }
 
@@ -123643,7 +129638,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
   p = sqlite3FindFunction(db, zFunctionName, nName, nArg, (u8)enc, 0);
   if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==enc && p->nArg==nArg ){
     if( db->nVdbeActive ){
-      sqlite3Error(db, SQLITE_BUSY, 
+      sqlite3ErrorWithMsg(db, SQLITE_BUSY, 
         "unable to delete/modify user-function due to active statements");
       assert( !db->mallocFailed );
       return SQLITE_BUSY;
@@ -123679,7 +129674,7 @@ SQLITE_PRIVATE int sqlite3CreateFunc(
 /*
 ** Create new user functions.
 */
-SQLITE_API int sqlite3_create_function(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_function(
   sqlite3 *db,
   const char *zFunc,
   int nArg,
@@ -123693,7 +129688,7 @@ SQLITE_API int sqlite3_create_function(
                                     xFinal, 0);
 }
 
-SQLITE_API int sqlite3_create_function_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2(
   sqlite3 *db,
   const char *zFunc,
   int nArg,
@@ -123706,6 +129701,12 @@ SQLITE_API 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));
@@ -123730,7 +129731,7 @@ SQLITE_API int sqlite3_create_function_v2(
 }
 
 #ifndef SQLITE_OMIT_UTF16
-SQLITE_API int sqlite3_create_function16(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_function16(
   sqlite3 *db,
   const void *zFunctionName,
   int nArg,
@@ -123742,6 +129743,10 @@ SQLITE_API 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);
@@ -123766,13 +129771,19 @@ SQLITE_API int sqlite3_create_function16(
 ** A global function must exist in order for name resolution to work
 ** properly.
 */
-SQLITE_API int sqlite3_overload_function(
+SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(
   sqlite3 *db,
   const char *zName,
   int nArg
 ){
   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,
@@ -123792,8 +129803,15 @@ SQLITE_API int sqlite3_overload_function(
 ** trace is a pointer to a function that is invoked at the start of each
 ** SQL statement.
 */
-SQLITE_API void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), void *pArg){
+SQLITE_API void *SQLITE_STDCALL 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;
@@ -123809,12 +129827,19 @@ SQLITE_API void *sqlite3_trace(sqlite3 *db, void (*xTrace)(void*,const char*), v
 ** profile is a pointer to a function that is invoked at the conclusion of
 ** each SQL statement that is run.
 */
-SQLITE_API void *sqlite3_profile(
+SQLITE_API void *SQLITE_STDCALL sqlite3_profile(
   sqlite3 *db,
   void (*xProfile)(void*,const char*,sqlite_uint64),
   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;
@@ -123829,12 +129854,19 @@ SQLITE_API void *sqlite3_profile(
 ** If the invoked function returns non-zero, then the commit becomes a
 ** rollback.
 */
-SQLITE_API void *sqlite3_commit_hook(
+SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(
   sqlite3 *db,              /* Attach the hook to this database */
   int (*xCallback)(void*),  /* Function to invoke on each commit */
   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;
@@ -123847,12 +129879,19 @@ SQLITE_API void *sqlite3_commit_hook(
 ** Register a callback to be invoked each time a row is updated,
 ** inserted or deleted using this database connection.
 */
-SQLITE_API void *sqlite3_update_hook(
+SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
   sqlite3 *db,              /* Attach the hook to this database */
   void (*xCallback)(void*,int,char const *,char const *,sqlite_int64),
   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;
@@ -123865,12 +129904,19 @@ SQLITE_API void *sqlite3_update_hook(
 ** Register a callback to be invoked each time a transaction is rolled
 ** back by this database connection.
 */
-SQLITE_API void *sqlite3_rollback_hook(
+SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(
   sqlite3 *db,              /* Attach the hook to this database */
   void (*xCallback)(void*), /* Callback function */
   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;
@@ -123912,11 +129958,14 @@ SQLITE_PRIVATE int sqlite3WalDefaultHook(
 ** using sqlite3_wal_hook() disables the automatic checkpoint mechanism
 ** configured by this function.
 */
-SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
+SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
 #ifdef SQLITE_OMIT_WAL
   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{
@@ -123930,13 +129979,19 @@ SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){
 ** Register a callback to be invoked each time a transaction is written
 ** into the write-ahead-log by this database connection.
 */
-SQLITE_API void *sqlite3_wal_hook(
+SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook(
   sqlite3 *db,                    /* Attach the hook to this db handle */
   int(*xCallback)(void *, sqlite3*, const char*, int),
   void *pArg                      /* First argument passed to xCallback() */
 ){
 #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;
@@ -123951,7 +130006,7 @@ SQLITE_API void *sqlite3_wal_hook(
 /*
 ** Checkpoint database zDb.
 */
-SQLITE_API int sqlite3_wal_checkpoint_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2(
   sqlite3 *db,                    /* Database handle */
   const char *zDb,                /* Name of attached database (or NULL) */
   int eMode,                      /* SQLITE_CHECKPOINT_* value */
@@ -123964,14 +130019,21 @@ SQLITE_API 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;
   }
 
@@ -123981,10 +130043,11 @@ SQLITE_API 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{
+    db->busyHandler.nBusy = 0;
     rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt);
-    sqlite3Error(db, rc, 0);
+    sqlite3Error(db, rc);
   }
   rc = sqlite3ApiExit(db, rc);
   sqlite3_mutex_leave(db->mutex);
@@ -123998,8 +130061,10 @@ SQLITE_API int sqlite3_wal_checkpoint_v2(
 ** to contains a zero-length string, all attached databases are 
 ** checkpointed.
 */
-SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
-  return sqlite3_wal_checkpoint_v2(db, zDb, SQLITE_CHECKPOINT_PASSIVE, 0, 0);
+SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){
+  /* 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
@@ -124085,7 +130150,7 @@ SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3 *db){
 ** Return UTF-8 encoded English language explanation of the most recent
 ** error.
 */
-SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){
+SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3 *db){
   const char *z;
   if( !db ){
     return sqlite3ErrStr(SQLITE_NOMEM);
@@ -124113,7 +130178,7 @@ SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){
 ** Return UTF-16 encoded English language explanation of the most recent
 ** error.
 */
-SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){
+SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3 *db){
   static const u16 outOfMem[] = {
     'o', 'u', 't', ' ', 'o', 'f', ' ', 'm', 'e', 'm', 'o', 'r', 'y', 0
   };
@@ -124139,7 +130204,7 @@ SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){
   }else{
     z = sqlite3_value_text16(db->pErr);
     if( z==0 ){
-      sqlite3Error(db, db->errCode, sqlite3ErrStr(db->errCode));
+      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()
@@ -124158,7 +130223,7 @@ SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){
 ** Return the most recent error code generated by an SQLite routine. If NULL is
 ** passed to this function, we assume a malloc() failed during sqlite3_open().
 */
-SQLITE_API int sqlite3_errcode(sqlite3 *db){
+SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db){
   if( db && !sqlite3SafetyCheckSickOrOk(db) ){
     return SQLITE_MISUSE_BKPT;
   }
@@ -124167,7 +130232,7 @@ SQLITE_API int sqlite3_errcode(sqlite3 *db){
   }
   return db->errCode & db->errMask;
 }
-SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){
+SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db){
   if( db && !sqlite3SafetyCheckSickOrOk(db) ){
     return SQLITE_MISUSE_BKPT;
   }
@@ -124182,37 +130247,11 @@ SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){
 ** argument.  For now, this simply calls the internal sqlite3ErrStr()
 ** function.
 */
-SQLITE_API const char *sqlite3_errstr(int rc){
+SQLITE_API const char *SQLITE_STDCALL 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.
 */
@@ -124226,7 +130265,6 @@ static int createCollation(
 ){
   CollSeq *pColl;
   int enc2;
-  int nName = sqlite3Strlen30(zName);
   
   assert( sqlite3_mutex_held(db->mutex) );
 
@@ -124251,12 +130289,11 @@ static int createCollation(
   pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0);
   if( pColl && pColl->xCmp ){
     if( db->nVdbeActive ){
-      sqlite3Error(db, SQLITE_BUSY, 
+      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(),
@@ -124265,7 +130302,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];
@@ -124285,7 +130322,7 @@ static int createCollation(
   pColl->pUser = pCtx;
   pColl->xDel = xDel;
   pColl->enc = (u8)(enc2 | (enc & SQLITE_UTF16_ALIGNED));
-  sqlite3Error(db, SQLITE_OK, 0);
+  sqlite3Error(db, SQLITE_OK);
   return SQLITE_OK;
 }
 
@@ -124307,6 +130344,7 @@ static const int aHardLimit[] = {
   SQLITE_MAX_LIKE_PATTERN_LENGTH,
   SQLITE_MAX_VARIABLE_NUMBER,      /* IMP: R-38091-32352 */
   SQLITE_MAX_TRIGGER_DEPTH,
+  SQLITE_MAX_WORKER_THREADS,
 };
 
 /*
@@ -124342,6 +130380,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
 
 
 /*
@@ -124354,9 +130395,15 @@ static const int aHardLimit[] = {
 ** It merely prevents new constructs that exceed the limit
 ** from forming.
 */
-SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
+SQLITE_API int SQLITE_STDCALL 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
@@ -124375,7 +130422,8 @@ SQLITE_API 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 ){
@@ -124432,25 +130480,38 @@ SQLITE_PRIVATE int sqlite3ParseUri(
 
   assert( *pzErrMsg==0 );
 
-  if( ((flags & SQLITE_OPEN_URI) || sqlite3GlobalConfig.bOpenUri) 
-   && nUri>=5 && memcmp(zUri, "file:", 5)==0 
+  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;
@@ -124600,7 +130661,7 @@ SQLITE_PRIVATE 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';
@@ -124641,6 +130702,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();
@@ -124663,7 +130727,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_BKPT;
+  if( ((1<<(flags&7)) & 0x46)==0 ){
+    return SQLITE_MISUSE_BKPT;  /* IMP: R-65497-44594 */
+  }
 
   if( sqlite3GlobalConfig.bCoreMutex==0 ){
     isThreadsafe = 0;
@@ -124722,14 +130788,19 @@ 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->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_CKPTFULLFSYNC
+                 | SQLITE_CkptFullFSync
+#endif
 #if SQLITE_DEFAULT_FILE_FORMAT<4
                  | SQLITE_LegacyFileFmt
 #endif
@@ -124742,6 +130813,9 @@ 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
       ;
   sqlite3HashInit(&db->aCollSeq);
 #ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -124751,26 +130825,30 @@ 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, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0);
   createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0);
   if( db->mallocFailed ){
     goto opendb_out;
   }
+  /* EVIDENCE-OF: R-08308-17224 The default collating function for all
+  ** strings is BINARY. 
+  */
   db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "BINARY", 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);
   if( rc!=SQLITE_OK ){
     if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
-    sqlite3Error(db, rc, zErrMsg ? "%s" : 0, zErrMsg);
+    sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg);
     sqlite3_free(zErrMsg);
     goto opendb_out;
   }
@@ -124782,13 +130860,15 @@ static int openDatabase(
     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);
+  if( !db->mallocFailed ) ENC(db) = SCHEMA_ENC(db);
+  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.  
   */
@@ -124806,7 +130886,7 @@ 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
@@ -124853,6 +130933,13 @@ static int openDatabase(
   }
 #endif
 
+#ifdef SQLITE_ENABLE_DBSTAT_VTAB
+  if( !db->mallocFailed && rc==SQLITE_OK){
+    int sqlite3_dbstat_register(sqlite3*);
+    rc = sqlite3_dbstat_register(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.
@@ -124863,7 +130950,7 @@ static int openDatabase(
                           SQLITE_DEFAULT_LOCKING_MODE);
 #endif
 
-  if( rc ) sqlite3Error(db, rc, 0);
+  if( rc ) sqlite3Error(db, rc);
 
   /* Enable the lookaside-malloc subsystem */
   setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside,
@@ -124874,7 +130961,8 @@ static int openDatabase(
 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);
@@ -124899,14 +130987,14 @@ opendb_out:
 /*
 ** Open a new database handle.
 */
-SQLITE_API int sqlite3_open(
+SQLITE_API int SQLITE_STDCALL sqlite3_open(
   const char *zFilename, 
   sqlite3 **ppDb 
 ){
   return openDatabase(zFilename, ppDb,
                       SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
 }
-SQLITE_API int sqlite3_open_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_open_v2(
   const char *filename,   /* Database filename (UTF-8) */
   sqlite3 **ppDb,         /* OUT: SQLite db handle */
   int flags,              /* Flags */
@@ -124919,7 +131007,7 @@ SQLITE_API int sqlite3_open_v2(
 /*
 ** Open a new database handle.
 */
-SQLITE_API int sqlite3_open16(
+SQLITE_API int SQLITE_STDCALL sqlite3_open16(
   const void *zFilename, 
   sqlite3 **ppDb
 ){
@@ -124927,13 +131015,15 @@ SQLITE_API 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);
@@ -124942,7 +131032,7 @@ SQLITE_API 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;
@@ -124956,26 +131046,20 @@ SQLITE_API int sqlite3_open16(
 /*
 ** Register a new collation sequence with the database handle db.
 */
-SQLITE_API int sqlite3_create_collation(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_collation(
   sqlite3* db, 
   const char *zName, 
   int enc, 
   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);
 }
 
 /*
 ** Register a new collation sequence with the database handle db.
 */
-SQLITE_API int sqlite3_create_collation_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2(
   sqlite3* db, 
   const char *zName, 
   int enc, 
@@ -124984,6 +131068,10 @@ SQLITE_API 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);
@@ -124996,7 +131084,7 @@ SQLITE_API int sqlite3_create_collation_v2(
 /*
 ** Register a new collation sequence with the database handle db.
 */
-SQLITE_API int sqlite3_create_collation16(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16(
   sqlite3* db, 
   const void *zName,
   int enc, 
@@ -125005,6 +131093,10 @@ SQLITE_API 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);
@@ -125022,11 +131114,14 @@ SQLITE_API int sqlite3_create_collation16(
 ** Register a collation sequence factory callback with the database handle
 ** db. Replace any previously installed collation sequence factory.
 */
-SQLITE_API int sqlite3_collation_needed(
+SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed(
   sqlite3 *db, 
   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;
@@ -125040,11 +131135,14 @@ SQLITE_API int sqlite3_collation_needed(
 ** Register a collation sequence factory callback with the database handle
 ** db. Replace any previously installed collation sequence factory.
 */
-SQLITE_API int sqlite3_collation_needed16(
+SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16(
   sqlite3 *db, 
   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;
@@ -125059,7 +131157,7 @@ SQLITE_API int sqlite3_collation_needed16(
 ** This function is now an anachronism. It used to be used to recover from a
 ** malloc() failure, but SQLite now does this automatically.
 */
-SQLITE_API int sqlite3_global_recover(void){
+SQLITE_API int SQLITE_STDCALL sqlite3_global_recover(void){
   return SQLITE_OK;
 }
 #endif
@@ -125070,14 +131168,20 @@ SQLITE_API int sqlite3_global_recover(void){
 ** by default.  Autocommit is disabled by a BEGIN statement and reenabled
 ** by the next COMMIT or ROLLBACK.
 */
-SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){
+SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3 *db){
+#ifdef SQLITE_ENABLE_API_ARMOR
+  if( !sqlite3SafetyCheckOk(db) ){
+    (void)SQLITE_MISUSE_BKPT;
+    return 0;
+  }
+#endif
   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.
@@ -125116,7 +131220,7 @@ SQLITE_PRIVATE int sqlite3CantopenError(int lineno){
 ** SQLite no longer uses thread-specific data so this routine is now a
 ** no-op.  It is retained for historical compatibility.
 */
-SQLITE_API void sqlite3_thread_cleanup(void){
+SQLITE_API void SQLITE_STDCALL sqlite3_thread_cleanup(void){
 }
 #endif
 
@@ -125124,8 +131228,7 @@ SQLITE_API 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
-SQLITE_API int sqlite3_table_column_metadata(
+SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
   sqlite3 *db,                /* Connection handle */
   const char *zDbName,        /* Database name or NULL */
   const char *zTableName,     /* Table name */
@@ -125140,14 +131243,20 @@ SQLITE_API 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);
@@ -125164,11 +131273,8 @@ SQLITE_API 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];
@@ -125177,8 +131283,13 @@ SQLITE_API 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;
+      }
     }
   }
 
@@ -125225,18 +131336,17 @@ 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);
   return rc;
 }
-#endif
 
 /*
 ** Sleep for a little while.  Return the amount of time slept.
 */
-SQLITE_API int sqlite3_sleep(int ms){
+SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int ms){
   sqlite3_vfs *pVfs;
   int rc;
   pVfs = sqlite3_vfs_find(0);
@@ -125252,7 +131362,10 @@ SQLITE_API int sqlite3_sleep(int ms){
 /*
 ** Enable or disable the extended result codes.
 */
-SQLITE_API int sqlite3_extended_result_codes(sqlite3 *db, int onoff){
+SQLITE_API int SQLITE_STDCALL 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);
@@ -125262,10 +131375,13 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3 *db, int onoff){
 /*
 ** Invoke the xFileControl method on a particular database.
 */
-SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){
+SQLITE_API int SQLITE_STDCALL 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 ){
@@ -125287,13 +131403,13 @@ SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, vo
     sqlite3BtreeLeave(pBtree);
   }
   sqlite3_mutex_leave(db->mutex);
-  return rc;   
+  return rc;
 }
 
 /*
 ** Interface to the testing logic.
 */
-SQLITE_API int sqlite3_test_control(int op, ...){
+SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...){
   int rc = 0;
 #ifndef SQLITE_OMIT_BUILTIN_TEST
   va_list ap;
@@ -125391,7 +131507,7 @@ SQLITE_API 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;
@@ -125546,22 +131662,6 @@ SQLITE_API int sqlite3_test_control(int op, ...){
       break;
     }
 
-#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
-    /*   sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT,
-    **                        sqlite3_stmt*,const char**);
-    **
-    ** If compiled with SQLITE_ENABLE_TREE_EXPLAIN, each sqlite3_stmt holds
-    ** a string that describes the optimized parse tree.  This test-control
-    ** returns a pointer to that string.
-    */
-    case SQLITE_TESTCTRL_EXPLAIN_STMT: {
-      sqlite3_stmt *pStmt = va_arg(ap, sqlite3_stmt*);
-      const char **pzRet = va_arg(ap, const char**);
-      *pzRet = sqlite3VdbeExplanation((Vdbe*)pStmt);
-      break;
-    }
-#endif
-
     /*   sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int);
     **
     ** Set or clear a flag that indicates that the database file is always well-
@@ -125590,6 +131690,13 @@ SQLITE_API int sqlite3_test_control(int op, ...){
       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
@@ -125600,6 +131707,34 @@ SQLITE_API int sqlite3_test_control(int op, ...){
       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 */
@@ -125617,8 +131752,8 @@ SQLITE_API int sqlite3_test_control(int op, ...){
 ** parameter if it exists.  If the parameter does not exist, this routine
 ** returns a NULL pointer.
 */
-SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){
-  if( zFilename==0 ) return 0;
+SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam){
+  if( zFilename==0 || zParam==0 ) return 0;
   zFilename += sqlite3Strlen30(zFilename) + 1;
   while( zFilename[0] ){
     int x = strcmp(zFilename, zParam);
@@ -125632,7 +131767,7 @@ SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *
 /*
 ** Return a boolean value for a query parameter.
 */
-SQLITE_API int sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){
+SQLITE_API int SQLITE_STDCALL 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;
@@ -125641,7 +131776,7 @@ SQLITE_API int sqlite3_uri_boolean(const char *zFilename, const char *zParam, in
 /*
 ** Return a 64-bit integer value for a query parameter.
 */
-SQLITE_API sqlite3_int64 sqlite3_uri_int64(
+SQLITE_API sqlite3_int64 SQLITE_STDCALL 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 */
@@ -125673,8 +131808,15 @@ SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){
 ** Return the filename of the database associated with a database
 ** connection.
 */
-SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){
-  Btree *pBt = sqlite3DbNameToBtree(db, zDbName);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *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;
 }
 
@@ -125682,8 +131824,15 @@ SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){
 ** Return 1 if database is read-only or 0 if read/write.  Return -1 if
 ** no such database exists.
 */
-SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){
-  Btree *pBt = sqlite3DbNameToBtree(db, zDbName);
+SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *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;
 }
 
@@ -125834,7 +131983,7 @@ static void leaveMutex(void){
 ** on the same "db".  If xNotify==0 then any prior callbacks are immediately
 ** cancelled.
 */
-SQLITE_API int sqlite3_unlock_notify(
+SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify(
   sqlite3 *db,
   void (*xNotify)(void **, int),
   void *pArg
@@ -125873,7 +132022,7 @@ SQLITE_API int sqlite3_unlock_notify(
 
   leaveMutex();
   assert( !db->mallocFailed );
-  sqlite3Error(db, rc, (rc?"database is deadlocked":0));
+  sqlite3ErrorWithMsg(db, rc, (rc?"database is deadlocked":0));
   sqlite3_mutex_leave(db->mutex);
   return rc;
 }
@@ -126728,6 +132877,11 @@ SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const voi
 #ifdef SQLITE_COVERAGE_TEST
 # define ALWAYS(x) (1)
 # define NEVER(X)  (0)
+#elif defined(SQLITE_DEBUG)
+# define ALWAYS(x) sqlite3Fts3Always((x)!=0)
+# define NEVER(x) sqlite3Fts3Never((x)!=0)
+SQLITE_PRIVATE int sqlite3Fts3Always(int b);
+SQLITE_PRIVATE int sqlite3Fts3Never(int b);
 #else
 # define ALWAYS(x) (x)
 # define NEVER(x)  (x)
@@ -126969,6 +133123,11 @@ struct Fts3Phrase {
   int bIncr;                 /* True if doclist is loaded incrementally */
   int iDoclistToken;
 
+  /* Used by sqlite3Fts3EvalPhrasePoslist() if this is a descendent of an
+  ** OR condition.  */
+  char *pOrPoslist;
+  i64 iOrDocid;
+
   /* Variables below this point are populated by fts3_expr.c when parsing 
   ** a MATCH expression. Everything above is part of the evaluation phase. 
   */
@@ -127123,6 +133282,7 @@ SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table*,int,int);
 )
 
 /* fts3.c */
+SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char**,const char*,...);
 SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *, sqlite3_int64);
 SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *, sqlite_int64 *);
 SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *, int *);
@@ -127212,6 +133372,13 @@ static int fts3EvalStart(Fts3Cursor *pCsr);
 static int fts3TermSegReaderCursor(
     Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **);
 
+#ifndef SQLITE_AMALGAMATION
+# if defined(SQLITE_DEBUG)
+SQLITE_PRIVATE int sqlite3Fts3Always(int b) { assert( b ); return b; }
+SQLITE_PRIVATE int sqlite3Fts3Never(int b)  { assert( !b ); return b; }
+# endif
+#endif
+
 /* 
 ** Write a 64-bit variable-length integer to memory starting at p[0].
 ** The length of data written will be between 1 and FTS3_VARINT_MAX bytes.
@@ -127321,7 +133488,7 @@ SQLITE_PRIVATE void sqlite3Fts3Dequote(char *z){
     /* If the first byte was a '[', then the close-quote character is a ']' */
     if( quote=='[' ) quote = ']';  
 
-    while( ALWAYS(z[iIn]) ){
+    while( z[iIn] ){
       if( z[iIn]==quote ){
         if( z[iIn+1]!=quote ) break;
         z[iOut++] = quote;
@@ -127401,6 +133568,17 @@ static int fts3DisconnectMethod(sqlite3_vtab *pVtab){
 }
 
 /*
+** Write an error message into *pzErr
+*/
+SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char **pzErr, const char *zFormat, ...){
+  va_list ap;
+  sqlite3_free(*pzErr);
+  va_start(ap, zFormat);
+  *pzErr = sqlite3_vmprintf(zFormat, ap);
+  va_end(ap);
+}
+
+/*
 ** Construct one or more SQL statements from the format string given
 ** and then evaluate those statements. The success code is written
 ** into *pRc.
@@ -127809,11 +133987,16 @@ static char *fts3WriteExprList(Fts3Table *p, const char *zFunc, int *pRc){
 ** This function is used when parsing the "prefix=" FTS4 parameter.
 */
 static int fts3GobbleInt(const char **pp, int *pnOut){
+  const int MAX_NPREFIX = 10000000;
   const char *p;                  /* Iterator pointer */
   int nInt = 0;                   /* Output value */
 
   for(p=*pp; p[0]>='0' && p[0]<='9'; p++){
     nInt = nInt * 10 + (p[0] - '0');
+    if( nInt>MAX_NPREFIX ){
+      nInt = 0;
+      break;
+    }
   }
   if( p==*pp ) return SQLITE_ERROR;
   *pnOut = nInt;
@@ -127856,7 +134039,6 @@ static int fts3PrefixParameter(
 
   aIndex = sqlite3_malloc(sizeof(struct Fts3Index) * nIndex);
   *apIndex = aIndex;
-  *pnIndex = nIndex;
   if( !aIndex ){
     return SQLITE_NOMEM;
   }
@@ -127866,13 +134048,20 @@ static int fts3PrefixParameter(
     const char *p = zParam;
     int i;
     for(i=1; i<nIndex; i++){
-      int nPrefix;
+      int nPrefix = 0;
       if( fts3GobbleInt(&p, &nPrefix) ) return SQLITE_ERROR;
-      aIndex[i].nPrefix = nPrefix;
+      assert( nPrefix>=0 );
+      if( nPrefix==0 ){
+        nIndex--;
+        i--;
+      }else{
+        aIndex[i].nPrefix = nPrefix;
+      }
       p++;
     }
   }
 
+  *pnIndex = nIndex;
   return SQLITE_OK;
 }
 
@@ -127907,7 +134096,8 @@ static int fts3ContentColumns(
   const char *zTbl,               /* Name of content table */
   const char ***pazCol,           /* OUT: Malloc'd array of column names */
   int *pnCol,                     /* OUT: Size of array *pazCol */
-  int *pnStr                      /* OUT: Bytes of string content */
+  int *pnStr,                     /* OUT: Bytes of string content */
+  char **pzErr                    /* OUT: error message */
 ){
   int rc = SQLITE_OK;             /* Return code */
   char *zSql;                     /* "SELECT *" statement on zTbl */  
@@ -127918,6 +134108,9 @@ static int fts3ContentColumns(
     rc = SQLITE_NOMEM;
   }else{
     rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
+    if( rc!=SQLITE_OK ){
+      sqlite3Fts3ErrMsg(pzErr, "%s", sqlite3_errmsg(db));
+    }
   }
   sqlite3_free(zSql);
 
@@ -127996,7 +134189,7 @@ static int fts3InitVtab(
   const char **aCol;              /* Array of column names */
   sqlite3_tokenizer *pTokenizer = 0;        /* Tokenizer for this table */
 
-  int nIndex;                     /* Size of aIndex[] array */
+  int nIndex = 0;                 /* Size of aIndex[] array */
   struct Fts3Index *aIndex = 0;   /* Array of indexes for this table */
 
   /* The results of parsing supported FTS4 key=value options: */
@@ -128084,13 +134277,13 @@ static int fts3InitVtab(
           }
         }
         if( iOpt==SizeofArray(aFts4Opt) ){
-          *pzErr = sqlite3_mprintf("unrecognized parameter: %s", z);
+          sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z);
           rc = SQLITE_ERROR;
         }else{
           switch( iOpt ){
             case 0:               /* MATCHINFO */
               if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){
-                *pzErr = sqlite3_mprintf("unrecognized matchinfo: %s", zVal);
+                sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal);
                 rc = SQLITE_ERROR;
               }
               bNoDocsize = 1;
@@ -128118,7 +134311,7 @@ static int fts3InitVtab(
               if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3)) 
                && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4)) 
               ){
-                *pzErr = sqlite3_mprintf("unrecognized order: %s", zVal);
+                sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal);
                 rc = SQLITE_ERROR;
               }
               bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
@@ -128169,7 +134362,7 @@ static int fts3InitVtab(
     if( nCol==0 ){
       sqlite3_free((void*)aCol); 
       aCol = 0;
-      rc = fts3ContentColumns(db, argv[1], zContent, &aCol, &nCol, &nString);
+      rc = fts3ContentColumns(db, argv[1], zContent,&aCol,&nCol,&nString,pzErr);
 
       /* If a languageid= option was specified, remove the language id
       ** column from the aCol[] array. */ 
@@ -128204,7 +134397,7 @@ static int fts3InitVtab(
   rc = fts3PrefixParameter(zPrefix, &nIndex, &aIndex);
   if( rc==SQLITE_ERROR ){
     assert( zPrefix );
-    *pzErr = sqlite3_mprintf("error parsing prefix parameter: %s", zPrefix);
+    sqlite3Fts3ErrMsg(pzErr, "error parsing prefix parameter: %s", zPrefix);
   }
   if( rc!=SQLITE_OK ) goto fts3_init_out;
 
@@ -128286,7 +134479,7 @@ static int fts3InitVtab(
   }
   for(i=0; i<nNotindexed; i++){
     if( azNotindexed[i] ){
-      *pzErr = sqlite3_mprintf("no such column: %s", azNotindexed[i]);
+      sqlite3Fts3ErrMsg(pzErr, "no such column: %s", azNotindexed[i]);
       rc = SQLITE_ERROR;
     }
   }
@@ -128294,7 +134487,7 @@ static int fts3InitVtab(
   if( rc==SQLITE_OK && (zCompress==0)!=(zUncompress==0) ){
     char const *zMiss = (zCompress==0 ? "compress" : "uncompress");
     rc = SQLITE_ERROR;
-    *pzErr = sqlite3_mprintf("missing %s parameter in fts4 constructor", zMiss);
+    sqlite3Fts3ErrMsg(pzErr, "missing %s parameter in fts4 constructor", zMiss);
   }
   p->zReadExprlist = fts3ReadExprList(p, zUncompress, &rc);
   p->zWriteExprlist = fts3WriteExprList(p, zCompress, &rc);
@@ -128752,7 +134945,7 @@ static int fts3SelectLeaf(
   sqlite3_int64 *piLeaf,          /* Selected leaf node */
   sqlite3_int64 *piLeaf2          /* Selected leaf node */
 ){
-  int rc;                         /* Return code */
+  int rc = SQLITE_OK;             /* Return code */
   int iHeight;                    /* Height of this node in tree */
 
   assert( piLeaf || piLeaf2 );
@@ -128763,7 +134956,7 @@ static int fts3SelectLeaf(
 
   if( rc==SQLITE_OK && iHeight>1 ){
     char *zBlob = 0;              /* Blob read from %_segments table */
-    int nBlob;                    /* Size of zBlob in bytes */
+    int nBlob = 0;                /* Size of zBlob in bytes */
 
     if( piLeaf && piLeaf2 && (*piLeaf!=*piLeaf2) ){
       rc = sqlite3Fts3ReadBlock(p, *piLeaf, &zBlob, &nBlob, 0);
@@ -129390,26 +135583,33 @@ static int fts3DoclistOrMerge(
 **
 ** The right-hand input doclist is overwritten by this function.
 */
-static void fts3DoclistPhraseMerge(
+static int fts3DoclistPhraseMerge(
   int bDescDoclist,               /* True if arguments are desc */
   int nDist,                      /* Distance from left to right (1=adjacent) */
   char *aLeft, int nLeft,         /* Left doclist */
-  char *aRight, int *pnRight      /* IN/OUT: Right/output doclist */
+  char **paRight, int *pnRight    /* IN/OUT: Right/output doclist */
 ){
   sqlite3_int64 i1 = 0;
   sqlite3_int64 i2 = 0;
   sqlite3_int64 iPrev = 0;
+  char *aRight = *paRight;
   char *pEnd1 = &aLeft[nLeft];
   char *pEnd2 = &aRight[*pnRight];
   char *p1 = aLeft;
   char *p2 = aRight;
   char *p;
   int bFirstOut = 0;
-  char *aOut = aRight;
+  char *aOut;
 
   assert( nDist>0 );
-
+  if( bDescDoclist ){
+    aOut = sqlite3_malloc(*pnRight + FTS3_VARINT_MAX);
+    if( aOut==0 ) return SQLITE_NOMEM;
+  }else{
+    aOut = aRight;
+  }
   p = aOut;
+
   fts3GetDeltaVarint3(&p1, pEnd1, 0, &i1);
   fts3GetDeltaVarint3(&p2, pEnd2, 0, &i2);
 
@@ -129438,6 +135638,12 @@ static void fts3DoclistPhraseMerge(
   }
 
   *pnRight = (int)(p - aOut);
+  if( bDescDoclist ){
+    sqlite3_free(aRight);
+    *paRight = aOut;
+  }
+
+  return SQLITE_OK;
 }
 
 /*
@@ -129562,8 +135768,22 @@ static int fts3TermSelectMerge(
 ){
   if( pTS->aaOutput[0]==0 ){
     /* If this is the first term selected, copy the doclist to the output
-    ** buffer using memcpy(). */
-    pTS->aaOutput[0] = sqlite3_malloc(nDoclist);
+    ** buffer using memcpy(). 
+    **
+    ** Add FTS3_VARINT_MAX bytes of unused space to the end of the 
+    ** allocation. This is so as to ensure that the buffer is big enough
+    ** to hold the current doclist AND'd with any other doclist. If the
+    ** doclists are stored in order=ASC order, this padding would not be
+    ** required (since the size of [doclistA AND doclistB] is always less
+    ** than or equal to the size of [doclistA] in that case). But this is
+    ** not true for order=DESC. For example, a doclist containing (1, -1) 
+    ** may be smaller than (-1), as in the first example the -1 may be stored
+    ** as a single-byte delta, whereas in the second it must be stored as a
+    ** FTS3_VARINT_MAX byte varint.
+    **
+    ** Similar padding is added in the fts3DoclistOrMerge() function.
+    */
+    pTS->aaOutput[0] = sqlite3_malloc(nDoclist + FTS3_VARINT_MAX + 1);
     pTS->anOutput[0] = nDoclist;
     if( pTS->aaOutput[0] ){
       memcpy(pTS->aaOutput[0], aDoclist, nDoclist);
@@ -129660,7 +135880,7 @@ static int fts3SegReaderCursor(
   ** calls out here.  */
   if( iLevel<0 && p->aIndex ){
     Fts3SegReader *pSeg = 0;
-    rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix, &pSeg);
+    rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix||isScan, &pSeg);
     if( rc==SQLITE_OK && pSeg ){
       rc = fts3SegReaderCursorAppend(pCsr, pSeg);
     }
@@ -129985,7 +136205,7 @@ static int fts3FilterMethod(
   int nVal,                       /* Number of elements in apVal */
   sqlite3_value **apVal           /* Arguments for the indexing scheme */
 ){
-  int rc;
+  int rc = SQLITE_OK;
   char *zSql;                     /* SQL statement used to access %_content */
   int eSearch;
   Fts3Table *p = (Fts3Table *)pCursor->pVtab;
@@ -130015,6 +136235,7 @@ static int fts3FilterMethod(
   /* In case the cursor has been used before, clear it now. */
   sqlite3_finalize(pCsr->pStmt);
   sqlite3_free(pCsr->aDoclist);
+  sqlite3_free(pCsr->aMatchinfo);
   sqlite3Fts3ExprFree(pCsr->pExpr);
   memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
 
@@ -130062,10 +136283,17 @@ static int fts3FilterMethod(
   ** row by docid.
   */
   if( eSearch==FTS3_FULLSCAN_SEARCH ){
-    zSql = sqlite3_mprintf(
-        "SELECT %s ORDER BY rowid %s",
-        p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC")
-    );
+    if( pDocidGe || pDocidLe ){
+      zSql = sqlite3_mprintf(
+          "SELECT %s WHERE rowid BETWEEN %lld AND %lld ORDER BY rowid %s",
+          p->zReadExprlist, pCsr->iMinDocid, pCsr->iMaxDocid,
+          (pCsr->bDesc ? "DESC" : "ASC")
+      );
+    }else{
+      zSql = sqlite3_mprintf("SELECT %s ORDER BY rowid %s", 
+          p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC")
+      );
+    }
     if( zSql ){
       rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
       sqlite3_free(zSql);
@@ -130301,11 +136529,31 @@ static void fts3ReversePoslist(char *pStart, char **ppPoslist){
   char *p = &(*ppPoslist)[-2];
   char c = 0;
 
+  /* Skip backwards passed any trailing 0x00 bytes added by NearTrim() */
   while( p>pStart && (c=*p--)==0 );
+
+  /* Search backwards for a varint with value zero (the end of the previous 
+  ** poslist). This is an 0x00 byte preceded by some byte that does not
+  ** have the 0x80 bit set.  */
   while( p>pStart && (*p & 0x80) | c ){ 
     c = *p--; 
   }
-  if( p>pStart ){ p = &p[2]; }
+  assert( p==pStart || c==0 );
+
+  /* At this point p points to that preceding byte without the 0x80 bit
+  ** set. So to find the start of the poslist, skip forward 2 bytes then
+  ** over a varint. 
+  **
+  ** Normally. The other case is that p==pStart and the poslist to return
+  ** is the first in the doclist. In this case do not skip forward 2 bytes.
+  ** The second part of the if condition (c==0 && *ppPoslist>&p[2])
+  ** is required for cases where the first byte of a doclist and the
+  ** doclist is empty. For example, if the first docid is 10, a doclist
+  ** that begins with:
+  **
+  **   0x0A 0x00 <next docid delta varint>
+  */
+  if( p>pStart || (c==0 && *ppPoslist>&p[2]) ){ p = &p[2]; }
   while( *p++&0x80 );
   *ppPoslist = p;
 }
@@ -130376,6 +136624,8 @@ static void fts3SnippetFunc(
   }
   if( !zEllipsis || !zEnd || !zStart ){
     sqlite3_result_error_nomem(pContext);
+  }else if( nToken==0 ){
+    sqlite3_result_text(pContext, "", -1, SQLITE_STATIC);
   }else if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){
     sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis, iCol, nToken);
   }
@@ -130811,14 +137061,17 @@ static void fts3EvalAllocateReaders(
 ** This function assumes that pList points to a buffer allocated using
 ** sqlite3_malloc(). This function takes responsibility for eventually
 ** freeing the buffer.
+**
+** SQLITE_OK is returned if successful, or SQLITE_NOMEM if an error occurs.
 */
-static void fts3EvalPhraseMergeToken(
+static int fts3EvalPhraseMergeToken(
   Fts3Table *pTab,                /* FTS Table pointer */
   Fts3Phrase *p,                  /* Phrase to merge pList/nList into */
   int iToken,                     /* Token pList/nList corresponds to */
   char *pList,                    /* Pointer to doclist */
   int nList                       /* Number of bytes in pList */
 ){
+  int rc = SQLITE_OK;
   assert( iToken!=p->iDoclistToken );
 
   if( pList==0 ){
@@ -130857,13 +137110,16 @@ static void fts3EvalPhraseMergeToken(
       nDiff = p->iDoclistToken - iToken;
     }
 
-    fts3DoclistPhraseMerge(pTab->bDescIdx, nDiff, pLeft, nLeft, pRight,&nRight);
+    rc = fts3DoclistPhraseMerge(
+        pTab->bDescIdx, nDiff, pLeft, nLeft, &pRight, &nRight
+    );
     sqlite3_free(pLeft);
     p->doclist.aAll = pRight;
     p->doclist.nAll = nRight;
   }
 
   if( iToken>p->iDoclistToken ) p->iDoclistToken = iToken;
+  return rc;
 }
 
 /*
@@ -130889,7 +137145,7 @@ static int fts3EvalPhraseLoad(
       char *pThis = 0;
       rc = fts3TermSelect(pTab, pToken, p->iColumn, &nThis, &pThis);
       if( rc==SQLITE_OK ){
-        fts3EvalPhraseMergeToken(pTab, p, iToken, pThis, nThis);
+        rc = fts3EvalPhraseMergeToken(pTab, p, iToken, pThis, nThis);
       }
     }
     assert( pToken->pSegcsr==0 );
@@ -131325,7 +137581,7 @@ static int fts3EvalIncrPhraseNext(
           bMaxSet = 1;
         }
       }
-      assert( rc!=SQLITE_OK || a[p->nToken-1].bIgnore==0 );
+      assert( rc!=SQLITE_OK || (p->nToken>=1 && a[p->nToken-1].bIgnore==0) );
       assert( rc!=SQLITE_OK || bMaxSet );
 
       /* Keep advancing iterators until they all point to the same document */
@@ -131431,12 +137687,14 @@ static void fts3EvalStartReaders(
 ){
   if( pExpr && SQLITE_OK==*pRc ){
     if( pExpr->eType==FTSQUERY_PHRASE ){
-      int i;
       int nToken = pExpr->pPhrase->nToken;
-      for(i=0; i<nToken; i++){
-        if( pExpr->pPhrase->aToken[i].pDeferred==0 ) break;
+      if( nToken ){
+        int i;
+        for(i=0; i<nToken; i++){
+          if( pExpr->pPhrase->aToken[i].pDeferred==0 ) break;
+        }
+        pExpr->bDeferred = (i==nToken);
       }
-      pExpr->bDeferred = (i==nToken);
       *pRc = fts3EvalPhraseStart(pCsr, 1, pExpr->pPhrase);
     }else{
       fts3EvalStartReaders(pCsr, pExpr->pLeft, pRc);
@@ -131692,8 +137950,12 @@ static int fts3EvalSelectDeferred(
         rc = fts3TermSelect(pTab, pToken, pTC->iCol, &nList, &pList);
         assert( rc==SQLITE_OK || pList==0 );
         if( rc==SQLITE_OK ){
+          rc = fts3EvalPhraseMergeToken(
+              pTab, pTC->pPhrase, pTC->iToken,pList,nList
+          );
+        }
+        if( rc==SQLITE_OK ){
           int nCount;
-          fts3EvalPhraseMergeToken(pTab, pTC->pPhrase, pTC->iToken,pList,nList);
           nCount = fts3DoclistCountDocids(
               pTC->pPhrase->doclist.aAll, pTC->pPhrase->doclist.nAll
           );
@@ -131918,6 +138180,22 @@ static void fts3EvalNextRow(
           }
           pExpr->iDocid = pLeft->iDocid;
           pExpr->bEof = (pLeft->bEof || pRight->bEof);
+          if( pExpr->eType==FTSQUERY_NEAR && pExpr->bEof ){
+            if( pRight->pPhrase && pRight->pPhrase->doclist.aAll ){
+              Fts3Doclist *pDl = &pRight->pPhrase->doclist;
+              while( *pRc==SQLITE_OK && pRight->bEof==0 ){
+                memset(pDl->pList, 0, pDl->nList);
+                fts3EvalNextRow(pCsr, pRight, pRc);
+              }
+            }
+            if( pLeft->pPhrase && pLeft->pPhrase->doclist.aAll ){
+              Fts3Doclist *pDl = &pLeft->pPhrase->doclist;
+              while( *pRc==SQLITE_OK && pLeft->bEof==0 ){
+                memset(pDl->pList, 0, pDl->nList);
+                fts3EvalNextRow(pCsr, pLeft, pRc);
+              }
+            }
+          }
         }
         break;
       }
@@ -132290,6 +138568,7 @@ static void fts3EvalRestart(
       }
       pPhrase->doclist.pNextDocid = 0;
       pPhrase->doclist.iDocid = 0;
+      pPhrase->pOrPoslist = 0;
     }
 
     pExpr->iDocid = 0;
@@ -132535,8 +138814,8 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(
   iDocid = pExpr->iDocid;
   pIter = pPhrase->doclist.pList;
   if( iDocid!=pCsr->iPrevId || pExpr->bEof ){
+    int rc = SQLITE_OK;
     int bDescDoclist = pTab->bDescIdx;      /* For DOCID_CMP macro */
-    int iMul;                     /* +1 if csr dir matches index dir, else -1 */
     int bOr = 0;
     u8 bEof = 0;
     u8 bTreeEof = 0;
@@ -132560,72 +138839,44 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(
     ** an incremental phrase. Load the entire doclist for the phrase
     ** into memory in this case.  */
     if( pPhrase->bIncr ){
-      int rc = SQLITE_OK;
-      int bEofSave = pExpr->bEof;
-      fts3EvalRestart(pCsr, pExpr, &rc);
-      while( rc==SQLITE_OK && !pExpr->bEof ){
-        fts3EvalNextRow(pCsr, pExpr, &rc);
-        if( bEofSave==0 && pExpr->iDocid==iDocid ) break;
+      int bEofSave = pNear->bEof;
+      fts3EvalRestart(pCsr, pNear, &rc);
+      while( rc==SQLITE_OK && !pNear->bEof ){
+        fts3EvalNextRow(pCsr, pNear, &rc);
+        if( bEofSave==0 && pNear->iDocid==iDocid ) break;
       }
-      pIter = pPhrase->doclist.pList;
       assert( rc!=SQLITE_OK || pPhrase->bIncr==0 );
-      if( rc!=SQLITE_OK ) return rc;
     }
-    
-    iMul = ((pCsr->bDesc==bDescDoclist) ? 1 : -1);
-    while( bTreeEof==1 
-        && pNear->bEof==0
-        && (DOCID_CMP(pNear->iDocid, pCsr->iPrevId) * iMul)<0
-    ){
-      int rc = SQLITE_OK;
-      fts3EvalNextRow(pCsr, pExpr, &rc);
-      if( rc!=SQLITE_OK ) return rc;
-      iDocid = pExpr->iDocid;
-      pIter = pPhrase->doclist.pList;
+    if( bTreeEof ){
+      while( rc==SQLITE_OK && !pNear->bEof ){
+        fts3EvalNextRow(pCsr, pNear, &rc);
+      }
     }
+    if( rc!=SQLITE_OK ) return rc;
 
-    bEof = (pPhrase->doclist.nAll==0);
-    assert( bDescDoclist==0 || bDescDoclist==1 );
-    assert( pCsr->bDesc==0 || pCsr->bDesc==1 );
-
-    if( bEof==0 ){
-      if( pCsr->bDesc==bDescDoclist ){
+    pIter = pPhrase->pOrPoslist;
+    iDocid = pPhrase->iOrDocid;
+    if( pCsr->bDesc==bDescDoclist ){
+      bEof = !pPhrase->doclist.nAll ||
+                 (pIter >= (pPhrase->doclist.aAll + pPhrase->doclist.nAll));
+      while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){
+        sqlite3Fts3DoclistNext(
+            bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, 
+            &pIter, &iDocid, &bEof
+        );
+      }
+    }else{
+      bEof = !pPhrase->doclist.nAll || (pIter && pIter<=pPhrase->doclist.aAll);
+      while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){
         int dummy;
-        if( pNear->bEof ){
-          /* This expression is already at EOF. So position it to point to the
-          ** last entry in the doclist at pPhrase->doclist.aAll[]. Variable
-          ** iDocid is already set for this entry, so all that is required is
-          ** to set pIter to point to the first byte of the last position-list
-          ** in the doclist. 
-          **
-          ** It would also be correct to set pIter and iDocid to zero. In
-          ** this case, the first call to sqltie3Fts4DoclistPrev() below
-          ** would also move the iterator to point to the last entry in the 
-          ** doclist. However, this is expensive, as to do so it has to 
-          ** iterate through the entire doclist from start to finish (since
-          ** it does not know the docid for the last entry).  */
-          pIter = &pPhrase->doclist.aAll[pPhrase->doclist.nAll-1];
-          fts3ReversePoslist(pPhrase->doclist.aAll, &pIter);
-        }
-        while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){
-          sqlite3Fts3DoclistPrev(
-              bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, 
-              &pIter, &iDocid, &dummy, &bEof
-          );
-        }
-      }else{
-        if( pNear->bEof ){
-          pIter = 0;
-          iDocid = 0;
-        }
-        while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){
-          sqlite3Fts3DoclistNext(
-              bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, 
-              &pIter, &iDocid, &bEof
-          );
-        }
+        sqlite3Fts3DoclistPrev(
+            bDescDoclist, pPhrase->doclist.aAll, pPhrase->doclist.nAll, 
+            &pIter, &iDocid, &dummy, &bEof
+        );
       }
     }
+    pPhrase->pOrPoslist = pIter;
+    pPhrase->iOrDocid = iDocid;
 
     if( bEof || iDocid!=pCsr->iPrevId ) pIter = 0;
   }
@@ -132639,10 +138890,13 @@ SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(
   }
   while( iThis<iCol ){
     fts3ColumnlistCopy(0, &pIter);
-    if( *pIter==0x00 ) return 0;
+    if( *pIter==0x00 ) return SQLITE_OK;
     pIter++;
     pIter += fts3GetVarint32(pIter, &iThis);
   }
+  if( *pIter==0x00 ){
+    pIter = 0;
+  }
 
   *ppOut = ((iCol==iThis)?pIter:0);
   return SQLITE_OK;
@@ -132685,7 +138939,7 @@ SQLITE_PRIVATE int sqlite3Fts3Corrupt(){
 #ifdef _WIN32
 __declspec(dllexport)
 #endif
-SQLITE_API int sqlite3_fts3_init(
+SQLITE_API int SQLITE_STDCALL sqlite3_fts3_init(
   sqlite3 *db, 
   char **pzErrMsg,
   const sqlite3_api_routines *pApi
@@ -132816,7 +139070,7 @@ static int fts3auxConnectMethod(
   return SQLITE_OK;
 
  bad_args:
-  *pzErr = sqlite3_mprintf("invalid arguments to fts4aux constructor");
+  sqlite3Fts3ErrMsg(pzErr, "invalid arguments to fts4aux constructor");
   return SQLITE_ERROR;
 }
 
@@ -133442,7 +139696,7 @@ static int getNextToken(
   /* Set variable i to the maximum number of bytes of input to tokenize. */
   for(i=0; i<n; i++){
     if( sqlite3_fts3_enable_parentheses && (z[i]=='(' || z[i]==')') ) break;
-    if( z[i]=='*' || z[i]=='"' ) break;
+    if( z[i]=='"' ) break;
   }
 
   *pnConsumed = i;
@@ -134274,13 +140528,13 @@ SQLITE_PRIVATE int sqlite3Fts3ExprParse(
     sqlite3Fts3ExprFree(*ppExpr);
     *ppExpr = 0;
     if( rc==SQLITE_TOOBIG ){
-      *pzErr = sqlite3_mprintf(
+      sqlite3Fts3ErrMsg(pzErr,
           "FTS expression tree is too large (maximum depth %d)", 
           SQLITE_FTS3_MAX_EXPR_DEPTH
       );
       rc = SQLITE_ERROR;
     }else if( rc==SQLITE_ERROR ){
-      *pzErr = sqlite3_mprintf("malformed MATCH expression: [%s]", z);
+      sqlite3Fts3ErrMsg(pzErr, "malformed MATCH expression: [%s]", z);
     }
   }
 
@@ -135103,7 +141357,7 @@ static int isVowel(const char *z){
 ** by a consonant.
 **
 ** In this routine z[] is in reverse order.  So we are really looking
-** for an instance of of a consonant followed by a vowel.
+** for an instance of a consonant followed by a vowel.
 */
 static int m_gt_0(const char *z){
   while( isVowel(z) ){ z++; }
@@ -135653,7 +141907,7 @@ static void scalarFunc(
   if( argc==2 ){
     void *pOld;
     int n = sqlite3_value_bytes(argv[1]);
-    if( n!=sizeof(pPtr) ){
+    if( zName==0 || n!=sizeof(pPtr) ){
       sqlite3_result_error(context, "argument type mismatch", -1);
       return;
     }
@@ -135664,7 +141918,9 @@ static void scalarFunc(
       return;
     }
   }else{
-    pPtr = sqlite3Fts3HashFind(pHash, zName, nName);
+    if( zName ){
+      pPtr = sqlite3Fts3HashFind(pHash, zName, nName);
+    }
     if( !pPtr ){
       char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
       sqlite3_result_error(context, zErr, -1);
@@ -135745,12 +142001,16 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(
   zEnd = &zCopy[strlen(zCopy)];
 
   z = (char *)sqlite3Fts3NextToken(zCopy, &n);
+  if( z==0 ){
+    assert( n==0 );
+    z = zCopy;
+  }
   z[n] = '\0';
   sqlite3Fts3Dequote(z);
 
   m = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash,z,(int)strlen(z)+1);
   if( !m ){
-    *pzErr = sqlite3_mprintf("unknown tokenizer: %s", z);
+    sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", z);
     rc = SQLITE_ERROR;
   }else{
     char const **aArg = 0;
@@ -135773,7 +142033,7 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(
     rc = m->xCreate(iArg, aArg, ppTok);
     assert( rc!=SQLITE_OK || *ppTok );
     if( rc!=SQLITE_OK ){
-      *pzErr = sqlite3_mprintf("unknown tokenizer");
+      sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer");
     }else{
       (*ppTok)->pModule = m; 
     }
@@ -135857,9 +142117,9 @@ static void testFunc(
   p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1);
 
   if( !p ){
-    char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
-    sqlite3_result_error(context, zErr, -1);
-    sqlite3_free(zErr);
+    char *zErr2 = sqlite3_mprintf("unknown tokenizer: %s", zName);
+    sqlite3_result_error(context, zErr2, -1);
+    sqlite3_free(zErr2);
     return;
   }
 
@@ -136394,7 +142654,7 @@ static int fts3tokQueryTokenizer(
 
   p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1);
   if( !p ){
-    *pzErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
+    sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", zName);
     return SQLITE_ERROR;
   }
 
@@ -136472,7 +142732,7 @@ static int fts3tokConnectMethod(
   sqlite3_vtab **ppVtab,          /* OUT: New sqlite3_vtab object */
   char **pzErr                    /* OUT: sqlite3_malloc'd error message */
 ){
-  Fts3tokTable *pTab;
+  Fts3tokTable *pTab = 0;
   const sqlite3_tokenizer_module *pMod = 0;
   sqlite3_tokenizer *pTok = 0;
   int rc;
@@ -137091,7 +143351,7 @@ static int fts3SqlStmt(
 /* 25 */  "",
 
 /* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?",
-/* 27 */ "SELECT DISTINCT level / (1024 * ?) FROM %Q.'%q_segdir'",
+/* 27 */ "SELECT ? UNION SELECT level / (1024 * ?) FROM %Q.'%q_segdir'",
 
 /* This statement is used to determine which level to read the input from
 ** when performing an incremental merge. It returns the absolute level number
@@ -138390,7 +144650,10 @@ SQLITE_PRIVATE int sqlite3Fts3SegReaderNew(
 ** an array of pending terms by term. This occurs as part of flushing
 ** the contents of the pending-terms hash table to the database.
 */
-static int fts3CompareElemByTerm(const void *lhs, const void *rhs){
+static int SQLITE_CDECL fts3CompareElemByTerm(
+  const void *lhs,
+  const void *rhs
+){
   char *z1 = fts3HashKey(*(Fts3HashElem **)lhs);
   char *z2 = fts3HashKey(*(Fts3HashElem **)rhs);
   int n1 = fts3HashKeysize(*(Fts3HashElem **)lhs);
@@ -139847,8 +146110,8 @@ static int fts3PromoteSegments(
 
     if( bOk ){
       int iIdx = 0;
-      sqlite3_stmt *pUpdate1;
-      sqlite3_stmt *pUpdate2;
+      sqlite3_stmt *pUpdate1 = 0;
+      sqlite3_stmt *pUpdate2 = 0;
 
       if( rc==SQLITE_OK ){
         rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL_IDX, &pUpdate1, 0);
@@ -140206,7 +146469,8 @@ static int fts3DoOptimize(Fts3Table *p, int bReturnDone){
   rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
   if( rc==SQLITE_OK ){
     int rc2;
-    sqlite3_bind_int(pAllLangid, 1, p->nIndex);
+    sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid);
+    sqlite3_bind_int(pAllLangid, 2, p->nIndex);
     while( sqlite3_step(pAllLangid)==SQLITE_ROW ){
       int i;
       int iLangid = sqlite3_column_int(pAllLangid, 0);
@@ -141538,7 +147802,7 @@ static int fts3IncrmergeHintPop(Blob *pHint, i64 *piAbsLevel, int *pnInput){
   pHint->n = i;
   i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel);
   i += fts3GetVarint32(&pHint->a[i], pnInput);
-  if( i!=nHint ) return SQLITE_CORRUPT_VTAB;
+  if( i!=nHint ) return FTS_CORRUPT_VTAB;
 
   return SQLITE_OK;
 }
@@ -141906,7 +148170,8 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){
   rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
   if( rc==SQLITE_OK ){
     int rc2;
-    sqlite3_bind_int(pAllLangid, 1, p->nIndex);
+    sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid);
+    sqlite3_bind_int(pAllLangid, 2, p->nIndex);
     while( rc==SQLITE_OK && sqlite3_step(pAllLangid)==SQLITE_ROW ){
       int iLangid = sqlite3_column_int(pAllLangid, 0);
       int i;
@@ -141919,7 +148184,6 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){
   }
 
   /* This block calculates the checksum according to the %_content table */
-  rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0);
   if( rc==SQLITE_OK ){
     sqlite3_tokenizer_module const *pModule = p->pTokenizer->pModule;
     sqlite3_stmt *pStmt = 0;
@@ -142016,7 +148280,7 @@ static int fts3DoIntegrityCheck(
   int rc;
   int bOk = 0;
   rc = fts3IntegrityCheck(p, &bOk);
-  if( rc==SQLITE_OK && bOk==0 ) rc = SQLITE_CORRUPT_VTAB;
+  if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB;
   return rc;
 }
 
@@ -142454,6 +148718,7 @@ SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *p){
 #define FTS3_MATCHINFO_LENGTH    'l'        /* nCol values */
 #define FTS3_MATCHINFO_LCS       's'        /* nCol values */
 #define FTS3_MATCHINFO_HITS      'x'        /* 3*nCol*nPhrase values */
+#define FTS3_MATCHINFO_LHITS     'y'        /* nCol*nPhrase values */
 
 /*
 ** The default value for the second argument to matchinfo(). 
@@ -142869,37 +149134,39 @@ static int fts3BestSnippet(
   sIter.nSnippet = nSnippet;
   sIter.nPhrase = nList;
   sIter.iCurrent = -1;
-  (void)fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void *)&sIter);
+  rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void *)&sIter);
+  if( rc==SQLITE_OK ){
 
-  /* Set the *pmSeen output variable. */
-  for(i=0; i<nList; i++){
-    if( sIter.aPhrase[i].pHead ){
-      *pmSeen |= (u64)1 << i;
+    /* Set the *pmSeen output variable. */
+    for(i=0; i<nList; i++){
+      if( sIter.aPhrase[i].pHead ){
+        *pmSeen |= (u64)1 << i;
+      }
     }
-  }
 
-  /* Loop through all candidate snippets. Store the best snippet in 
-  ** *pFragment. Store its associated 'score' in iBestScore.
-  */
-  pFragment->iCol = iCol;
-  while( !fts3SnippetNextCandidate(&sIter) ){
-    int iPos;
-    int iScore;
-    u64 mCover;
-    u64 mHighlight;
-    fts3SnippetDetails(&sIter, mCovered, &iPos, &iScore, &mCover, &mHighlight);
-    assert( iScore>=0 );
-    if( iScore>iBestScore ){
-      pFragment->iPos = iPos;
-      pFragment->hlmask = mHighlight;
-      pFragment->covered = mCover;
-      iBestScore = iScore;
+    /* Loop through all candidate snippets. Store the best snippet in 
+     ** *pFragment. Store its associated 'score' in iBestScore.
+     */
+    pFragment->iCol = iCol;
+    while( !fts3SnippetNextCandidate(&sIter) ){
+      int iPos;
+      int iScore;
+      u64 mCover;
+      u64 mHighlite;
+      fts3SnippetDetails(&sIter, mCovered, &iPos, &iScore, &mCover,&mHighlite);
+      assert( iScore>=0 );
+      if( iScore>iBestScore ){
+        pFragment->iPos = iPos;
+        pFragment->hlmask = mHighlite;
+        pFragment->covered = mCover;
+        iBestScore = iScore;
+      }
     }
-  }
 
+    *piScore = iBestScore;
+  }
   sqlite3_free(sIter.aPhrase);
-  *piScore = iBestScore;
-  return SQLITE_OK;
+  return rc;
 }
 
 
@@ -143107,8 +149374,12 @@ static int fts3SnippetText(
       ** required. They are required if (a) this is not the first fragment,
       ** or (b) this fragment does not begin at position 0 of its column. 
       */
-      if( rc==SQLITE_OK && (iPos>0 || iFragment>0) ){
-        rc = fts3StringAppend(pOut, zEllipsis, -1);
+      if( rc==SQLITE_OK ){
+        if( iPos>0 || iFragment>0 ){
+          rc = fts3StringAppend(pOut, zEllipsis, -1);
+        }else if( iBegin ){
+          rc = fts3StringAppend(pOut, zDoc, iBegin);
+        }
       }
       if( rc!=SQLITE_OK || iCurrent<iPos ) continue;
     }
@@ -143230,6 +149501,51 @@ static int fts3ExprLocalHitsCb(
   return rc;
 }
 
+/*
+** fts3ExprIterate() callback used to gather information for the matchinfo
+** directive 'y'.
+*/
+static int fts3ExprLHitsCb(
+  Fts3Expr *pExpr,                /* Phrase expression node */
+  int iPhrase,                    /* Phrase number */
+  void *pCtx                      /* Pointer to MatchInfo structure */
+){
+  MatchInfo *p = (MatchInfo *)pCtx;
+  Fts3Table *pTab = (Fts3Table *)p->pCursor->base.pVtab;
+  int rc = SQLITE_OK;
+  int iStart = iPhrase * p->nCol;
+  Fts3Expr *pEof;                 /* Ancestor node already at EOF */
+  
+  /* This must be a phrase */
+  assert( pExpr->pPhrase );
+
+  /* Initialize all output integers to zero. */
+  memset(&p->aMatchinfo[iStart], 0, sizeof(u32) * p->nCol);
+
+  /* Check if this or any parent node is at EOF. If so, then all output
+  ** values are zero.  */
+  for(pEof=pExpr; pEof && pEof->bEof==0; pEof=pEof->pParent);
+
+  if( pEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){
+    Fts3Phrase *pPhrase = pExpr->pPhrase;
+    char *pIter = pPhrase->doclist.pList;
+    int iCol = 0;
+
+    while( 1 ){
+      int nHit = fts3ColumnlistCount(&pIter);
+      if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){
+        p->aMatchinfo[iStart + iCol] = (u32)nHit;
+      }
+      assert( *pIter==0x00 || *pIter==0x01 );
+      if( *pIter!=0x01 ) break;
+      pIter++;
+      pIter += fts3GetVarint32(pIter, &iCol);
+    }
+  }
+
+  return rc;
+}
+
 static int fts3MatchinfoCheck(
   Fts3Table *pTab, 
   char cArg,
@@ -143242,10 +149558,11 @@ static int fts3MatchinfoCheck(
    || (cArg==FTS3_MATCHINFO_LENGTH && pTab->bHasDocsize)
    || (cArg==FTS3_MATCHINFO_LCS)
    || (cArg==FTS3_MATCHINFO_HITS)
+   || (cArg==FTS3_MATCHINFO_LHITS)
   ){
     return SQLITE_OK;
   }
-  *pzErr = sqlite3_mprintf("unrecognized matchinfo request: %c", cArg);
+  sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo request: %c", cArg);
   return SQLITE_ERROR;
 }
 
@@ -143265,6 +149582,10 @@ static int fts3MatchinfoSize(MatchInfo *pInfo, char cArg){
       nVal = pInfo->nCol;
       break;
 
+    case FTS3_MATCHINFO_LHITS:
+      nVal = pInfo->nCol * pInfo->nPhrase;
+      break;
+
     default:
       assert( cArg==FTS3_MATCHINFO_HITS );
       nVal = pInfo->nCol * pInfo->nPhrase * 3;
@@ -143519,6 +149840,10 @@ static int fts3MatchinfoValues(
         }
         break;
 
+      case FTS3_MATCHINFO_LHITS:
+        (void)fts3ExprIterate(pCsr->pExpr, fts3ExprLHitsCb, (void*)pInfo);
+        break;
+
       default: {
         Fts3Expr *pExpr;
         assert( zArg[i]==FTS3_MATCHINFO_HITS );
@@ -143674,7 +149999,7 @@ SQLITE_PRIVATE void sqlite3Fts3Snippet(
       */
       for(iRead=0; iRead<pTab->nColumn; iRead++){
         SnippetFragment sF = {0, 0, 0, 0};
-        int iS;
+        int iS = 0;
         if( iCol>=0 && iRead!=iCol ) continue;
 
         /* Find the best snippet of nFToken tokens in column iRead. */
@@ -145080,13 +151405,12 @@ static int readInt16(u8 *p){
   return (p[0]<<8) + p[1];
 }
 static void readCoord(u8 *p, RtreeCoord *pCoord){
-  u32 i = (
+  pCoord->u = (
     (((u32)p[0]) << 24) + 
     (((u32)p[1]) << 16) + 
     (((u32)p[2]) <<  8) + 
     (((u32)p[3]) <<  0)
   );
-  *(u32 *)pCoord = i;
 }
 static i64 readInt64(u8 *p){
   return (
@@ -145115,7 +151439,7 @@ static int writeCoord(u8 *p, RtreeCoord *pCoord){
   u32 i;
   assert( sizeof(RtreeCoord)==4 );
   assert( sizeof(u32)==4 );
-  i = *(u32 *)pCoord;
+  i = pCoord->u;
   p[0] = (i>>24)&0xFF;
   p[1] = (i>>16)&0xFF;
   p[2] = (i>> 8)&0xFF;
@@ -145446,14 +151770,13 @@ static void nodeGetCell(
   RtreeCell *pCell             /* OUT: Write the cell contents here */
 ){
   u8 *pData;
-  u8 *pEnd;
   RtreeCoord *pCoord;
+  int ii;
   pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell);
   pData = pNode->zData + (12 + pRtree->nBytesPerCell*iCell);
-  pEnd = pData + pRtree->nDim*8;
   pCoord = pCell->aCoord;
-  for(; pData<pEnd; pData+=4, pCoord++){
-    readCoord(pData, pCoord);
+  for(ii=0; ii<pRtree->nDim*2; ii++){
+    readCoord(&pData[ii*4], &pCoord[ii]);
   }
 }
 
@@ -145893,7 +152216,7 @@ static RtreeSearchPoint *rtreeEnqueue(
   pNew = pCur->aPoint + i;
   pNew->rScore = rScore;
   pNew->iLevel = iLevel;
-  assert( iLevel>=0 && iLevel<=RTREE_MAX_DEPTH );
+  assert( iLevel<=RTREE_MAX_DEPTH );
   while( i>0 ){
     RtreeSearchPoint *pParent;
     j = (i-1)/2;
@@ -147517,6 +153840,8 @@ static int rtreeUpdate(
   rtreeReference(pRtree);
   assert(nData>=1);
 
+  cell.iRowid = 0;  /* Used only to suppress a compiler warning */
+
   /* Constraint handling. A write operation on an r-tree table may return
   ** SQLITE_CONSTRAINT for two reasons:
   **
@@ -147531,11 +153856,19 @@ static int rtreeUpdate(
   if( nData>1 ){
     int ii;
 
-    /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */
-    assert( nData==(pRtree->nDim*2 + 3) );
+    /* Populate the cell.aCoord[] array. The first coordinate is azData[3].
+    **
+    ** NB: nData can only be less than nDim*2+3 if the rtree is mis-declared
+    ** with "column" that are interpreted as table constraints.
+    ** Example:  CREATE VIRTUAL TABLE bad USING rtree(x,y,CHECK(y>5));
+    ** This problem was discovered after years of use, so we silently ignore
+    ** these kinds of misdeclared tables to avoid breaking any legacy.
+    */
+    assert( nData<=(pRtree->nDim*2 + 3) );
+
 #ifndef SQLITE_RTREE_INT_ONLY
     if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
-      for(ii=0; ii<(pRtree->nDim*2); ii+=2){
+      for(ii=0; ii<nData-4; ii+=2){
         cell.aCoord[ii].f = rtreeValueDown(azData[ii+3]);
         cell.aCoord[ii+1].f = rtreeValueUp(azData[ii+4]);
         if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
@@ -147546,7 +153879,7 @@ static int rtreeUpdate(
     }else
 #endif
     {
-      for(ii=0; ii<(pRtree->nDim*2); ii+=2){
+      for(ii=0; ii<nData-4; ii+=2){
         cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]);
         cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]);
         if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){
@@ -148117,7 +154450,7 @@ static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
 /*
 ** Register a new geometry function for use with the r-tree MATCH operator.
 */
-SQLITE_API int sqlite3_rtree_geometry_callback(
+SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback(
   sqlite3 *db,                  /* Register SQL function on this connection */
   const char *zGeom,            /* Name of the new SQL function */
   int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*), /* Callback */
@@ -148141,7 +154474,7 @@ SQLITE_API int sqlite3_rtree_geometry_callback(
 ** Register a new 2nd-generation geometry function for use with the
 ** r-tree MATCH operator.
 */
-SQLITE_API int sqlite3_rtree_query_callback(
+SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback(
   sqlite3 *db,                 /* Register SQL function on this connection */
   const char *zQueryFunc,      /* Name of new SQL function */
   int (*xQueryFunc)(sqlite3_rtree_query_info*), /* Callback */
@@ -148166,7 +154499,7 @@ SQLITE_API int sqlite3_rtree_query_callback(
 #ifdef _WIN32
 __declspec(dllexport)
 #endif
-SQLITE_API int sqlite3_rtree_init(
+SQLITE_API int SQLITE_STDCALL sqlite3_rtree_init(
   sqlite3 *db,
   char **pzErrMsg,
   const sqlite3_api_routines *pApi
@@ -148671,7 +155004,7 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){
 #ifdef _WIN32
 __declspec(dllexport)
 #endif
-SQLITE_API int sqlite3_icu_init(
+SQLITE_API int SQLITE_STDCALL sqlite3_icu_init(
   sqlite3 *db, 
   char **pzErrMsg,
   const sqlite3_api_routines *pApi
@@ -148946,3 +155279,654 @@ SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(
 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
 
 /************** End of fts3_icu.c ********************************************/
+/************** Begin file dbstat.c ******************************************/
+/*
+** 2010 July 12
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+******************************************************************************
+**
+** This file contains an implementation of the "dbstat" virtual table.
+**
+** The dbstat virtual table is used to extract low-level formatting
+** information from an SQLite database in order to implement the
+** "sqlite3_analyzer" utility.  See the ../tool/spaceanal.tcl script
+** for an example implementation.
+*/
+
+#if (defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)) \
+    && !defined(SQLITE_OMIT_VIRTUALTABLE)
+
+/*
+** Page paths:
+** 
+**   The value of the 'path' column describes the path taken from the 
+**   root-node of the b-tree structure to each page. The value of the 
+**   root-node path is '/'.
+**
+**   The value of the path for the left-most child page of the root of
+**   a b-tree is '/000/'. (Btrees store content ordered from left to right
+**   so the pages to the left have smaller keys than the pages to the right.)
+**   The next to left-most child of the root page is
+**   '/001', and so on, each sibling page identified by a 3-digit hex 
+**   value. The children of the 451st left-most sibling have paths such
+**   as '/1c2/000/, '/1c2/001/' etc.
+**
+**   Overflow pages are specified by appending a '+' character and a 
+**   six-digit hexadecimal value to the path to the cell they are linked
+**   from. For example, the three overflow pages in a chain linked from 
+**   the left-most cell of the 450th child of the root page are identified
+**   by the paths:
+**
+**      '/1c2/000+000000'         // First page in overflow chain
+**      '/1c2/000+000001'         // Second page in overflow chain
+**      '/1c2/000+000002'         // Third page in overflow chain
+**
+**   If the paths are sorted using the BINARY collation sequence, then
+**   the overflow pages associated with a cell will appear earlier in the
+**   sort-order than its child page:
+**
+**      '/1c2/000/'               // Left-most child of 451st child of root
+*/
+#define VTAB_SCHEMA                                                         \
+  "CREATE TABLE xx( "                                                       \
+  "  name       STRING,           /* Name of table or index */"             \
+  "  path       INTEGER,          /* Path to page from root */"             \
+  "  pageno     INTEGER,          /* Page number */"                        \
+  "  pagetype   STRING,           /* 'internal', 'leaf' or 'overflow' */"   \
+  "  ncell      INTEGER,          /* Cells on page (0 for overflow) */"     \
+  "  payload    INTEGER,          /* Bytes of payload on this page */"      \
+  "  unused     INTEGER,          /* Bytes of unused space on this page */" \
+  "  mx_payload INTEGER,          /* Largest payload size of all cells */"  \
+  "  pgoffset   INTEGER,          /* Offset of page in file */"             \
+  "  pgsize     INTEGER           /* Size of the page */"                   \
+  ");"
+
+
+typedef struct StatTable StatTable;
+typedef struct StatCursor StatCursor;
+typedef struct StatPage StatPage;
+typedef struct StatCell StatCell;
+
+struct StatCell {
+  int nLocal;                     /* Bytes of local payload */
+  u32 iChildPg;                   /* Child node (or 0 if this is a leaf) */
+  int nOvfl;                      /* Entries in aOvfl[] */
+  u32 *aOvfl;                     /* Array of overflow page numbers */
+  int nLastOvfl;                  /* Bytes of payload on final overflow page */
+  int iOvfl;                      /* Iterates through aOvfl[] */
+};
+
+struct StatPage {
+  u32 iPgno;
+  DbPage *pPg;
+  int iCell;
+
+  char *zPath;                    /* Path to this page */
+
+  /* Variables populated by statDecodePage(): */
+  u8 flags;                       /* Copy of flags byte */
+  int nCell;                      /* Number of cells on page */
+  int nUnused;                    /* Number of unused bytes on page */
+  StatCell *aCell;                /* Array of parsed cells */
+  u32 iRightChildPg;              /* Right-child page number (or 0) */
+  int nMxPayload;                 /* Largest payload of any cell on this page */
+};
+
+struct StatCursor {
+  sqlite3_vtab_cursor base;
+  sqlite3_stmt *pStmt;            /* Iterates through set of root pages */
+  int isEof;                      /* After pStmt has returned SQLITE_DONE */
+
+  StatPage aPage[32];
+  int iPage;                      /* Current entry in aPage[] */
+
+  /* Values to return. */
+  char *zName;                    /* Value of 'name' column */
+  char *zPath;                    /* Value of 'path' column */
+  u32 iPageno;                    /* Value of 'pageno' column */
+  char *zPagetype;                /* Value of 'pagetype' column */
+  int nCell;                      /* Value of 'ncell' column */
+  int nPayload;                   /* Value of 'payload' column */
+  int nUnused;                    /* Value of 'unused' column */
+  int nMxPayload;                 /* Value of 'mx_payload' column */
+  i64 iOffset;                    /* Value of 'pgOffset' column */
+  int szPage;                     /* Value of 'pgSize' column */
+};
+
+struct StatTable {
+  sqlite3_vtab base;
+  sqlite3 *db;
+  int iDb;                        /* Index of database to analyze */
+};
+
+#ifndef get2byte
+# define get2byte(x)   ((x)[0]<<8 | (x)[1])
+#endif
+
+/*
+** Connect to or create a statvfs virtual table.
+*/
+static int statConnect(
+  sqlite3 *db,
+  void *pAux,
+  int argc, const char *const*argv,
+  sqlite3_vtab **ppVtab,
+  char **pzErr
+){
+  StatTable *pTab = 0;
+  int rc = SQLITE_OK;
+  int iDb;
+
+  if( argc>=4 ){
+    iDb = sqlite3FindDbName(db, argv[3]);
+    if( iDb<0 ){
+      *pzErr = sqlite3_mprintf("no such database: %s", argv[3]);
+      return SQLITE_ERROR;
+    }
+  }else{
+    iDb = 0;
+  }
+  rc = sqlite3_declare_vtab(db, VTAB_SCHEMA);
+  if( rc==SQLITE_OK ){
+    pTab = (StatTable *)sqlite3_malloc64(sizeof(StatTable));
+    if( pTab==0 ) rc = SQLITE_NOMEM;
+  }
+
+  assert( rc==SQLITE_OK || pTab==0 );
+  if( rc==SQLITE_OK ){
+    memset(pTab, 0, sizeof(StatTable));
+    pTab->db = db;
+    pTab->iDb = iDb;
+  }
+
+  *ppVtab = (sqlite3_vtab*)pTab;
+  return rc;
+}
+
+/*
+** Disconnect from or destroy a statvfs virtual table.
+*/
+static int statDisconnect(sqlite3_vtab *pVtab){
+  sqlite3_free(pVtab);
+  return SQLITE_OK;
+}
+
+/*
+** There is no "best-index". This virtual table always does a linear
+** scan of the binary VFS log file.
+*/
+static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
+
+  /* Records are always returned in ascending order of (name, path). 
+  ** If this will satisfy the client, set the orderByConsumed flag so that 
+  ** SQLite does not do an external sort.
+  */
+  if( ( pIdxInfo->nOrderBy==1
+     && pIdxInfo->aOrderBy[0].iColumn==0
+     && pIdxInfo->aOrderBy[0].desc==0
+     ) ||
+      ( pIdxInfo->nOrderBy==2
+     && pIdxInfo->aOrderBy[0].iColumn==0
+     && pIdxInfo->aOrderBy[0].desc==0
+     && pIdxInfo->aOrderBy[1].iColumn==1
+     && pIdxInfo->aOrderBy[1].desc==0
+     )
+  ){
+    pIdxInfo->orderByConsumed = 1;
+  }
+
+  pIdxInfo->estimatedCost = 10.0;
+  return SQLITE_OK;
+}
+
+/*
+** Open a new statvfs cursor.
+*/
+static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
+  StatTable *pTab = (StatTable *)pVTab;
+  StatCursor *pCsr;
+  int rc;
+
+  pCsr = (StatCursor *)sqlite3_malloc64(sizeof(StatCursor));
+  if( pCsr==0 ){
+    rc = SQLITE_NOMEM;
+  }else{
+    char *zSql;
+    memset(pCsr, 0, sizeof(StatCursor));
+    pCsr->base.pVtab = pVTab;
+
+    zSql = sqlite3_mprintf(
+        "SELECT 'sqlite_master' AS name, 1 AS rootpage, 'table' AS type"
+        "  UNION ALL  "
+        "SELECT name, rootpage, type"
+        "  FROM \"%w\".sqlite_master WHERE rootpage!=0"
+        "  ORDER BY name", pTab->db->aDb[pTab->iDb].zName);
+    if( zSql==0 ){
+      rc = SQLITE_NOMEM;
+    }else{
+      rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
+      sqlite3_free(zSql);
+    }
+    if( rc!=SQLITE_OK ){
+      sqlite3_free(pCsr);
+      pCsr = 0;
+    }
+  }
+
+  *ppCursor = (sqlite3_vtab_cursor *)pCsr;
+  return rc;
+}
+
+static void statClearPage(StatPage *p){
+  int i;
+  if( p->aCell ){
+    for(i=0; i<p->nCell; i++){
+      sqlite3_free(p->aCell[i].aOvfl);
+    }
+    sqlite3_free(p->aCell);
+  }
+  sqlite3PagerUnref(p->pPg);
+  sqlite3_free(p->zPath);
+  memset(p, 0, sizeof(StatPage));
+}
+
+static void statResetCsr(StatCursor *pCsr){
+  int i;
+  sqlite3_reset(pCsr->pStmt);
+  for(i=0; i<ArraySize(pCsr->aPage); i++){
+    statClearPage(&pCsr->aPage[i]);
+  }
+  pCsr->iPage = 0;
+  sqlite3_free(pCsr->zPath);
+  pCsr->zPath = 0;
+}
+
+/*
+** Close a statvfs cursor.
+*/
+static int statClose(sqlite3_vtab_cursor *pCursor){
+  StatCursor *pCsr = (StatCursor *)pCursor;
+  statResetCsr(pCsr);
+  sqlite3_finalize(pCsr->pStmt);
+  sqlite3_free(pCsr);
+  return SQLITE_OK;
+}
+
+static void getLocalPayload(
+  int nUsable,                    /* Usable bytes per page */
+  u8 flags,                       /* Page flags */
+  int nTotal,                     /* Total record (payload) size */
+  int *pnLocal                    /* OUT: Bytes stored locally */
+){
+  int nLocal;
+  int nMinLocal;
+  int nMaxLocal;
+ 
+  if( flags==0x0D ){              /* Table leaf node */
+    nMinLocal = (nUsable - 12) * 32 / 255 - 23;
+    nMaxLocal = nUsable - 35;
+  }else{                          /* Index interior and leaf nodes */
+    nMinLocal = (nUsable - 12) * 32 / 255 - 23;
+    nMaxLocal = (nUsable - 12) * 64 / 255 - 23;
+  }
+
+  nLocal = nMinLocal + (nTotal - nMinLocal) % (nUsable - 4);
+  if( nLocal>nMaxLocal ) nLocal = nMinLocal;
+  *pnLocal = nLocal;
+}
+
+static int statDecodePage(Btree *pBt, StatPage *p){
+  int nUnused;
+  int iOff;
+  int nHdr;
+  int isLeaf;
+  int szPage;
+
+  u8 *aData = sqlite3PagerGetData(p->pPg);
+  u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0];
+
+  p->flags = aHdr[0];
+  p->nCell = get2byte(&aHdr[3]);
+  p->nMxPayload = 0;
+
+  isLeaf = (p->flags==0x0A || p->flags==0x0D);
+  nHdr = 12 - isLeaf*4 + (p->iPgno==1)*100;
+
+  nUnused = get2byte(&aHdr[5]) - nHdr - 2*p->nCell;
+  nUnused += (int)aHdr[7];
+  iOff = get2byte(&aHdr[1]);
+  while( iOff ){
+    nUnused += get2byte(&aData[iOff+2]);
+    iOff = get2byte(&aData[iOff]);
+  }
+  p->nUnused = nUnused;
+  p->iRightChildPg = isLeaf ? 0 : sqlite3Get4byte(&aHdr[8]);
+  szPage = sqlite3BtreeGetPageSize(pBt);
+
+  if( p->nCell ){
+    int i;                        /* Used to iterate through cells */
+    int nUsable;                  /* Usable bytes per page */
+
+    sqlite3BtreeEnter(pBt);
+    nUsable = szPage - sqlite3BtreeGetReserveNoMutex(pBt);
+    sqlite3BtreeLeave(pBt);
+    p->aCell = sqlite3_malloc64((p->nCell+1) * sizeof(StatCell));
+    if( p->aCell==0 ) return SQLITE_NOMEM;
+    memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell));
+
+    for(i=0; i<p->nCell; i++){
+      StatCell *pCell = &p->aCell[i];
+
+      iOff = get2byte(&aData[nHdr+i*2]);
+      if( !isLeaf ){
+        pCell->iChildPg = sqlite3Get4byte(&aData[iOff]);
+        iOff += 4;
+      }
+      if( p->flags==0x05 ){
+        /* A table interior node. nPayload==0. */
+      }else{
+        u32 nPayload;             /* Bytes of payload total (local+overflow) */
+        int nLocal;               /* Bytes of payload stored locally */
+        iOff += getVarint32(&aData[iOff], nPayload);
+        if( p->flags==0x0D ){
+          u64 dummy;
+          iOff += sqlite3GetVarint(&aData[iOff], &dummy);
+        }
+        if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload;
+        getLocalPayload(nUsable, p->flags, nPayload, &nLocal);
+        pCell->nLocal = nLocal;
+        assert( nLocal>=0 );
+        assert( nPayload>=(u32)nLocal );
+        assert( nLocal<=(nUsable-35) );
+        if( nPayload>(u32)nLocal ){
+          int j;
+          int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
+          pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
+          pCell->nOvfl = nOvfl;
+          pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
+          if( pCell->aOvfl==0 ) return SQLITE_NOMEM;
+          pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
+          for(j=1; j<nOvfl; j++){
+            int rc;
+            u32 iPrev = pCell->aOvfl[j-1];
+            DbPage *pPg = 0;
+            rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPrev, &pPg);
+            if( rc!=SQLITE_OK ){
+              assert( pPg==0 );
+              return rc;
+            } 
+            pCell->aOvfl[j] = sqlite3Get4byte(sqlite3PagerGetData(pPg));
+            sqlite3PagerUnref(pPg);
+          }
+        }
+      }
+    }
+  }
+
+  return SQLITE_OK;
+}
+
+/*
+** Populate the pCsr->iOffset and pCsr->szPage member variables. Based on
+** the current value of pCsr->iPageno.
+*/
+static void statSizeAndOffset(StatCursor *pCsr){
+  StatTable *pTab = (StatTable *)((sqlite3_vtab_cursor *)pCsr)->pVtab;
+  Btree *pBt = pTab->db->aDb[pTab->iDb].pBt;
+  Pager *pPager = sqlite3BtreePager(pBt);
+  sqlite3_file *fd;
+  sqlite3_int64 x[2];
+
+  /* The default page size and offset */
+  pCsr->szPage = sqlite3BtreeGetPageSize(pBt);
+  pCsr->iOffset = (i64)pCsr->szPage * (pCsr->iPageno - 1);
+
+  /* If connected to a ZIPVFS backend, override the page size and
+  ** offset with actual values obtained from ZIPVFS.
+  */
+  fd = sqlite3PagerFile(pPager);
+  x[0] = pCsr->iPageno;
+  if( fd->pMethods!=0 && sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){
+    pCsr->iOffset = x[0];
+    pCsr->szPage = (int)x[1];
+  }
+}
+
+/*
+** Move a statvfs cursor to the next entry in the file.
+*/
+static int statNext(sqlite3_vtab_cursor *pCursor){
+  int rc;
+  int nPayload;
+  char *z;
+  StatCursor *pCsr = (StatCursor *)pCursor;
+  StatTable *pTab = (StatTable *)pCursor->pVtab;
+  Btree *pBt = pTab->db->aDb[pTab->iDb].pBt;
+  Pager *pPager = sqlite3BtreePager(pBt);
+
+  sqlite3_free(pCsr->zPath);
+  pCsr->zPath = 0;
+
+statNextRestart:
+  if( pCsr->aPage[0].pPg==0 ){
+    rc = sqlite3_step(pCsr->pStmt);
+    if( rc==SQLITE_ROW ){
+      int nPage;
+      u32 iRoot = (u32)sqlite3_column_int64(pCsr->pStmt, 1);
+      sqlite3PagerPagecount(pPager, &nPage);
+      if( nPage==0 ){
+        pCsr->isEof = 1;
+        return sqlite3_reset(pCsr->pStmt);
+      }
+      rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg);
+      pCsr->aPage[0].iPgno = iRoot;
+      pCsr->aPage[0].iCell = 0;
+      pCsr->aPage[0].zPath = z = sqlite3_mprintf("/");
+      pCsr->iPage = 0;
+      if( z==0 ) rc = SQLITE_NOMEM;
+    }else{
+      pCsr->isEof = 1;
+      return sqlite3_reset(pCsr->pStmt);
+    }
+  }else{
+
+    /* Page p itself has already been visited. */
+    StatPage *p = &pCsr->aPage[pCsr->iPage];
+
+    while( p->iCell<p->nCell ){
+      StatCell *pCell = &p->aCell[p->iCell];
+      if( pCell->iOvfl<pCell->nOvfl ){
+        int nUsable;
+        sqlite3BtreeEnter(pBt);
+        nUsable = sqlite3BtreeGetPageSize(pBt) - 
+                        sqlite3BtreeGetReserveNoMutex(pBt);
+        sqlite3BtreeLeave(pBt);
+        pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0);
+        pCsr->iPageno = pCell->aOvfl[pCell->iOvfl];
+        pCsr->zPagetype = "overflow";
+        pCsr->nCell = 0;
+        pCsr->nMxPayload = 0;
+        pCsr->zPath = z = sqlite3_mprintf(
+            "%s%.3x+%.6x", p->zPath, p->iCell, pCell->iOvfl
+        );
+        if( pCell->iOvfl<pCell->nOvfl-1 ){
+          pCsr->nUnused = 0;
+          pCsr->nPayload = nUsable - 4;
+        }else{
+          pCsr->nPayload = pCell->nLastOvfl;
+          pCsr->nUnused = nUsable - 4 - pCsr->nPayload;
+        }
+        pCell->iOvfl++;
+        statSizeAndOffset(pCsr);
+        return z==0 ? SQLITE_NOMEM : SQLITE_OK;
+      }
+      if( p->iRightChildPg ) break;
+      p->iCell++;
+    }
+
+    if( !p->iRightChildPg || p->iCell>p->nCell ){
+      statClearPage(p);
+      if( pCsr->iPage==0 ) return statNext(pCursor);
+      pCsr->iPage--;
+      goto statNextRestart; /* Tail recursion */
+    }
+    pCsr->iPage++;
+    assert( p==&pCsr->aPage[pCsr->iPage-1] );
+
+    if( p->iCell==p->nCell ){
+      p[1].iPgno = p->iRightChildPg;
+    }else{
+      p[1].iPgno = p->aCell[p->iCell].iChildPg;
+    }
+    rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg);
+    p[1].iCell = 0;
+    p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
+    p->iCell++;
+    if( z==0 ) rc = SQLITE_NOMEM;
+  }
+
+
+  /* Populate the StatCursor fields with the values to be returned
+  ** by the xColumn() and xRowid() methods.
+  */
+  if( rc==SQLITE_OK ){
+    int i;
+    StatPage *p = &pCsr->aPage[pCsr->iPage];
+    pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0);
+    pCsr->iPageno = p->iPgno;
+
+    rc = statDecodePage(pBt, p);
+    if( rc==SQLITE_OK ){
+      statSizeAndOffset(pCsr);
+
+      switch( p->flags ){
+        case 0x05:             /* table internal */
+        case 0x02:             /* index internal */
+          pCsr->zPagetype = "internal";
+          break;
+        case 0x0D:             /* table leaf */
+        case 0x0A:             /* index leaf */
+          pCsr->zPagetype = "leaf";
+          break;
+        default:
+          pCsr->zPagetype = "corrupted";
+          break;
+      }
+      pCsr->nCell = p->nCell;
+      pCsr->nUnused = p->nUnused;
+      pCsr->nMxPayload = p->nMxPayload;
+      pCsr->zPath = z = sqlite3_mprintf("%s", p->zPath);
+      if( z==0 ) rc = SQLITE_NOMEM;
+      nPayload = 0;
+      for(i=0; i<p->nCell; i++){
+        nPayload += p->aCell[i].nLocal;
+      }
+      pCsr->nPayload = nPayload;
+    }
+  }
+
+  return rc;
+}
+
+static int statEof(sqlite3_vtab_cursor *pCursor){
+  StatCursor *pCsr = (StatCursor *)pCursor;
+  return pCsr->isEof;
+}
+
+static int statFilter(
+  sqlite3_vtab_cursor *pCursor, 
+  int idxNum, const char *idxStr,
+  int argc, sqlite3_value **argv
+){
+  StatCursor *pCsr = (StatCursor *)pCursor;
+
+  statResetCsr(pCsr);
+  return statNext(pCursor);
+}
+
+static int statColumn(
+  sqlite3_vtab_cursor *pCursor, 
+  sqlite3_context *ctx, 
+  int i
+){
+  StatCursor *pCsr = (StatCursor *)pCursor;
+  switch( i ){
+    case 0:            /* name */
+      sqlite3_result_text(ctx, pCsr->zName, -1, SQLITE_TRANSIENT);
+      break;
+    case 1:            /* path */
+      sqlite3_result_text(ctx, pCsr->zPath, -1, SQLITE_TRANSIENT);
+      break;
+    case 2:            /* pageno */
+      sqlite3_result_int64(ctx, pCsr->iPageno);
+      break;
+    case 3:            /* pagetype */
+      sqlite3_result_text(ctx, pCsr->zPagetype, -1, SQLITE_STATIC);
+      break;
+    case 4:            /* ncell */
+      sqlite3_result_int(ctx, pCsr->nCell);
+      break;
+    case 5:            /* payload */
+      sqlite3_result_int(ctx, pCsr->nPayload);
+      break;
+    case 6:            /* unused */
+      sqlite3_result_int(ctx, pCsr->nUnused);
+      break;
+    case 7:            /* mx_payload */
+      sqlite3_result_int(ctx, pCsr->nMxPayload);
+      break;
+    case 8:            /* pgoffset */
+      sqlite3_result_int64(ctx, pCsr->iOffset);
+      break;
+    default:           /* pgsize */
+      assert( i==9 );
+      sqlite3_result_int(ctx, pCsr->szPage);
+      break;
+  }
+  return SQLITE_OK;
+}
+
+static int statRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
+  StatCursor *pCsr = (StatCursor *)pCursor;
+  *pRowid = pCsr->iPageno;
+  return SQLITE_OK;
+}
+
+/*
+** Invoke this routine to register the "dbstat" virtual table module
+*/
+SQLITE_API int SQLITE_STDCALL sqlite3_dbstat_register(sqlite3 *db){
+  static sqlite3_module dbstat_module = {
+    0,                            /* iVersion */
+    statConnect,                  /* xCreate */
+    statConnect,                  /* xConnect */
+    statBestIndex,                /* xBestIndex */
+    statDisconnect,               /* xDisconnect */
+    statDisconnect,               /* xDestroy */
+    statOpen,                     /* xOpen - open a cursor */
+    statClose,                    /* xClose - close a cursor */
+    statFilter,                   /* xFilter - configure scan constraints */
+    statNext,                     /* xNext - advance a cursor */
+    statEof,                      /* xEof - check for end of scan */
+    statColumn,                   /* xColumn - read data */
+    statRowid,                    /* xRowid - read data */
+    0,                            /* xUpdate */
+    0,                            /* xBegin */
+    0,                            /* xSync */
+    0,                            /* xCommit */
+    0,                            /* xRollback */
+    0,                            /* xFindMethod */
+    0,                            /* xRename */
+  };
+  return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
+}
+#endif /* SQLITE_ENABLE_DBSTAT_VTAB */
+
+/************** End of dbstat.c **********************************************/
diff --git a/libgda/sqlite/sqlite-src/sqlite3.h b/libgda/sqlite/sqlite-src/sqlite3.h
index 9879f80..d43b63c 100644
--- a/libgda/sqlite/sqlite-src/sqlite3.h
+++ b/libgda/sqlite/sqlite-src/sqlite3.h
@@ -43,21 +43,25 @@ extern "C" {
 
 
 /*
-** Add the ability to override 'extern'
+** Provide the ability to override linkage features of the interface.
 */
 #ifndef SQLITE_EXTERN
 # define SQLITE_EXTERN extern
 #endif
-
 #ifndef SQLITE_API
 # define SQLITE_API
 #endif
-
+#ifndef SQLITE_CDECL
+# define SQLITE_CDECL
+#endif
+#ifndef SQLITE_STDCALL
+# define SQLITE_STDCALL
+#endif
 
 /*
 ** These no-op macros are used in front of interfaces to mark those
 ** interfaces as either deprecated or experimental.  New applications
-** should not use deprecated interfaces - they are support for backwards
+** should not use deprecated interfaces - they are supported for backwards
 ** compatibility only.  Application writers should be aware that
 ** experimental interfaces are subject to change in point releases.
 **
@@ -107,9 +111,9 @@ extern "C" {
 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
 ** [sqlite_version()] and [sqlite_source_id()].
 */
-#define SQLITE_VERSION        "3.8.6"
-#define SQLITE_VERSION_NUMBER 3008006
-#define SQLITE_SOURCE_ID      "2014-08-15 11:46:33 9491ba7d738528f168657adb43a198238abde19e"
+#define SQLITE_VERSION        "3.8.10.2"
+#define SQLITE_VERSION_NUMBER 3008010
+#define SQLITE_SOURCE_ID      "2015-05-20 18:17:19 2ef4f3a5b1d1d0c4338f8243d40a2452cc1f7fe4"
 
 /*
 ** CAPI3REF: Run-Time Library Version Numbers
@@ -142,9 +146,9 @@ extern "C" {
 ** See also: [sqlite_version()] and [sqlite_source_id()].
 */
 SQLITE_API SQLITE_EXTERN const char sqlite3_version[];
-SQLITE_API const char *sqlite3_libversion(void);
-SQLITE_API const char *sqlite3_sourceid(void);
-SQLITE_API int sqlite3_libversion_number(void);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_libversion(void);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_sourceid(void);
+SQLITE_API int SQLITE_STDCALL sqlite3_libversion_number(void);
 
 /*
 ** CAPI3REF: Run-Time Library Compilation Options Diagnostics
@@ -169,8 +173,8 @@ SQLITE_API int sqlite3_libversion_number(void);
 ** [sqlite_compileoption_get()] and the [compile_options pragma].
 */
 #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
-SQLITE_API int sqlite3_compileoption_used(const char *zOptName);
-SQLITE_API const char *sqlite3_compileoption_get(int N);
+SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N);
 #endif
 
 /*
@@ -201,7 +205,7 @@ SQLITE_API const char *sqlite3_compileoption_get(int N);
 ** SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but
 ** can be fully or partially disabled using a call to [sqlite3_config()]
 ** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD],
-** or [SQLITE_CONFIG_MUTEX].  ^(The return value of the
+** or [SQLITE_CONFIG_SERIALIZED].  ^(The return value of the
 ** sqlite3_threadsafe() function shows only the compile-time setting of
 ** thread safety, not any run-time changes to that setting made by
 ** sqlite3_config(). In other words, the return value from sqlite3_threadsafe()
@@ -209,7 +213,7 @@ SQLITE_API const char *sqlite3_compileoption_get(int N);
 **
 ** See the [threading mode] documentation for additional information.
 */
-SQLITE_API int sqlite3_threadsafe(void);
+SQLITE_API int SQLITE_STDCALL sqlite3_threadsafe(void);
 
 /*
 ** CAPI3REF: Database Connection Handle
@@ -266,6 +270,7 @@ typedef sqlite_uint64 sqlite3_uint64;
 
 /*
 ** CAPI3REF: Closing A Database Connection
+** DESTRUCTOR: sqlite3
 **
 ** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors
 ** for the [sqlite3] object.
@@ -305,8 +310,8 @@ typedef sqlite_uint64 sqlite3_uint64;
 ** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer
 ** argument is a harmless no-op.
 */
-SQLITE_API int sqlite3_close(sqlite3*);
-SQLITE_API int sqlite3_close_v2(sqlite3*);
+SQLITE_API int SQLITE_STDCALL sqlite3_close(sqlite3*);
+SQLITE_API int SQLITE_STDCALL sqlite3_close_v2(sqlite3*);
 
 /*
 ** The type for a callback function.
@@ -317,6 +322,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
 
 /*
 ** CAPI3REF: One-Step Query Execution Interface
+** METHOD: sqlite3
 **
 ** The sqlite3_exec() interface is a convenience wrapper around
 ** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()],
@@ -376,7 +382,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**);
 **      the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
 ** </ul>
 */
-SQLITE_API int sqlite3_exec(
+SQLITE_API int SQLITE_STDCALL sqlite3_exec(
   sqlite3*,                                  /* An open database */
   const char *sql,                           /* SQL to be evaluated */
   int (*callback)(void*,int,char**,char**),  /* Callback function */
@@ -497,6 +503,7 @@ SQLITE_API int sqlite3_exec(
 #define SQLITE_NOTICE_RECOVER_WAL      (SQLITE_NOTICE | (1<<8))
 #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
 #define SQLITE_WARNING_AUTOINDEX       (SQLITE_WARNING | (1<<8))
+#define SQLITE_AUTH_USER               (SQLITE_AUTH | (1<<8))
 
 /*
 ** CAPI3REF: Flags For File Open Operations
@@ -755,14 +762,16 @@ struct sqlite3_io_methods {
 ** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()]
 ** interface.
 **
+** <ul>
+** <li>[[SQLITE_FCNTL_LOCKSTATE]]
 ** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging.  This
 ** opcode causes the xFileControl method to write the current state of
 ** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED],
 ** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE])
 ** into an integer that the pArg argument points to. This capability
-** is used during testing and only needs to be supported when SQLITE_TEST
-** is defined.
-** <ul>
+** is used during testing and is only available when the SQLITE_TEST
+** compile-time option is used.
+**
 ** <li>[[SQLITE_FCNTL_SIZE_HINT]]
 ** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS
 ** layer a hint of how large the database file will grow to be during the
@@ -887,7 +896,9 @@ struct sqlite3_io_methods {
 ** [PRAGMA] processing continues.  ^If the [SQLITE_FCNTL_PRAGMA]
 ** file control returns [SQLITE_OK], then the parser assumes that the
 ** VFS has handled the PRAGMA itself and the parser generates a no-op
-** prepared statement.  ^If the [SQLITE_FCNTL_PRAGMA] file control returns
+** prepared statement if result string is NULL, or that returns a copy
+** of the result string if the string is non-NULL.
+** ^If the [SQLITE_FCNTL_PRAGMA] file control returns
 ** any result code other than [SQLITE_OK] or [SQLITE_NOTFOUND], that means
 ** that the VFS encountered an error while handling the [PRAGMA] and the
 ** compilation of the PRAGMA fails with an error.  ^The [SQLITE_FCNTL_PRAGMA]
@@ -945,12 +956,19 @@ struct sqlite3_io_methods {
 ** pointed to by the pArg argument.  This capability is used during testing
 ** and only needs to be supported when SQLITE_TEST is defined.
 **
+** <li>[[SQLITE_FCNTL_WAL_BLOCK]]
+** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
+** be advantageous to block on the next WAL lock if the lock is not immediately
+** available.  The WAL subsystem issues this signal during rare
+** circumstances in order to fix a problem with priority inversion.
+** Applications should <em>not</em> use this file-control.
+**
 ** </ul>
 */
 #define SQLITE_FCNTL_LOCKSTATE               1
-#define SQLITE_GET_LOCKPROXYFILE             2
-#define SQLITE_SET_LOCKPROXYFILE             3
-#define SQLITE_LAST_ERRNO                    4
+#define SQLITE_FCNTL_GET_LOCKPROXYFILE       2
+#define SQLITE_FCNTL_SET_LOCKPROXYFILE       3
+#define SQLITE_FCNTL_LAST_ERRNO              4
 #define SQLITE_FCNTL_SIZE_HINT               5
 #define SQLITE_FCNTL_CHUNK_SIZE              6
 #define SQLITE_FCNTL_FILE_POINTER            7
@@ -969,6 +987,13 @@ struct sqlite3_io_methods {
 #define SQLITE_FCNTL_SYNC                   21
 #define SQLITE_FCNTL_COMMIT_PHASETWO        22
 #define SQLITE_FCNTL_WIN32_SET_HANDLE       23
+#define SQLITE_FCNTL_WAL_BLOCK              24
+
+/* deprecated names */
+#define SQLITE_GET_LOCKPROXYFILE      SQLITE_FCNTL_GET_LOCKPROXYFILE
+#define SQLITE_SET_LOCKPROXYFILE      SQLITE_FCNTL_SET_LOCKPROXYFILE
+#define SQLITE_LAST_ERRNO             SQLITE_FCNTL_LAST_ERRNO
+
 
 /*
 ** CAPI3REF: Mutex Handle
@@ -1220,7 +1245,7 @@ struct sqlite3_vfs {
 ** </ul>
 **
 ** When unlocking, the same SHARED or EXCLUSIVE flag must be supplied as
-** was given no the corresponding lock.  
+** was given on the corresponding lock.  
 **
 ** The xShmLock method can transition between unlocked and SHARED or
 ** between unlocked and EXCLUSIVE.  It cannot transition between SHARED
@@ -1317,10 +1342,10 @@ struct sqlite3_vfs {
 ** must return [SQLITE_OK] on success and some other [error code] upon
 ** failure.
 */
-SQLITE_API int sqlite3_initialize(void);
-SQLITE_API int sqlite3_shutdown(void);
-SQLITE_API int sqlite3_os_init(void);
-SQLITE_API int sqlite3_os_end(void);
+SQLITE_API int SQLITE_STDCALL sqlite3_initialize(void);
+SQLITE_API int SQLITE_STDCALL sqlite3_shutdown(void);
+SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void);
+SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void);
 
 /*
 ** CAPI3REF: Configuring The SQLite Library
@@ -1351,10 +1376,11 @@ SQLITE_API int sqlite3_os_end(void);
 ** ^If the option is unknown or SQLite is unable to set the option
 ** then this routine returns a non-zero [error code].
 */
-SQLITE_API int sqlite3_config(int, ...);
+SQLITE_API int SQLITE_CDECL sqlite3_config(int, ...);
 
 /*
 ** CAPI3REF: Configure database connections
+** METHOD: sqlite3
 **
 ** The sqlite3_db_config() interface is used to make configuration
 ** changes to a [database connection].  The interface is similar to
@@ -1369,7 +1395,7 @@ SQLITE_API int sqlite3_config(int, ...);
 ** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if
 ** the call is considered successful.
 */
-SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...);
+SQLITE_API int SQLITE_CDECL sqlite3_db_config(sqlite3*, int op, ...);
 
 /*
 ** CAPI3REF: Memory Allocation Routines
@@ -1503,31 +1529,33 @@ struct sqlite3_mem_methods {
 ** SQLITE_CONFIG_SERIALIZED configuration option.</dd>
 **
 ** [[SQLITE_CONFIG_MALLOC]] <dt>SQLITE_CONFIG_MALLOC</dt>
-** <dd> ^(This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mem_methods] structure.  The argument specifies
+** <dd> ^(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.)^ ^SQLite makes
 ** its own private copy of the content of the [sqlite3_mem_methods] structure
 ** before the [sqlite3_config()] call returns.</dd>
 **
 ** [[SQLITE_CONFIG_GETMALLOC]] <dt>SQLITE_CONFIG_GETMALLOC</dt>
-** <dd> ^(This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mem_methods] structure.  The [sqlite3_mem_methods]
+** <dd> ^(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.)^
 ** This option can be used to overload the default memory allocation
 ** routines with a wrapper that simulations memory allocation failure or
 ** tracks memory usage, for example. </dd>
 **
 ** [[SQLITE_CONFIG_MEMSTATUS]] <dt>SQLITE_CONFIG_MEMSTATUS</dt>
-** <dd> ^This option takes single argument of type int, interpreted as a 
-** boolean, which enables or disables the collection of memory allocation 
-** statistics. ^(When memory allocation statistics are disabled, the 
-** following SQLite interfaces become non-operational:
+** <dd> ^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. ^(When memory allocation statistics are
+** disabled, the following SQLite interfaces become non-operational:
 **   <ul>
 **   <li> [sqlite3_memory_used()]
 **   <li> [sqlite3_memory_highwater()]
 **   <li> [sqlite3_soft_heap_limit64()]
-**   <li> [sqlite3_status()]
+**   <li> [sqlite3_status64()]
 **   </ul>)^
 ** ^Memory allocation statistics are enabled by default unless SQLite is
 ** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory
@@ -1535,53 +1563,67 @@ struct sqlite3_mem_methods {
 ** </dd>
 **
 ** [[SQLITE_CONFIG_SCRATCH]] <dt>SQLITE_CONFIG_SCRATCH</dt>
-** <dd> ^This option specifies a static memory buffer that SQLite can use for
-** scratch memory.  There are three arguments:  A pointer an 8-byte
+** <dd> ^The SQLITE_CONFIG_SCRATCH option specifies a static memory buffer
+** that SQLite can use for scratch memory.  ^(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).  The sz
-** argument must be a multiple of 16.
+** and the maximum number of scratch allocations (N).)^
 ** The first argument must be a pointer to an 8-byte aligned buffer
 ** of at least sz*N bytes of memory.
-** ^SQLite will use no more than two scratch buffers per thread.  So
-** N should be set to twice the expected maximum number of threads.
-** ^SQLite will never require a scratch buffer that is more than 6
-** times the database page size. ^If SQLite needs needs additional
+** ^SQLite will not use more than one scratch buffers per thread.
+** ^SQLite will never request a scratch buffer that is more than 6
+** times the database page size.
+** ^If SQLite needs needs additional
 ** scratch memory beyond what is provided by this configuration option, then 
-** [sqlite3_malloc()] will be used to obtain the memory needed.</dd>
+** [sqlite3_malloc()] will be used to obtain the memory needed.<p>
+** ^When the application provides any amount of scratch memory using
+** SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary large
+** [sqlite3_malloc|heap allocations].
+** This can help [Robson proof|prevent memory allocation failures] due to heap
+** fragmentation in low-memory embedded systems.
+** </dd>
 **
 ** [[SQLITE_CONFIG_PAGECACHE]] <dt>SQLITE_CONFIG_PAGECACHE</dt>
-** <dd> ^This option specifies a static memory buffer that SQLite can use for
-** the database page cache with the default page cache implementation.  
+** <dd> ^The SQLITE_CONFIG_PAGECACHE option specifies a static memory buffer
+** that SQLite can use for the database page cache with the default page
+** cache implementation.  
 ** This configuration should not be used if an application-define page
-** cache implementation is loaded using the SQLITE_CONFIG_PCACHE2 option.
-** There are three arguments to this option: A pointer to 8-byte aligned
+** cache implementation is loaded using the [SQLITE_CONFIG_PCACHE2]
+** configuration option.
+** ^There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to
+** 8-byte aligned
 ** memory, the size of each page buffer (sz), and the number of pages (N).
 ** The sz argument should be the size of the largest database page
-** (a power of two between 512 and 32768) plus a little extra for each
-** page header.  ^The page header size is 20 to 40 bytes depending on
-** the host architecture.  ^It is harmless, apart from the wasted memory,
-** to make sz a little too large.  The first
-** argument should point to an allocation of at least sz*N bytes of memory.
+** (a power of two between 512 and 65536) plus some extra bytes for each
+** page header.  ^The number of extra bytes needed by the page header
+** can be determined using the [SQLITE_CONFIG_PCACHE_HDRSZ] option 
+** to [sqlite3_config()].
+** ^It is harmless, apart from the wasted memory,
+** for the sz parameter to be larger than necessary.  The first
+** argument should pointer to an 8-byte aligned block of memory that
+** is at least sz*N bytes of memory, otherwise subsequent behavior is
+** undefined.
 ** ^SQLite will use the memory provided by the first argument to satisfy its
 ** memory needs for the first N pages that it adds to cache.  ^If additional
 ** page cache memory is needed beyond what is provided by this option, then
-** SQLite goes to [sqlite3_malloc()] for the additional storage space.
-** The pointer in the first argument must
-** be aligned to an 8-byte boundary or subsequent behavior of SQLite
-** will be undefined.</dd>
+** SQLite goes to [sqlite3_malloc()] for the additional storage space.</dd>
 **
 ** [[SQLITE_CONFIG_HEAP]] <dt>SQLITE_CONFIG_HEAP</dt>
-** <dd> ^This option specifies a static memory buffer that SQLite will use
-** for all of its dynamic memory allocation needs beyond those provided
-** for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE].
-** There are three arguments: An 8-byte aligned pointer to the memory,
+** <dd> ^The SQLITE_CONFIG_HEAP option specifies a static memory buffer 
+** that SQLite will use for all of its dynamic memory allocation needs
+** beyond those provided for by [SQLITE_CONFIG_SCRATCH] and
+** [SQLITE_CONFIG_PAGECACHE].
+** ^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.
+** ^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.
 ** ^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].  ^If the
-** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
-** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
+** memory pointer is not NULL then the alternative memory
 ** allocator is engaged to handle all of SQLites memory allocation needs.
 ** The first pointer (the memory pointer) must be aligned to an 8-byte
 ** boundary or subsequent behavior of SQLite will be undefined.
@@ -1589,11 +1631,11 @@ struct sqlite3_mem_methods {
 ** for the minimum allocation size are 2**5 through 2**8.</dd>
 **
 ** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
-** <dd> ^(This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mutex_methods] structure.  The argument specifies
-** alternative low-level mutex routines to be used in place
-** the mutex routines built into SQLite.)^  ^SQLite makes a copy of the
-** content of the [sqlite3_mutex_methods] structure before the call to
+** <dd> ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a
+** pointer to an instance of the [sqlite3_mutex_methods] structure.
+** The argument specifies alternative low-level mutex routines to be used
+** in place the mutex routines built into SQLite.)^  ^SQLite makes a copy of
+** the content of the [sqlite3_mutex_methods] structure before the call to
 ** [sqlite3_config()] returns. ^If SQLite is compiled with
 ** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then
 ** the entire mutexing subsystem is omitted from the build and hence calls to
@@ -1601,8 +1643,8 @@ struct sqlite3_mem_methods {
 ** return [SQLITE_ERROR].</dd>
 **
 ** [[SQLITE_CONFIG_GETMUTEX]] <dt>SQLITE_CONFIG_GETMUTEX</dt>
-** <dd> ^(This option takes a single argument which is a pointer to an
-** instance of the [sqlite3_mutex_methods] structure.  The
+** <dd> ^(The SQLITE_CONFIG_GETMUTEX option takes a single argument which
+** is a pointer to an instance of the [sqlite3_mutex_methods] structure.  The
 ** [sqlite3_mutex_methods]
 ** structure is filled with the currently defined mutex routines.)^
 ** This option can be used to overload the default mutex allocation
@@ -1614,25 +1656,25 @@ struct sqlite3_mem_methods {
 ** return [SQLITE_ERROR].</dd>
 **
 ** [[SQLITE_CONFIG_LOOKASIDE]] <dt>SQLITE_CONFIG_LOOKASIDE</dt>
-** <dd> ^(This option takes two arguments that determine the default
-** memory allocation for the lookaside memory allocator on each
-** [database connection].  The first argument is the
+** <dd> ^(The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine
+** the default size of lookaside memory on each [database connection].
+** The first argument is the
 ** size of each lookaside buffer slot and the second is the number of
-** slots allocated to each database connection.)^  ^(This option sets the
-** <i>default</i> lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE]
-** verb to [sqlite3_db_config()] can be used to change the lookaside
+** slots allocated to each database connection.)^  ^(SQLITE_CONFIG_LOOKASIDE
+** sets the <i>default</i> lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE]
+** option to [sqlite3_db_config()] can be used to change the lookaside
 ** configuration on individual connections.)^ </dd>
 **
 ** [[SQLITE_CONFIG_PCACHE2]] <dt>SQLITE_CONFIG_PCACHE2</dt>
-** <dd> ^(This 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.)^  ^SQLite makes a copy of the
-** object and uses it for page cache memory allocations.</dd>
+** <dd> ^(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.)^
+** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object.</dd>
 **
 ** [[SQLITE_CONFIG_GETPCACHE2]] <dt>SQLITE_CONFIG_GETPCACHE2</dt>
-** <dd> ^(This 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.)^ </dd>
+** <dd> ^(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.)^ </dd>
 **
 ** [[SQLITE_CONFIG_LOG]] <dt>SQLITE_CONFIG_LOG</dt>
 ** <dd> The SQLITE_CONFIG_LOG option is used to configure the SQLite
@@ -1655,10 +1697,11 @@ struct sqlite3_mem_methods {
 ** function must be threadsafe. </dd>
 **
 ** [[SQLITE_CONFIG_URI]] <dt>SQLITE_CONFIG_URI
-** <dd>^(This 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.)^ ^If URI handling is globally enabled, all filenames
-** passed to [sqlite3_open()], [sqlite3_open_v2()], [sqlite3_open16()] or
+** <dd>^(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.)^ ^If URI handling is globally
+** enabled, all filenames passed to [sqlite3_open()], [sqlite3_open_v2()],
+** [sqlite3_open16()] or
 ** specified as part of [ATTACH] commands are interpreted as URIs, regardless
 ** of whether or not the [SQLITE_OPEN_URI] flag is set when the database
 ** connection is opened. ^If it is globally disabled, filenames are
@@ -1668,9 +1711,10 @@ struct sqlite3_mem_methods {
 ** [SQLITE_USE_URI] symbol defined.)^
 **
 ** [[SQLITE_CONFIG_COVERING_INDEX_SCAN]] <dt>SQLITE_CONFIG_COVERING_INDEX_SCAN
-** <dd>^This 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.  ^The default setting is determined
+** <dd>^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.
+** ^The default setting is determined
 ** by the [SQLITE_ALLOW_COVERING_INDEX_SCAN] compile-time option, or is "on"
 ** if that compile-time option is omitted.
 ** The ability to disable the use of covering indices for full table scans
@@ -1710,18 +1754,37 @@ struct sqlite3_mem_methods {
 ** ^The default setting can be overridden by each database connection using
 ** either the [PRAGMA mmap_size] command, or by using the
 ** [SQLITE_FCNTL_MMAP_SIZE] file control.  ^(The maximum allowed mmap size
-** cannot be changed at run-time.  Nor may the maximum allowed mmap size
-** exceed the compile-time maximum mmap size set by the
+** 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 either argument to this option is negative, then that argument is
 ** changed to its compile-time default.
 **
 ** [[SQLITE_CONFIG_WIN32_HEAPSIZE]]
 ** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE
-** <dd>^This option is only available if SQLite is compiled for Windows
-** with the [SQLITE_WIN32_MALLOC] pre-processor macro defined.
-** SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
+** <dd>^The SQLITE_CONFIG_WIN32_HEAPSIZE option is only available if SQLite is
+** compiled for Windows with the [SQLITE_WIN32_MALLOC] pre-processor macro
+** defined. ^SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
 ** that specifies the maximum size of the created heap.
+**
+** [[SQLITE_CONFIG_PCACHE_HDRSZ]]
+** <dt>SQLITE_CONFIG_PCACHE_HDRSZ
+** <dd>^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].
+** The amount of extra space required can change depending on the compiler,
+** target platform, and SQLite version.
+**
+** [[SQLITE_CONFIG_PMASZ]]
+** <dt>SQLITE_CONFIG_PMASZ
+** <dd>^The SQLITE_CONFIG_PMASZ option takes a single parameter which
+** is an unsigned integer and sets the "Minimum PMA Size" for the multithreaded
+** sorter to that integer.  The default minimum PMA Size is set by the
+** [SQLITE_SORTER_PMASZ] compile-time option.  New threads are launched
+** to help with sort operations when multithreaded sorting
+** is enabled (using the [PRAGMA threads] command) and the amount of content
+** to be sorted exceeds the page size times the minimum of the
+** [PRAGMA cache_size] setting and this value.
 ** </dl>
 */
 #define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
@@ -1747,6 +1810,8 @@ struct sqlite3_mem_methods {
 #define SQLITE_CONFIG_SQLLOG       21  /* xSqllog, void* */
 #define SQLITE_CONFIG_MMAP_SIZE    22  /* sqlite3_int64, sqlite3_int64 */
 #define SQLITE_CONFIG_WIN32_HEAPSIZE      23  /* int nByte */
+#define SQLITE_CONFIG_PCACHE_HDRSZ        24  /* int *psz */
+#define SQLITE_CONFIG_PMASZ               25  /* unsigned int szPma */
 
 /*
 ** CAPI3REF: Database Connection Configuration Options
@@ -1813,15 +1878,17 @@ struct sqlite3_mem_methods {
 
 /*
 ** CAPI3REF: Enable Or Disable Extended Result Codes
+** METHOD: sqlite3
 **
 ** ^The sqlite3_extended_result_codes() routine enables or disables the
 ** [extended result codes] feature of SQLite. ^The extended result
 ** codes are disabled by default for historical compatibility.
 */
-SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
+SQLITE_API int SQLITE_STDCALL sqlite3_extended_result_codes(sqlite3*, int onoff);
 
 /*
 ** CAPI3REF: Last Insert Rowid
+** METHOD: sqlite3
 **
 ** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables)
 ** has a unique 64-bit signed
@@ -1869,52 +1936,51 @@ SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
 ** unpredictable and might not equal either the old or the new
 ** last insert [rowid].
 */
-SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_last_insert_rowid(sqlite3*);
 
 /*
 ** CAPI3REF: Count The Number Of Rows Modified
+** METHOD: sqlite3
 **
-** ^This function returns the number of database rows that were changed
-** or inserted or deleted by the most recently completed SQL statement
-** on the [database connection] specified by the first parameter.
-** ^(Only changes that are directly specified by the [INSERT], [UPDATE],
-** or [DELETE] statement are counted.  Auxiliary changes caused by
-** triggers or [foreign key actions] are not counted.)^ Use the
-** [sqlite3_total_changes()] function to find the total number of changes
-** including changes caused by triggers and foreign key actions.
-**
-** ^Changes to a view that are simulated by an [INSTEAD OF trigger]
-** are not counted.  Only real table changes are counted.
-**
-** ^(A "row change" is a change to a single row of a single table
-** caused by an INSERT, DELETE, or UPDATE statement.  Rows that
-** are changed as side effects of [REPLACE] constraint resolution,
-** rollback, ABORT processing, [DROP TABLE], or by any other
-** mechanisms do not count as direct row changes.)^
-**
-** A "trigger context" is a scope of execution that begins and
-** ends with the script of a [CREATE TRIGGER | trigger]. 
-** Most SQL statements are
-** evaluated outside of any trigger.  This is the "top level"
-** trigger context.  If a trigger fires from the top level, a
-** new trigger context is entered for the duration of that one
-** trigger.  Subtriggers create subcontexts for their duration.
-**
-** ^Calling [sqlite3_exec()] or [sqlite3_step()] recursively does
-** not create a new trigger context.
-**
-** ^This function returns the number of direct row changes in the
-** most recent INSERT, UPDATE, or DELETE statement within the same
-** trigger context.
-**
-** ^Thus, when called from the top level, this function returns the
-** number of changes in the most recent INSERT, UPDATE, or DELETE
-** that also occurred at the top level.  ^(Within the body of a trigger,
-** the sqlite3_changes() interface can be called to find the number of
-** changes in the most recently completed INSERT, UPDATE, or DELETE
-** statement within the body of the same trigger.
-** However, the number returned does not include changes
-** caused by subtriggers since those have their own context.)^
+** ^This function returns the number of rows modified, inserted or
+** deleted by the most recently completed INSERT, UPDATE or DELETE
+** statement on the database connection specified by the only parameter.
+** ^Executing any other type of SQL statement does not modify the value
+** returned by this function.
+**
+** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are
+** considered - auxiliary changes caused by [CREATE TRIGGER | triggers], 
+** [foreign key actions] or [REPLACE] constraint resolution are not counted.
+** 
+** Changes to a view that are intercepted by 
+** [INSTEAD OF trigger | INSTEAD OF triggers] are not counted. ^The value 
+** returned by sqlite3_changes() immediately after an INSERT, UPDATE or 
+** DELETE statement run on a view is always zero. Only changes made to real 
+** tables are counted.
+**
+** Things are more complicated if the sqlite3_changes() function is
+** executed while a trigger program is running. This may happen if the
+** program uses the [changes() SQL function], or if some other callback
+** function invokes sqlite3_changes() directly. Essentially:
+** 
+** <ul>
+**   <li> ^(Before entering a trigger program the value returned by
+**        sqlite3_changes() function is saved. After the trigger program 
+**        has finished, the original value is restored.)^
+** 
+**   <li> ^(Within a trigger program each INSERT, UPDATE and DELETE 
+**        statement sets the value returned by sqlite3_changes() 
+**        upon completion as normal. Of course, this value will not include 
+**        any changes performed by sub-triggers, as the sqlite3_changes() 
+**        value will be saved and restored after each sub-trigger has run.)^
+** </ul>
+** 
+** ^This means that if the changes() SQL function (or similar) is used
+** by the first INSERT, UPDATE or DELETE statement within a trigger, it 
+** returns the value as set when the calling statement began executing.
+** ^If it is used by the second or subsequent such statement within a trigger 
+** program, the value returned reflects the number of rows modified by the 
+** previous INSERT, UPDATE or DELETE statement within the same trigger.
 **
 ** See also the [sqlite3_total_changes()] interface, the
 ** [count_changes pragma], and the [changes() SQL function].
@@ -1923,25 +1989,23 @@ SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*);
 ** while [sqlite3_changes()] is running then the value returned
 ** is unpredictable and not meaningful.
 */
-SQLITE_API int sqlite3_changes(sqlite3*);
+SQLITE_API int SQLITE_STDCALL sqlite3_changes(sqlite3*);
 
 /*
 ** CAPI3REF: Total Number Of Rows Modified
+** METHOD: sqlite3
 **
-** ^This function returns the number of row changes caused by [INSERT],
-** [UPDATE] or [DELETE] statements since the [database connection] was opened.
-** ^(The count returned by sqlite3_total_changes() includes all changes
-** from all [CREATE TRIGGER | trigger] contexts and changes made by
-** [foreign key actions]. However,
-** the count does not include changes used to implement [REPLACE] constraints,
-** do rollbacks or ABORT processing, or [DROP TABLE] processing.  The
-** count does not include rows of views that fire an [INSTEAD OF trigger],
-** though if the INSTEAD OF trigger makes changes of its own, those changes 
-** are counted.)^
-** ^The sqlite3_total_changes() function counts the changes as soon as
-** the statement that makes them is completed (when the statement handle
-** is passed to [sqlite3_reset()] or [sqlite3_finalize()]).
-**
+** ^This function returns the total number of rows inserted, modified or
+** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed
+** since the database connection was opened, including those executed as
+** part of trigger programs. ^Executing any other type of SQL statement
+** does not affect the value returned by sqlite3_total_changes().
+** 
+** ^Changes made as part of [foreign key actions] are included in the
+** count, but those made as part of REPLACE constraint resolution are
+** not. ^Changes to a view that are intercepted by INSTEAD OF triggers 
+** are not counted.
+** 
 ** See also the [sqlite3_changes()] interface, the
 ** [count_changes pragma], and the [total_changes() SQL function].
 **
@@ -1949,10 +2013,11 @@ SQLITE_API int sqlite3_changes(sqlite3*);
 ** while [sqlite3_total_changes()] is running then the value
 ** returned is unpredictable and not meaningful.
 */
-SQLITE_API int sqlite3_total_changes(sqlite3*);
+SQLITE_API int SQLITE_STDCALL sqlite3_total_changes(sqlite3*);
 
 /*
 ** CAPI3REF: Interrupt A Long-Running Query
+** METHOD: sqlite3
 **
 ** ^This function causes any pending database operation to abort and
 ** return at its earliest opportunity. This routine is typically
@@ -1988,7 +2053,7 @@ SQLITE_API int sqlite3_total_changes(sqlite3*);
 ** If the database connection closes while [sqlite3_interrupt()]
 ** is running then bad things will likely happen.
 */
-SQLITE_API void sqlite3_interrupt(sqlite3*);
+SQLITE_API void SQLITE_STDCALL sqlite3_interrupt(sqlite3*);
 
 /*
 ** CAPI3REF: Determine If An SQL Statement Is Complete
@@ -2023,11 +2088,13 @@ SQLITE_API void sqlite3_interrupt(sqlite3*);
 ** The input to [sqlite3_complete16()] must be a zero-terminated
 ** UTF-16 string in native byte order.
 */
-SQLITE_API int sqlite3_complete(const char *sql);
-SQLITE_API int sqlite3_complete16(const void *sql);
+SQLITE_API int SQLITE_STDCALL sqlite3_complete(const char *sql);
+SQLITE_API int SQLITE_STDCALL sqlite3_complete16(const void *sql);
 
 /*
 ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors
+** KEYWORDS: {busy-handler callback} {busy handler}
+** METHOD: sqlite3
 **
 ** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X
 ** that might be invoked with argument P whenever
@@ -2044,7 +2111,7 @@ SQLITE_API int sqlite3_complete16(const void *sql);
 ** ^The first argument to the busy handler is a copy of the void* pointer which
 ** is the third argument to sqlite3_busy_handler().  ^The second argument to
 ** the busy handler callback is the number of times that the busy handler has
-** been invoked for the same locking event.  ^If the
+** been invoked previously for the same locking event.  ^If the
 ** busy callback returns 0, then no additional attempts are made to
 ** access the database and [SQLITE_BUSY] is returned
 ** to the application.
@@ -2083,10 +2150,11 @@ SQLITE_API int sqlite3_complete16(const void *sql);
 ** A busy handler must not close the database connection
 ** or [prepared statement] that invoked the busy handler.
 */
-SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
+SQLITE_API int SQLITE_STDCALL sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
 
 /*
 ** CAPI3REF: Set A Busy Timeout
+** METHOD: sqlite3
 **
 ** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps
 ** for a specified amount of time when a table is locked.  ^The handler
@@ -2099,16 +2167,17 @@ SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
 ** turns off all busy handlers.
 **
 ** ^(There can only be a single busy handler for a particular
-** [database connection] any any given moment.  If another busy handler
+** [database connection] at any given moment.  If another busy handler
 ** was defined  (using [sqlite3_busy_handler()]) prior to calling
 ** this routine, that other busy handler is cleared.)^
 **
 ** See also:  [PRAGMA busy_timeout]
 */
-SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
+SQLITE_API int SQLITE_STDCALL sqlite3_busy_timeout(sqlite3*, int ms);
 
 /*
 ** CAPI3REF: Convenience Routines For Running Queries
+** METHOD: sqlite3
 **
 ** This is a legacy interface that is preserved for backwards compatibility.
 ** Use of this interface is not recommended.
@@ -2179,7 +2248,7 @@ SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
 ** reflected in subsequent calls to [sqlite3_errcode()] or
 ** [sqlite3_errmsg()].
 */
-SQLITE_API int sqlite3_get_table(
+SQLITE_API int SQLITE_STDCALL sqlite3_get_table(
   sqlite3 *db,          /* An open database */
   const char *zSql,     /* SQL to be evaluated */
   char ***pazResult,    /* Results of the query */
@@ -2187,13 +2256,17 @@ SQLITE_API int sqlite3_get_table(
   int *pnColumn,        /* Number of result columns written here */
   char **pzErrmsg       /* Error msg written here */
 );
-SQLITE_API void sqlite3_free_table(char **result);
+SQLITE_API void SQLITE_STDCALL sqlite3_free_table(char **result);
 
 /*
 ** CAPI3REF: Formatted String Printing Functions
 **
 ** These routines are work-alikes of the "printf()" family of functions
 ** from the standard C library.
+** These routines understand most of the common K&R formatting options,
+** plus some additional non-standard formats, detailed below.
+** Note that some of the more obscure formatting options from recent
+** C-library standards are omitted from this implementation.
 **
 ** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
 ** results into memory obtained from [sqlite3_malloc()].
@@ -2226,7 +2299,7 @@ SQLITE_API void sqlite3_free_table(char **result);
 ** These routines all implement some additional formatting
 ** options that are useful for constructing SQL statements.
 ** All of the usual printf() formatting options apply.  In addition, there
-** is are "%q", "%Q", and "%z" options.
+** is are "%q", "%Q", "%w" and "%z" options.
 **
 ** ^(The %q option works like %s in that it substitutes a nul-terminated
 ** string from the argument list.  But %q also doubles every '\'' character.
@@ -2279,14 +2352,20 @@ SQLITE_API void sqlite3_free_table(char **result);
 ** The code above will render a correct SQL statement in the zSQL
 ** variable even if the zText variable is a NULL pointer.
 **
+** ^(The "%w" formatting option is like "%q" except that it expects to
+** be contained within double-quotes instead of single quotes, and it
+** escapes the double-quote character instead of the single-quote
+** character.)^  The "%w" formatting option is intended for safely inserting
+** table and column names into a constructed SQL statement.
+**
 ** ^(The "%z" formatting option works like "%s" but with the
 ** addition that after the string has been read and copied into
 ** the result, [sqlite3_free()] is called on the input string.)^
 */
-SQLITE_API char *sqlite3_mprintf(const char*,...);
-SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
-SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...);
-SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
+SQLITE_API char *SQLITE_CDECL sqlite3_mprintf(const char*,...);
+SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char*, va_list);
+SQLITE_API char *SQLITE_CDECL sqlite3_snprintf(int,char*,const char*, ...);
+SQLITE_API char *SQLITE_STDCALL sqlite3_vsnprintf(int,char*,const char*, va_list);
 
 /*
 ** CAPI3REF: Memory Allocation Subsystem
@@ -2303,6 +2382,10 @@ SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
 ** sqlite3_malloc() is zero or negative then sqlite3_malloc() returns
 ** a NULL pointer.
 **
+** ^The sqlite3_malloc64(N) routine works just like
+** sqlite3_malloc(N) except that N is an unsigned 64-bit integer instead
+** of a signed 32-bit integer.
+**
 ** ^Calling sqlite3_free() with a pointer previously returned
 ** by sqlite3_malloc() or sqlite3_realloc() releases that memory so
 ** that it might be reused.  ^The sqlite3_free() routine is
@@ -2314,24 +2397,38 @@ SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
 ** might result if sqlite3_free() is called with a non-NULL pointer that
 ** was not obtained from sqlite3_malloc() or sqlite3_realloc().
 **
-** ^(The sqlite3_realloc() interface attempts to resize a
-** prior memory allocation to be at least N bytes, where N is the
-** second parameter.  The memory allocation to be resized is the first
-** parameter.)^ ^ If the first parameter to sqlite3_realloc()
+** ^The sqlite3_realloc(X,N) interface attempts to resize a
+** prior memory allocation X to be at least N bytes.
+** ^If the X parameter to sqlite3_realloc(X,N)
 ** is a NULL pointer then its behavior is identical to calling
-** sqlite3_malloc(N) where N is the second parameter to sqlite3_realloc().
-** ^If the second parameter to sqlite3_realloc() is zero or
+** sqlite3_malloc(N).
+** ^If the N parameter to sqlite3_realloc(X,N) is zero or
 ** negative then the behavior is exactly the same as calling
-** sqlite3_free(P) where P is the first parameter to sqlite3_realloc().
-** ^sqlite3_realloc() returns a pointer to a memory allocation
-** of at least N bytes in size or NULL if sufficient memory is unavailable.
+** sqlite3_free(X).
+** ^sqlite3_realloc(X,N) returns a pointer to a memory allocation
+** of at least N bytes in size or NULL if insufficient memory is available.
 ** ^If M is the size of the prior allocation, then min(N,M) bytes
 ** of the prior allocation are copied into the beginning of buffer returned
-** by sqlite3_realloc() and the prior allocation is freed.
-** ^If sqlite3_realloc() returns NULL, then the prior allocation
-** is not freed.
-**
-** ^The memory returned by sqlite3_malloc() and sqlite3_realloc()
+** by sqlite3_realloc(X,N) and the prior allocation is freed.
+** ^If sqlite3_realloc(X,N) returns NULL and N is positive, then the
+** prior allocation is not freed.
+**
+** ^The sqlite3_realloc64(X,N) interfaces works the same as
+** sqlite3_realloc(X,N) except that N is a 64-bit unsigned integer instead
+** of a 32-bit signed integer.
+**
+** ^If X is a memory allocation previously obtained from sqlite3_malloc(),
+** sqlite3_malloc64(), sqlite3_realloc(), or sqlite3_realloc64(), then
+** sqlite3_msize(X) returns the size of that memory allocation in bytes.
+** ^The value returned by sqlite3_msize(X) might be larger than the number
+** of bytes requested when X was allocated.  ^If X is a NULL pointer then
+** sqlite3_msize(X) returns zero.  If X points to something that is not
+** the beginning of memory allocation, or if it points to a formerly
+** valid memory allocation that has now been freed, then the behavior
+** of sqlite3_msize(X) is undefined and possibly harmful.
+**
+** ^The memory returned by sqlite3_malloc(), sqlite3_realloc(),
+** sqlite3_malloc64(), and sqlite3_realloc64()
 ** is always aligned to at least an 8 byte boundary, or to a
 ** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time
 ** option is used.
@@ -2358,9 +2455,12 @@ SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list);
 ** a block of memory after it has been released using
 ** [sqlite3_free()] or [sqlite3_realloc()].
 */
-SQLITE_API void *sqlite3_malloc(int);
-SQLITE_API void *sqlite3_realloc(void*, int);
-SQLITE_API void sqlite3_free(void*);
+SQLITE_API void *SQLITE_STDCALL sqlite3_malloc(int);
+SQLITE_API void *SQLITE_STDCALL sqlite3_malloc64(sqlite3_uint64);
+SQLITE_API void *SQLITE_STDCALL sqlite3_realloc(void*, int);
+SQLITE_API void *SQLITE_STDCALL sqlite3_realloc64(void*, sqlite3_uint64);
+SQLITE_API void SQLITE_STDCALL sqlite3_free(void*);
+SQLITE_API sqlite3_uint64 SQLITE_STDCALL sqlite3_msize(void*);
 
 /*
 ** CAPI3REF: Memory Allocator Statistics
@@ -2385,8 +2485,8 @@ SQLITE_API void sqlite3_free(void*);
 ** by [sqlite3_memory_highwater(1)] is the high-water mark
 ** prior to the reset.
 */
-SQLITE_API sqlite3_int64 sqlite3_memory_used(void);
-SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag);
 
 /*
 ** CAPI3REF: Pseudo-Random Number Generator
@@ -2398,20 +2498,22 @@ SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
 ** applications to access the same PRNG for other purposes.
 **
 ** ^A call to this routine stores N bytes of randomness into buffer P.
-** ^If N is less than one, then P can be a NULL pointer.
+** ^The P parameter can be a NULL pointer.
 **
 ** ^If this routine has not been previously called or if the previous
-** call had N less than one, then the PRNG is seeded using randomness
-** obtained from the xRandomness method of the default [sqlite3_vfs] object.
-** ^If the previous call to this routine had an N of 1 or more then
-** the pseudo-randomness is generated
+** call had N less than one or a NULL pointer for P, then the PRNG is
+** seeded using randomness obtained from the xRandomness method of
+** the default [sqlite3_vfs] object.
+** ^If the previous call to this routine had an N of 1 or more and a
+** non-NULL P then the pseudo-randomness is generated
 ** internally and without recourse to the [sqlite3_vfs] xRandomness
 ** method.
 */
-SQLITE_API void sqlite3_randomness(int N, void *P);
+SQLITE_API void SQLITE_STDCALL sqlite3_randomness(int N, void *P);
 
 /*
 ** CAPI3REF: Compile-Time Authorization Callbacks
+** METHOD: sqlite3
 **
 ** ^This routine registers an authorizer callback with a particular
 ** [database connection], supplied in the first argument.
@@ -2490,7 +2592,7 @@ SQLITE_API void sqlite3_randomness(int N, void *P);
 ** as stated in the previous paragraph, sqlite3_step() invokes
 ** sqlite3_prepare_v2() to reprepare a statement after a schema change.
 */
-SQLITE_API int sqlite3_set_authorizer(
+SQLITE_API int SQLITE_STDCALL sqlite3_set_authorizer(
   sqlite3*,
   int (*xAuth)(void*,int,const char*,const char*,const char*,const char*),
   void *pUserData
@@ -2568,6 +2670,7 @@ SQLITE_API int sqlite3_set_authorizer(
 
 /*
 ** CAPI3REF: Tracing And Profiling Functions
+** METHOD: sqlite3
 **
 ** These routines register callback functions that can be used for
 ** tracing and profiling the execution of SQL statements.
@@ -2594,12 +2697,13 @@ SQLITE_API int sqlite3_set_authorizer(
 ** sqlite3_profile() function is considered experimental and is
 ** subject to change in future versions of SQLite.
 */
-SQLITE_API void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
-SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
+SQLITE_API void *SQLITE_STDCALL sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*);
+SQLITE_API SQLITE_EXPERIMENTAL void *SQLITE_STDCALL sqlite3_profile(sqlite3*,
    void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
 
 /*
 ** CAPI3REF: Query Progress Callbacks
+** METHOD: sqlite3
 **
 ** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback
 ** function X to be invoked periodically during long running calls to
@@ -2629,10 +2733,11 @@ SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
 ** database connections for the meaning of "modify" in this paragraph.
 **
 */
-SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
+SQLITE_API void SQLITE_STDCALL sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
 
 /*
 ** CAPI3REF: Opening A New Database Connection
+** CONSTRUCTOR: sqlite3
 **
 ** ^These routines open an SQLite database file as specified by the 
 ** filename argument. ^The filename argument is interpreted as UTF-8 for
@@ -2647,9 +2752,9 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
 ** an English language description of the error following a failure of any
 ** of the sqlite3_open() routines.
 **
-** ^The default encoding for the database will be UTF-8 if
-** sqlite3_open() or sqlite3_open_v2() is called and
-** UTF-16 in the native byte order if sqlite3_open16() is used.
+** ^The default encoding will be UTF-8 for databases created using
+** sqlite3_open() or sqlite3_open_v2().  ^The default encoding for databases
+** created using sqlite3_open16() will be UTF-16 in the native byte order.
 **
 ** Whether or not an error occurs when it is opened, resources
 ** associated with the [database connection] handle should be released by
@@ -2737,13 +2842,14 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
 ** then it is interpreted as an absolute path. ^If the path does not begin 
 ** with a '/' (meaning that the authority section is omitted from the URI)
 ** then the path is interpreted as a relative path. 
-** ^On windows, the first component of an absolute path 
-** is a drive specification (e.g. "C:").
+** ^(On windows, the first component of an absolute path 
+** is a drive specification (e.g. "C:").)^
 **
 ** [[core URI query parameters]]
 ** The query component of a URI may contain parameters that are interpreted
 ** either by SQLite itself, or by a [VFS | custom VFS implementation].
-** SQLite interprets the following three query parameters:
+** SQLite and its built-in [VFSes] interpret the
+** following query parameters:
 **
 ** <ul>
 **   <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of
@@ -2778,11 +2884,9 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
 **     a URI filename, its value overrides any behavior requested by setting
 **     SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
 **
-**  <li> <b>psow</b>: ^The psow parameter may be "true" (or "on" or "yes" or
-**     "1") or "false" (or "off" or "no" or "0") to indicate that the
+**  <li> <b>psow</b>: ^The psow parameter indicates whether or not the
 **     [powersafe overwrite] property does or does not apply to the
-**     storage media on which the database file resides.  ^The psow query
-**     parameter only works for the built-in unix and Windows VFSes.
+**     storage media on which the database file resides.
 **
 **  <li> <b>nolock</b>: ^The nolock parameter is a boolean query parameter
 **     which if set disables file locking in rollback journal modes.  This
@@ -2858,15 +2962,15 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
 **
 ** See also: [sqlite3_temp_directory]
 */
-SQLITE_API int sqlite3_open(
+SQLITE_API int SQLITE_STDCALL sqlite3_open(
   const char *filename,   /* Database filename (UTF-8) */
   sqlite3 **ppDb          /* OUT: SQLite db handle */
 );
-SQLITE_API int sqlite3_open16(
+SQLITE_API int SQLITE_STDCALL sqlite3_open16(
   const void *filename,   /* Database filename (UTF-16) */
   sqlite3 **ppDb          /* OUT: SQLite db handle */
 );
-SQLITE_API int sqlite3_open_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_open_v2(
   const char *filename,   /* Database filename (UTF-8) */
   sqlite3 **ppDb,         /* OUT: SQLite db handle */
   int flags,              /* Flags */
@@ -2912,19 +3016,22 @@ SQLITE_API int sqlite3_open_v2(
 ** VFS method, then the behavior of this routine is undefined and probably
 ** undesirable.
 */
-SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
-SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
-SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_uri_parameter(const char *zFilename, const char *zParam);
+SQLITE_API int SQLITE_STDCALL sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
 
 
 /*
 ** CAPI3REF: Error Codes And Messages
-**
-** ^The sqlite3_errcode() interface returns the numeric [result code] or
-** [extended result code] for the most recent failed sqlite3_* API call
-** associated with a [database connection]. If a prior API call failed
-** but the most recent API call succeeded, the return value from
-** sqlite3_errcode() is undefined.  ^The sqlite3_extended_errcode()
+** METHOD: sqlite3
+**
+** ^If the most recent sqlite3_* API call associated with 
+** [database connection] D failed, then the sqlite3_errcode(D) interface
+** returns the numeric [result code] or [extended result code] for that
+** API call.
+** If the most recent API call was successful,
+** then the return value from sqlite3_errcode() is undefined.
+** ^The sqlite3_extended_errcode()
 ** interface is the same except that it always returns the 
 ** [extended result code] even when extended result codes are
 ** disabled.
@@ -2955,40 +3062,41 @@ SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int
 ** was invoked incorrectly by the application.  In that case, the
 ** error code and message may or may not be set.
 */
-SQLITE_API int sqlite3_errcode(sqlite3 *db);
-SQLITE_API int sqlite3_extended_errcode(sqlite3 *db);
-SQLITE_API const char *sqlite3_errmsg(sqlite3*);
-SQLITE_API const void *sqlite3_errmsg16(sqlite3*);
-SQLITE_API const char *sqlite3_errstr(int);
+SQLITE_API int SQLITE_STDCALL sqlite3_errcode(sqlite3 *db);
+SQLITE_API int SQLITE_STDCALL sqlite3_extended_errcode(sqlite3 *db);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_errmsg(sqlite3*);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_errmsg16(sqlite3*);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_errstr(int);
 
 /*
-** CAPI3REF: SQL Statement Object
+** CAPI3REF: Prepared Statement Object
 ** KEYWORDS: {prepared statement} {prepared statements}
 **
-** An instance of this object represents a single SQL statement.
-** This object is variously known as a "prepared statement" or a
-** "compiled SQL statement" or simply as a "statement".
+** An instance of this object represents a single SQL statement that
+** has been compiled into binary form and is ready to be evaluated.
+**
+** Think of each SQL statement as a separate computer program.  The
+** original SQL text is source code.  A prepared statement object 
+** is the compiled object code.  All SQL must be converted into a
+** prepared statement before it can be run.
 **
-** The life of a statement object goes something like this:
+** The life-cycle of a prepared statement object usually goes like this:
 **
 ** <ol>
-** <li> Create the object using [sqlite3_prepare_v2()] or a related
-**      function.
-** <li> Bind values to [host parameters] using the sqlite3_bind_*()
+** <li> Create the prepared statement object using [sqlite3_prepare_v2()].
+** <li> Bind values to [parameters] using the sqlite3_bind_*()
 **      interfaces.
 ** <li> Run the SQL by calling [sqlite3_step()] one or more times.
-** <li> Reset the statement using [sqlite3_reset()] then go back
+** <li> Reset the prepared statement using [sqlite3_reset()] then go back
 **      to step 2.  Do this zero or more times.
 ** <li> Destroy the object using [sqlite3_finalize()].
 ** </ol>
-**
-** Refer to documentation on individual methods above for additional
-** information.
 */
 typedef struct sqlite3_stmt sqlite3_stmt;
 
 /*
 ** CAPI3REF: Run-time Limits
+** METHOD: sqlite3
 **
 ** ^(This interface allows the size of various constructs to be limited
 ** on a connection by connection basis.  The first parameter is the
@@ -3026,7 +3134,7 @@ typedef struct sqlite3_stmt sqlite3_stmt;
 **
 ** New run-time limit categories may be added in future releases.
 */
-SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
+SQLITE_API int SQLITE_STDCALL sqlite3_limit(sqlite3*, int id, int newVal);
 
 /*
 ** CAPI3REF: Run-Time Limit Categories
@@ -3078,6 +3186,10 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
 **
 ** [[SQLITE_LIMIT_TRIGGER_DEPTH]] ^(<dt>SQLITE_LIMIT_TRIGGER_DEPTH</dt>
 ** <dd>The maximum depth of recursion for triggers.</dd>)^
+**
+** [[SQLITE_LIMIT_WORKER_THREADS]] ^(<dt>SQLITE_LIMIT_WORKER_THREADS</dt>
+** <dd>The maximum number of auxiliary worker threads that a single
+** [prepared statement] may start.</dd>)^
 ** </dl>
 */
 #define SQLITE_LIMIT_LENGTH                    0
@@ -3091,10 +3203,13 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
 #define SQLITE_LIMIT_LIKE_PATTERN_LENGTH       8
 #define SQLITE_LIMIT_VARIABLE_NUMBER           9
 #define SQLITE_LIMIT_TRIGGER_DEPTH            10
+#define SQLITE_LIMIT_WORKER_THREADS           11
 
 /*
 ** CAPI3REF: Compiling An SQL Statement
 ** KEYWORDS: {SQL statement compiler}
+** METHOD: sqlite3
+** CONSTRUCTOR: sqlite3_stmt
 **
 ** To execute an SQL query, it must first be compiled into a byte-code
 ** program using one of these routines.
@@ -3108,16 +3223,14 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
 ** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2()
 ** use UTF-16.
 **
-** ^If the nByte argument is less than zero, then zSql is read up to the
-** first zero terminator. ^If nByte is non-negative, then it is the maximum
-** number of  bytes read from zSql.  ^When nByte is non-negative, the
-** zSql string ends at either the first '\000' or '\u0000' character or
-** the nByte-th byte, whichever comes first. If the caller knows
-** that the supplied string is nul-terminated, then there is a small
-** performance advantage to be gained by passing an nByte parameter that
-** is equal to the number of bytes in the input string <i>including</i>
-** the nul-terminator bytes as this saves SQLite from having to
-** make a copy of the input string.
+** ^If the nByte argument is negative, then zSql is read up to the
+** first zero terminator. ^If nByte is positive, then it is the
+** number of bytes read from zSql.  ^If nByte is zero, then no prepared
+** statement is generated.
+** If the caller knows that the supplied string is nul-terminated, then
+** there is a small performance advantage to passing an nByte parameter that
+** is the number of bytes in the input string <i>including</i>
+** the nul-terminator.
 **
 ** ^If pzTail is not NULL then *pzTail is made to point to the first byte
 ** past the end of the first SQL statement in zSql.  These routines only
@@ -3173,28 +3286,28 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
 ** </li>
 ** </ol>
 */
-SQLITE_API int sqlite3_prepare(
+SQLITE_API int SQLITE_STDCALL sqlite3_prepare(
   sqlite3 *db,            /* Database handle */
   const char *zSql,       /* SQL statement, UTF-8 encoded */
   int nByte,              /* Maximum length of zSql in bytes. */
   sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
   const char **pzTail     /* OUT: Pointer to unused portion of zSql */
 );
-SQLITE_API int sqlite3_prepare_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_prepare_v2(
   sqlite3 *db,            /* Database handle */
   const char *zSql,       /* SQL statement, UTF-8 encoded */
   int nByte,              /* Maximum length of zSql in bytes. */
   sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
   const char **pzTail     /* OUT: Pointer to unused portion of zSql */
 );
-SQLITE_API int sqlite3_prepare16(
+SQLITE_API int SQLITE_STDCALL sqlite3_prepare16(
   sqlite3 *db,            /* Database handle */
   const void *zSql,       /* SQL statement, UTF-16 encoded */
   int nByte,              /* Maximum length of zSql in bytes. */
   sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
   const void **pzTail     /* OUT: Pointer to unused portion of zSql */
 );
-SQLITE_API int sqlite3_prepare16_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_prepare16_v2(
   sqlite3 *db,            /* Database handle */
   const void *zSql,       /* SQL statement, UTF-16 encoded */
   int nByte,              /* Maximum length of zSql in bytes. */
@@ -3204,15 +3317,17 @@ SQLITE_API int sqlite3_prepare16_v2(
 
 /*
 ** CAPI3REF: Retrieving Statement SQL
+** METHOD: sqlite3_stmt
 **
 ** ^This interface can be used to retrieve a saved copy of the original
 ** SQL text used to create a [prepared statement] if that statement was
 ** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
 */
-SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_sql(sqlite3_stmt *pStmt);
 
 /*
 ** CAPI3REF: Determine If An SQL Statement Writes The Database
+** METHOD: sqlite3_stmt
 **
 ** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if
 ** and only if the [prepared statement] X makes no direct changes to
@@ -3240,10 +3355,11 @@ SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
 ** change the configuration of a database connection, they do not make 
 ** changes to the content of the database files on disk.
 */
-SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
+SQLITE_API int SQLITE_STDCALL sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
 
 /*
 ** CAPI3REF: Determine If A Prepared Statement Has Been Reset
+** METHOD: sqlite3_stmt
 **
 ** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the
 ** [prepared statement] S has been stepped at least once using 
@@ -3259,7 +3375,7 @@ SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);
 ** for example, in diagnostic routines to search for prepared 
 ** statements that are holding a transaction open.
 */
-SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*);
+SQLITE_API int SQLITE_STDCALL sqlite3_stmt_busy(sqlite3_stmt*);
 
 /*
 ** CAPI3REF: Dynamically Typed Value Object
@@ -3318,6 +3434,7 @@ typedef struct sqlite3_context sqlite3_context;
 ** CAPI3REF: Binding Values To Prepared Statements
 ** KEYWORDS: {host parameter} {host parameters} {host parameter name}
 ** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
+** METHOD: sqlite3_stmt
 **
 ** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants,
 ** literals may be replaced by a [parameter] that matches one of following
@@ -3364,18 +3481,18 @@ typedef struct sqlite3_context sqlite3_context;
 ** If the fourth parameter to sqlite3_bind_blob() is negative, then
 ** the behavior is undefined.
 ** If a non-negative fourth parameter is provided to sqlite3_bind_text()
-** or sqlite3_bind_text16() then that parameter must be the byte offset
+** or sqlite3_bind_text16() or sqlite3_bind_text64() then
+** that parameter must be the byte offset
 ** where the NUL terminator would occur assuming the string were NUL
 ** terminated.  If any NUL characters occur at byte offsets less than 
 ** the value of the fourth parameter then the resulting string value will
 ** contain embedded NULs.  The result of expressions involving strings
 ** with embedded NULs is undefined.
 **
-** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
-** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
+** ^The fifth argument to the BLOB and string binding interfaces
+** is a destructor used to dispose of the BLOB or
 ** string after SQLite has finished with it.  ^The destructor is called
-** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(),
-** sqlite3_bind_text(), or sqlite3_bind_text16() fails.  
+** to dispose of the BLOB or string even if the call to bind API fails.
 ** ^If the fifth argument is
 ** the special value [SQLITE_STATIC], then SQLite assumes that the
 ** information is in static, unmanaged space and does not need to be freed.
@@ -3383,6 +3500,14 @@ typedef struct sqlite3_context sqlite3_context;
 ** SQLite makes its own private copy of the data immediately, before
 ** the sqlite3_bind_*() routine returns.
 **
+** ^The sixth argument to sqlite3_bind_text64() must be one of
+** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]
+** to specify the encoding of the text in the third parameter.  If
+** the sixth argument to sqlite3_bind_text64() is not one of the
+** allowed values shown above, or if the text encoding is different
+** from the encoding specified by the sixth parameter, then the behavior
+** is undefined.
+**
 ** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that
 ** is filled with zeroes.  ^A zeroblob uses a fixed amount of memory
 ** (just an integer to hold its size) while it is being processed.
@@ -3403,24 +3528,32 @@ typedef struct sqlite3_context sqlite3_context;
 **
 ** ^The sqlite3_bind_* routines return [SQLITE_OK] on success or an
 ** [error code] if anything goes wrong.
+** ^[SQLITE_TOOBIG] might be returned if the size of a string or BLOB
+** exceeds limits imposed by [sqlite3_limit]([SQLITE_LIMIT_LENGTH]) or
+** [SQLITE_MAX_LENGTH].
 ** ^[SQLITE_RANGE] is returned if the parameter
 ** index is out of range.  ^[SQLITE_NOMEM] is returned if malloc() fails.
 **
 ** See also: [sqlite3_bind_parameter_count()],
 ** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()].
 */
-SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
-SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double);
-SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int);
-SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
-SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int);
-SQLITE_API int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*));
-SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
-SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
-SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*));
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64,
+                        void(*)(void*));
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_double(sqlite3_stmt*, int, double);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_int(sqlite3_stmt*, int, int);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_null(sqlite3_stmt*, int);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*));
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*));
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64,
+                         void(*)(void*), unsigned char encoding);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
 
 /*
 ** CAPI3REF: Number Of SQL Parameters
+** METHOD: sqlite3_stmt
 **
 ** ^This routine can be used to find the number of [SQL parameters]
 ** in a [prepared statement].  SQL parameters are tokens of the
@@ -3437,10 +3570,11 @@ SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n);
 ** [sqlite3_bind_parameter_name()], and
 ** [sqlite3_bind_parameter_index()].
 */
-SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_count(sqlite3_stmt*);
 
 /*
 ** CAPI3REF: Name Of A Host Parameter
+** METHOD: sqlite3_stmt
 **
 ** ^The sqlite3_bind_parameter_name(P,N) interface returns
 ** the name of the N-th [SQL parameter] in the [prepared statement] P.
@@ -3464,10 +3598,11 @@ SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
 ** [sqlite3_bind_parameter_count()], and
 ** [sqlite3_bind_parameter_index()].
 */
-SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_bind_parameter_name(sqlite3_stmt*, int);
 
 /*
 ** CAPI3REF: Index Of A Parameter With A Given Name
+** METHOD: sqlite3_stmt
 **
 ** ^Return the index of an SQL parameter given its name.  ^The
 ** index value returned is suitable for use as the second
@@ -3480,19 +3615,21 @@ SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int);
 ** [sqlite3_bind_parameter_count()], and
 ** [sqlite3_bind_parameter_index()].
 */
-SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
+SQLITE_API int SQLITE_STDCALL sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);
 
 /*
 ** CAPI3REF: Reset All Bindings On A Prepared Statement
+** METHOD: sqlite3_stmt
 **
 ** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset
 ** the [sqlite3_bind_blob | bindings] on a [prepared statement].
 ** ^Use this routine to reset all host parameters to NULL.
 */
-SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
+SQLITE_API int SQLITE_STDCALL sqlite3_clear_bindings(sqlite3_stmt*);
 
 /*
 ** CAPI3REF: Number Of Columns In A Result Set
+** METHOD: sqlite3_stmt
 **
 ** ^Return the number of columns in the result set returned by the
 ** [prepared statement]. ^This routine returns 0 if pStmt is an SQL
@@ -3500,10 +3637,11 @@ SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
 **
 ** See also: [sqlite3_data_count()]
 */
-SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
+SQLITE_API int SQLITE_STDCALL sqlite3_column_count(sqlite3_stmt *pStmt);
 
 /*
 ** CAPI3REF: Column Names In A Result Set
+** METHOD: sqlite3_stmt
 **
 ** ^These routines return the name assigned to a particular column
 ** in the result set of a [SELECT] statement.  ^The sqlite3_column_name()
@@ -3528,11 +3666,12 @@ SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
 ** then the name of the column is unspecified and may change from
 ** one release of SQLite to the next.
 */
-SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N);
-SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_name(sqlite3_stmt*, int N);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_name16(sqlite3_stmt*, int N);
 
 /*
 ** CAPI3REF: Source Of Data In A Query Result
+** METHOD: sqlite3_stmt
 **
 ** ^These routines provide a means to determine the database, table, and
 ** table column that is the origin of a particular result column in
@@ -3576,15 +3715,16 @@ SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N);
 ** for the same [prepared statement] and result column
 ** at the same time then the results are undefined.
 */
-SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int);
-SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int);
-SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt*,int);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt*,int);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt*,int);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt*,int);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt*,int);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt*,int);
 
 /*
 ** CAPI3REF: Declared Datatype Of A Query Result
+** METHOD: sqlite3_stmt
 **
 ** ^(The first parameter is a [prepared statement].
 ** If this statement is a [SELECT] statement and the Nth column of the
@@ -3612,11 +3752,12 @@ SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int);
 ** is associated with individual values, not with the containers
 ** used to hold those values.
 */
-SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int);
-SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_column_decltype(sqlite3_stmt*,int);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_decltype16(sqlite3_stmt*,int);
 
 /*
 ** CAPI3REF: Evaluate An SQL Statement
+** METHOD: sqlite3_stmt
 **
 ** After a [prepared statement] has been prepared using either
 ** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy
@@ -3692,10 +3833,11 @@ SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
 ** then the more specific [error codes] are returned directly
 ** by sqlite3_step().  The use of the "v2" interface is recommended.
 */
-SQLITE_API int sqlite3_step(sqlite3_stmt*);
+SQLITE_API int SQLITE_STDCALL sqlite3_step(sqlite3_stmt*);
 
 /*
 ** CAPI3REF: Number of columns in a result set
+** METHOD: sqlite3_stmt
 **
 ** ^The sqlite3_data_count(P) interface returns the number of columns in the
 ** current row of the result set of [prepared statement] P.
@@ -3712,7 +3854,7 @@ SQLITE_API int sqlite3_step(sqlite3_stmt*);
 **
 ** See also: [sqlite3_column_count()]
 */
-SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
+SQLITE_API int SQLITE_STDCALL sqlite3_data_count(sqlite3_stmt *pStmt);
 
 /*
 ** CAPI3REF: Fundamental Datatypes
@@ -3749,6 +3891,7 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
 /*
 ** CAPI3REF: Result Values From A Query
 ** KEYWORDS: {column access functions}
+** METHOD: sqlite3_stmt
 **
 ** These routines form the "result set" interface.
 **
@@ -3908,19 +4051,20 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
 ** pointer.  Subsequent calls to [sqlite3_errcode()] will return
 ** [SQLITE_NOMEM].)^
 */
-SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
-SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol);
-SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol);
-SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol);
-SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol);
-SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_blob(sqlite3_stmt*, int iCol);
+SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes(sqlite3_stmt*, int iCol);
+SQLITE_API int SQLITE_STDCALL sqlite3_column_bytes16(sqlite3_stmt*, int iCol);
+SQLITE_API double SQLITE_STDCALL sqlite3_column_double(sqlite3_stmt*, int iCol);
+SQLITE_API int SQLITE_STDCALL sqlite3_column_int(sqlite3_stmt*, int iCol);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_column_int64(sqlite3_stmt*, int iCol);
+SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_column_text(sqlite3_stmt*, int iCol);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_column_text16(sqlite3_stmt*, int iCol);
+SQLITE_API int SQLITE_STDCALL sqlite3_column_type(sqlite3_stmt*, int iCol);
+SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_column_value(sqlite3_stmt*, int iCol);
 
 /*
 ** CAPI3REF: Destroy A Prepared Statement Object
+** DESTRUCTOR: sqlite3_stmt
 **
 ** ^The sqlite3_finalize() function is called to delete a [prepared statement].
 ** ^If the most recent evaluation of the statement encountered no errors
@@ -3944,10 +4088,11 @@ SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol);
 ** statement after it has been finalized can result in undefined and
 ** undesirable behavior such as segfaults and heap corruption.
 */
-SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
+SQLITE_API int SQLITE_STDCALL sqlite3_finalize(sqlite3_stmt *pStmt);
 
 /*
 ** CAPI3REF: Reset A Prepared Statement Object
+** METHOD: sqlite3_stmt
 **
 ** The sqlite3_reset() function is called to reset a [prepared statement]
 ** object back to its initial state, ready to be re-executed.
@@ -3970,13 +4115,14 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt);
 ** ^The [sqlite3_reset(S)] interface does not change the values
 ** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
 */
-SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
+SQLITE_API int SQLITE_STDCALL sqlite3_reset(sqlite3_stmt *pStmt);
 
 /*
 ** CAPI3REF: Create Or Redefine SQL Functions
 ** KEYWORDS: {function creation routines}
 ** KEYWORDS: {application-defined SQL function}
 ** KEYWORDS: {application-defined SQL functions}
+** METHOD: sqlite3
 **
 ** ^These functions (collectively known as "function creation routines")
 ** are used to add SQL functions or aggregates or to redefine the behavior
@@ -4069,7 +4215,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
 ** close the database connection nor finalize or reset the prepared
 ** statement in which the function is running.
 */
-SQLITE_API int sqlite3_create_function(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_function(
   sqlite3 *db,
   const char *zFunctionName,
   int nArg,
@@ -4079,7 +4225,7 @@ SQLITE_API int sqlite3_create_function(
   void (*xStep)(sqlite3_context*,int,sqlite3_value**),
   void (*xFinal)(sqlite3_context*)
 );
-SQLITE_API int sqlite3_create_function16(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_function16(
   sqlite3 *db,
   const void *zFunctionName,
   int nArg,
@@ -4089,7 +4235,7 @@ SQLITE_API int sqlite3_create_function16(
   void (*xStep)(sqlite3_context*,int,sqlite3_value**),
   void (*xFinal)(sqlite3_context*)
 );
-SQLITE_API int sqlite3_create_function_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_function_v2(
   sqlite3 *db,
   const char *zFunctionName,
   int nArg,
@@ -4107,9 +4253,9 @@ SQLITE_API int sqlite3_create_function_v2(
 ** These constant define integer codes that represent the various
 ** text encodings supported by SQLite.
 */
-#define SQLITE_UTF8           1
-#define SQLITE_UTF16LE        2
-#define SQLITE_UTF16BE        3
+#define SQLITE_UTF8           1    /* IMP: R-37514-35566 */
+#define SQLITE_UTF16LE        2    /* IMP: R-03371-37637 */
+#define SQLITE_UTF16BE        3    /* IMP: R-51971-34154 */
 #define SQLITE_UTF16          4    /* Use native byte order */
 #define SQLITE_ANY            5    /* Deprecated */
 #define SQLITE_UTF16_ALIGNED  8    /* sqlite3_create_collation only */
@@ -4131,21 +4277,22 @@ SQLITE_API int sqlite3_create_function_v2(
 ** These functions are [deprecated].  In order to maintain
 ** backwards compatibility with older code, these functions continue 
 ** to be supported.  However, new applications should avoid
-** the use of these functions.  To help encourage people to avoid
-** using these functions, we are not going to tell you what they do.
+** the use of these functions.  To encourage programmers to avoid
+** these functions, we will not explain what they do.
 */
 #ifndef SQLITE_OMIT_DEPRECATED
-SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void);
-SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void);
-SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
+SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_aggregate_count(sqlite3_context*);
+SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_expired(sqlite3_stmt*);
+SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*);
+SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_global_recover(void);
+SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_thread_cleanup(void);
+SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
                       void*,sqlite3_int64);
 #endif
 
 /*
 ** CAPI3REF: Obtaining SQL Function Parameter Values
+** METHOD: sqlite3_value
 **
 ** The C-language implementation of SQL functions and aggregates uses
 ** this set of interface routines to access the parameter values on
@@ -4164,7 +4311,7 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
 ** object results in undefined behavior.
 **
 ** ^These routines work just like the corresponding [column access functions]
-** except that  these routines take a single [protected sqlite3_value] object
+** except that these routines take a single [protected sqlite3_value] object
 ** pointer instead of a [sqlite3_stmt*] pointer and an integer column number.
 **
 ** ^The sqlite3_value_text16() interface extracts a UTF-16 string
@@ -4189,21 +4336,22 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
 ** These routines must be called from the same thread as
 ** the SQL function that supplied the [sqlite3_value*] parameters.
 */
-SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
-SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
-SQLITE_API int sqlite3_value_bytes16(sqlite3_value*);
-SQLITE_API double sqlite3_value_double(sqlite3_value*);
-SQLITE_API int sqlite3_value_int(sqlite3_value*);
-SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*);
-SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*);
-SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*);
-SQLITE_API int sqlite3_value_type(sqlite3_value*);
-SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_blob(sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes(sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_value_bytes16(sqlite3_value*);
+SQLITE_API double SQLITE_STDCALL sqlite3_value_double(sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_value_int(sqlite3_value*);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_value_int64(sqlite3_value*);
+SQLITE_API const unsigned char *SQLITE_STDCALL sqlite3_value_text(sqlite3_value*);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16(sqlite3_value*);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value*);
+SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*);
+SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*);
 
 /*
 ** CAPI3REF: Obtain Aggregate Function Context
+** METHOD: sqlite3_context
 **
 ** Implementations of aggregate SQL functions use this
 ** routine to allocate memory for storing their state.
@@ -4244,10 +4392,11 @@ SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
 ** This routine must be called from the same thread in which
 ** the aggregate SQL function is running.
 */
-SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
+SQLITE_API void *SQLITE_STDCALL sqlite3_aggregate_context(sqlite3_context*, int nBytes);
 
 /*
 ** CAPI3REF: User Data For Functions
+** METHOD: sqlite3_context
 **
 ** ^The sqlite3_user_data() interface returns a copy of
 ** the pointer that was the pUserData parameter (the 5th parameter)
@@ -4258,10 +4407,11 @@ SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes);
 ** This routine must be called from the same thread in which
 ** the application-defined function is running.
 */
-SQLITE_API void *sqlite3_user_data(sqlite3_context*);
+SQLITE_API void *SQLITE_STDCALL sqlite3_user_data(sqlite3_context*);
 
 /*
 ** CAPI3REF: Database Connection For Functions
+** METHOD: sqlite3_context
 **
 ** ^The sqlite3_context_db_handle() interface returns a copy of
 ** the pointer to the [database connection] (the 1st parameter)
@@ -4269,10 +4419,11 @@ SQLITE_API void *sqlite3_user_data(sqlite3_context*);
 ** and [sqlite3_create_function16()] routines that originally
 ** registered the application defined function.
 */
-SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
+SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_context_db_handle(sqlite3_context*);
 
 /*
 ** CAPI3REF: Function Auxiliary Data
+** METHOD: sqlite3_context
 **
 ** These functions may be used by (non-aggregate) SQL functions to
 ** associate metadata with argument values. If the same value is passed to
@@ -4321,8 +4472,8 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
 ** These routines must be called from the same thread in which
 ** the SQL function is running.
 */
-SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
-SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
+SQLITE_API void *SQLITE_STDCALL sqlite3_get_auxdata(sqlite3_context*, int N);
+SQLITE_API void SQLITE_STDCALL sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*));
 
 
 /*
@@ -4345,6 +4496,7 @@ typedef void (*sqlite3_destructor_type)(void*);
 
 /*
 ** CAPI3REF: Setting The Result Of An SQL Function
+** METHOD: sqlite3_context
 **
 ** These routines are used by the xFunc or xFinal callbacks that
 ** implement SQL functions and aggregates.  See
@@ -4411,6 +4563,10 @@ typedef void (*sqlite3_destructor_type)(void*);
 ** set the return value of the application-defined function to be
 ** a text string which is represented as UTF-8, UTF-16 native byte order,
 ** UTF-16 little endian, or UTF-16 big endian, respectively.
+** ^The sqlite3_result_text64() interface sets the return value of an
+** application-defined function to be a text string in an encoding
+** specified by the fifth (and last) parameter, which must be one
+** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE].
 ** ^SQLite takes the text result from the application from
 ** the 2nd parameter of the sqlite3_result_text* interfaces.
 ** ^If the 3rd parameter to the sqlite3_result_text* interfaces
@@ -4453,25 +4609,30 @@ typedef void (*sqlite3_destructor_type)(void*);
 ** than the one containing the application-defined function that received
 ** the [sqlite3_context] pointer, the results are undefined.
 */
-SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_double(sqlite3_context*, double);
-SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int);
-SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int);
-SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*);
-SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*);
-SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int);
-SQLITE_API void sqlite3_result_int(sqlite3_context*, int);
-SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
-SQLITE_API void sqlite3_result_null(sqlite3_context*);
-SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
-SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
-SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*);
-SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_blob64(sqlite3_context*,const void*,
+                           sqlite3_uint64,void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_double(sqlite3_context*, double);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error(sqlite3_context*, const char*, int);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error16(sqlite3_context*, const void*, int);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error_toobig(sqlite3_context*);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error_nomem(sqlite3_context*);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_error_code(sqlite3_context*, int);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_int(sqlite3_context*, int);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_int64(sqlite3_context*, sqlite3_int64);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_null(sqlite3_context*);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64,
+                           void(*)(void*), unsigned char encoding);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*));
+SQLITE_API void SQLITE_STDCALL sqlite3_result_value(sqlite3_context*, sqlite3_value*);
+SQLITE_API void SQLITE_STDCALL sqlite3_result_zeroblob(sqlite3_context*, int n);
 
 /*
 ** CAPI3REF: Define New Collating Sequences
+** METHOD: sqlite3
 **
 ** ^These functions add, remove, or modify a [collation] associated
 ** with the [database connection] specified as the first argument.
@@ -4549,14 +4710,14 @@ SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n);
 **
 ** See also:  [sqlite3_collation_needed()] and [sqlite3_collation_needed16()].
 */
-SQLITE_API int sqlite3_create_collation(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_collation(
   sqlite3*, 
   const char *zName, 
   int eTextRep, 
   void *pArg,
   int(*xCompare)(void*,int,const void*,int,const void*)
 );
-SQLITE_API int sqlite3_create_collation_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_collation_v2(
   sqlite3*, 
   const char *zName, 
   int eTextRep, 
@@ -4564,7 +4725,7 @@ SQLITE_API int sqlite3_create_collation_v2(
   int(*xCompare)(void*,int,const void*,int,const void*),
   void(*xDestroy)(void*)
 );
-SQLITE_API int sqlite3_create_collation16(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_collation16(
   sqlite3*, 
   const void *zName,
   int eTextRep, 
@@ -4574,6 +4735,7 @@ SQLITE_API int sqlite3_create_collation16(
 
 /*
 ** CAPI3REF: Collation Needed Callbacks
+** METHOD: sqlite3
 **
 ** ^To avoid having to register all collation sequences before a database
 ** can be used, a single callback function may be registered with the
@@ -4598,12 +4760,12 @@ SQLITE_API int sqlite3_create_collation16(
 ** [sqlite3_create_collation()], [sqlite3_create_collation16()], or
 ** [sqlite3_create_collation_v2()].
 */
-SQLITE_API int sqlite3_collation_needed(
+SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed(
   sqlite3*, 
   void*, 
   void(*)(void*,sqlite3*,int eTextRep,const char*)
 );
-SQLITE_API int sqlite3_collation_needed16(
+SQLITE_API int SQLITE_STDCALL sqlite3_collation_needed16(
   sqlite3*, 
   void*,
   void(*)(void*,sqlite3*,int eTextRep,const void*)
@@ -4617,11 +4779,11 @@ SQLITE_API int sqlite3_collation_needed16(
 ** The code to implement this API is not available in the public release
 ** of SQLite.
 */
-SQLITE_API int sqlite3_key(
+SQLITE_API int SQLITE_STDCALL sqlite3_key(
   sqlite3 *db,                   /* Database to be rekeyed */
   const void *pKey, int nKey     /* The key */
 );
-SQLITE_API int sqlite3_key_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_key_v2(
   sqlite3 *db,                   /* Database to be rekeyed */
   const char *zDbName,           /* Name of the database */
   const void *pKey, int nKey     /* The key */
@@ -4635,11 +4797,11 @@ SQLITE_API int sqlite3_key_v2(
 ** The code to implement this API is not available in the public release
 ** of SQLite.
 */
-SQLITE_API int sqlite3_rekey(
+SQLITE_API int SQLITE_STDCALL sqlite3_rekey(
   sqlite3 *db,                   /* Database to be rekeyed */
   const void *pKey, int nKey     /* The new key */
 );
-SQLITE_API int sqlite3_rekey_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_rekey_v2(
   sqlite3 *db,                   /* Database to be rekeyed */
   const char *zDbName,           /* Name of the database */
   const void *pKey, int nKey     /* The new key */
@@ -4649,7 +4811,7 @@ SQLITE_API int sqlite3_rekey_v2(
 ** Specify the activation key for a SEE database.  Unless 
 ** activated, none of the SEE routines will work.
 */
-SQLITE_API void sqlite3_activate_see(
+SQLITE_API void SQLITE_STDCALL sqlite3_activate_see(
   const char *zPassPhrase        /* Activation phrase */
 );
 #endif
@@ -4659,7 +4821,7 @@ SQLITE_API void sqlite3_activate_see(
 ** Specify the activation key for a CEROD database.  Unless 
 ** activated, none of the CEROD routines will work.
 */
-SQLITE_API void sqlite3_activate_cerod(
+SQLITE_API void SQLITE_STDCALL sqlite3_activate_cerod(
   const char *zPassPhrase        /* Activation phrase */
 );
 #endif
@@ -4681,7 +4843,7 @@ SQLITE_API void sqlite3_activate_cerod(
 ** all, then the behavior of sqlite3_sleep() may deviate from the description
 ** in the previous paragraphs.
 */
-SQLITE_API int sqlite3_sleep(int);
+SQLITE_API int SQLITE_STDCALL sqlite3_sleep(int);
 
 /*
 ** CAPI3REF: Name Of The Folder Holding Temporary Files
@@ -4781,6 +4943,7 @@ SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory;
 /*
 ** CAPI3REF: Test For Auto-Commit Mode
 ** KEYWORDS: {autocommit mode}
+** METHOD: sqlite3
 **
 ** ^The sqlite3_get_autocommit() interface returns non-zero or
 ** zero if the given database connection is or is not in autocommit mode,
@@ -4799,10 +4962,11 @@ SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory;
 ** connection while this routine is running, then the return value
 ** is undefined.
 */
-SQLITE_API int sqlite3_get_autocommit(sqlite3*);
+SQLITE_API int SQLITE_STDCALL sqlite3_get_autocommit(sqlite3*);
 
 /*
 ** CAPI3REF: Find The Database Handle Of A Prepared Statement
+** METHOD: sqlite3_stmt
 **
 ** ^The sqlite3_db_handle interface returns the [database connection] handle
 ** to which a [prepared statement] belongs.  ^The [database connection]
@@ -4811,10 +4975,11 @@ SQLITE_API int sqlite3_get_autocommit(sqlite3*);
 ** to the [sqlite3_prepare_v2()] call (or its variants) that was used to
 ** create the statement in the first place.
 */
-SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
+SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3_db_handle(sqlite3_stmt*);
 
 /*
 ** CAPI3REF: Return The Filename For A Database Connection
+** METHOD: sqlite3
 **
 ** ^The sqlite3_db_filename(D,N) interface returns a pointer to a filename
 ** associated with database N of connection D.  ^The main database file
@@ -4827,19 +4992,21 @@ SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
 ** will be an absolute pathname, even if the filename used
 ** to open the database originally was a URI or relative pathname.
 */
-SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
+SQLITE_API const char *SQLITE_STDCALL sqlite3_db_filename(sqlite3 *db, const char *zDbName);
 
 /*
 ** CAPI3REF: Determine if a database is read-only
+** METHOD: sqlite3
 **
 ** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N
 ** of connection D is read-only, 0 if it is read/write, or -1 if N is not
 ** the name of a database on connection D.
 */
-SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
+SQLITE_API int SQLITE_STDCALL sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
 
 /*
 ** CAPI3REF: Find the next prepared statement
+** METHOD: sqlite3
 **
 ** ^This interface returns a pointer to the next [prepared statement] after
 ** pStmt associated with the [database connection] pDb.  ^If pStmt is NULL
@@ -4851,10 +5018,11 @@ SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName);
 ** [sqlite3_next_stmt(D,S)] must refer to an open database
 ** connection and in particular must not be a NULL pointer.
 */
-SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
+SQLITE_API sqlite3_stmt *SQLITE_STDCALL sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
 
 /*
 ** CAPI3REF: Commit And Rollback Notification Callbacks
+** METHOD: sqlite3
 **
 ** ^The sqlite3_commit_hook() interface registers a callback
 ** function to be invoked whenever a transaction is [COMMIT | committed].
@@ -4899,11 +5067,12 @@ SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
 **
 ** See also the [sqlite3_update_hook()] interface.
 */
-SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
-SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
+SQLITE_API void *SQLITE_STDCALL sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
+SQLITE_API void *SQLITE_STDCALL sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
 
 /*
 ** CAPI3REF: Data Change Notification Callbacks
+** METHOD: sqlite3
 **
 ** ^The sqlite3_update_hook() interface registers a callback function
 ** with the [database connection] identified by the first argument
@@ -4950,7 +5119,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
 ** See also the [sqlite3_commit_hook()] and [sqlite3_rollback_hook()]
 ** interfaces.
 */
-SQLITE_API void *sqlite3_update_hook(
+SQLITE_API void *SQLITE_STDCALL sqlite3_update_hook(
   sqlite3*, 
   void(*)(void *,int ,char const *,char const *,sqlite3_int64),
   void*
@@ -4980,12 +5149,17 @@ SQLITE_API void *sqlite3_update_hook(
 ** future releases of SQLite.  Applications that care about shared
 ** cache setting should set it explicitly.
 **
+** Note: This method is disabled on MacOS X 10.7 and iOS version 5.0
+** and will always return SQLITE_MISUSE. On those systems, 
+** shared cache mode should be enabled per-database connection via 
+** [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE].
+**
 ** This interface is threadsafe on processors where writing a
 ** 32-bit integer is atomic.
 **
 ** See Also:  [SQLite Shared-Cache Mode]
 */
-SQLITE_API int sqlite3_enable_shared_cache(int);
+SQLITE_API int SQLITE_STDCALL sqlite3_enable_shared_cache(int);
 
 /*
 ** CAPI3REF: Attempt To Free Heap Memory
@@ -5001,10 +5175,11 @@ SQLITE_API int sqlite3_enable_shared_cache(int);
 **
 ** See also: [sqlite3_db_release_memory()]
 */
-SQLITE_API int sqlite3_release_memory(int);
+SQLITE_API int SQLITE_STDCALL sqlite3_release_memory(int);
 
 /*
 ** CAPI3REF: Free Memory Used By A Database Connection
+** METHOD: sqlite3
 **
 ** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap
 ** memory as possible from database connection D. Unlike the
@@ -5014,7 +5189,7 @@ SQLITE_API int sqlite3_release_memory(int);
 **
 ** See also: [sqlite3_release_memory()]
 */
-SQLITE_API int sqlite3_db_release_memory(sqlite3*);
+SQLITE_API int SQLITE_STDCALL sqlite3_db_release_memory(sqlite3*);
 
 /*
 ** CAPI3REF: Impose A Limit On Heap Size
@@ -5066,7 +5241,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*);
 ** The circumstances under which SQLite will enforce the soft heap limit may
 ** changes in future releases of SQLite.
 */
-SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_soft_heap_limit64(sqlite3_int64 N);
 
 /*
 ** CAPI3REF: Deprecated Soft Heap Limit Interface
@@ -5077,26 +5252,34 @@ SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N);
 ** only.  All new applications should use the
 ** [sqlite3_soft_heap_limit64()] interface rather than this one.
 */
-SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
+SQLITE_API SQLITE_DEPRECATED void SQLITE_STDCALL sqlite3_soft_heap_limit(int N);
 
 
 /*
 ** CAPI3REF: Extract Metadata About A Column Of A Table
-**
-** ^This routine returns metadata about a specific column of a specific
-** database table accessible using the [database connection] handle
-** passed as the first function argument.
+** METHOD: sqlite3
+**
+** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns
+** information about column C of table T in database D
+** on [database connection] X.)^  ^The sqlite3_table_column_metadata()
+** interface returns SQLITE_OK and fills in the non-NULL pointers in
+** the final five arguments with appropriate values if the specified
+** column exists.  ^The sqlite3_table_column_metadata() interface returns
+** SQLITE_ERROR and if the specified column does not exist.
+** ^If the column-name parameter to sqlite3_table_column_metadata() is a
+** NULL pointer, then this routine simply checks for the existance of the
+** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it
+** does not.
 **
 ** ^The column is identified by the second, third and fourth parameters to
-** this function. ^The second parameter is either the name of the database
+** this function. ^(The second parameter is either the name of the database
 ** (i.e. "main", "temp", or an attached database) containing the specified
-** table or NULL. ^If it is NULL, then all attached databases are searched
+** table or NULL.)^ ^If it is NULL, then all attached databases are searched
 ** for the table using the same algorithm used by the database engine to
 ** resolve unqualified table references.
 **
 ** ^The third and fourth parameters to this function are the table and column
-** name of the desired column, respectively. Neither of these parameters
-** may be NULL.
+** name of the desired column, respectively.
 **
 ** ^Metadata is returned by writing to the memory locations passed as the 5th
 ** and subsequent parameters to this function. ^Any of these arguments may be
@@ -5115,16 +5298,17 @@ SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
 ** </blockquote>)^
 **
 ** ^The memory pointed to by the character pointers returned for the
-** declaration type and collation sequence is valid only until the next
+** declaration type and collation sequence is valid until the next
 ** call to any SQLite API function.
 **
 ** ^If the specified table is actually a view, an [error code] is returned.
 **
-** ^If the specified column is "rowid", "oid" or "_rowid_" and an
+** ^If the specified column is "rowid", "oid" or "_rowid_" and the table 
+** is not a [WITHOUT ROWID] table and an
 ** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output
 ** parameters are set for the explicitly declared column. ^(If there is no
-** explicitly declared [INTEGER PRIMARY KEY] column, then the output
-** parameters are set as follows:
+** [INTEGER PRIMARY KEY] column, then the outputs
+** for the [rowid] are set as follows:
 **
 ** <pre>
 **     data type: "INTEGER"
@@ -5134,15 +5318,11 @@ SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);
 **     auto increment: 0
 ** </pre>)^
 **
-** ^(This function may load one or more schemas from database files. If an
-** error occurs during this process, or if the requested table or column
-** cannot be found, an [error code] is returned and an error message left
-** in the [database connection] (to be retrieved using sqlite3_errmsg()).)^
-**
-** ^This API is only available if the library was compiled with the
-** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined.
+** ^This function causes all database schemas to be read from disk and
+** parsed, if that has not already been done, and returns an error if
+** any errors are encountered while loading the schema.
 */
-SQLITE_API int sqlite3_table_column_metadata(
+SQLITE_API int SQLITE_STDCALL sqlite3_table_column_metadata(
   sqlite3 *db,                /* Connection handle */
   const char *zDbName,        /* Database name or NULL */
   const char *zTableName,     /* Table name */
@@ -5156,6 +5336,7 @@ SQLITE_API int sqlite3_table_column_metadata(
 
 /*
 ** CAPI3REF: Load An Extension
+** METHOD: sqlite3
 **
 ** ^This interface loads an SQLite extension library from the named file.
 **
@@ -5188,7 +5369,7 @@ SQLITE_API int sqlite3_table_column_metadata(
 **
 ** See also the [load_extension() SQL function].
 */
-SQLITE_API int sqlite3_load_extension(
+SQLITE_API int SQLITE_STDCALL sqlite3_load_extension(
   sqlite3 *db,          /* Load the extension into this database connection */
   const char *zFile,    /* Name of the shared library containing extension */
   const char *zProc,    /* Entry point.  Derived from zFile if 0 */
@@ -5197,6 +5378,7 @@ SQLITE_API int sqlite3_load_extension(
 
 /*
 ** CAPI3REF: Enable Or Disable Extension Loading
+** METHOD: sqlite3
 **
 ** ^So as not to open security holes in older applications that are
 ** unprepared to deal with [extension loading], and as a means of disabling
@@ -5208,7 +5390,7 @@ SQLITE_API int sqlite3_load_extension(
 ** to turn extension loading on and call it with onoff==0 to turn
 ** it back off again.
 */
-SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
+SQLITE_API int SQLITE_STDCALL sqlite3_enable_load_extension(sqlite3 *db, int onoff);
 
 /*
 ** CAPI3REF: Automatically Load Statically Linked Extensions
@@ -5246,7 +5428,7 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
 ** See also: [sqlite3_reset_auto_extension()]
 ** and [sqlite3_cancel_auto_extension()]
 */
-SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
+SQLITE_API int SQLITE_STDCALL sqlite3_auto_extension(void (*xEntryPoint)(void));
 
 /*
 ** CAPI3REF: Cancel Automatic Extension Loading
@@ -5258,7 +5440,7 @@ SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
 ** unregistered and it returns 0 if X was not on the list of initialization
 ** routines.
 */
-SQLITE_API int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void));
+SQLITE_API int SQLITE_STDCALL sqlite3_cancel_auto_extension(void (*xEntryPoint)(void));
 
 /*
 ** CAPI3REF: Reset Automatic Extension Loading
@@ -5266,7 +5448,7 @@ SQLITE_API int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void));
 ** ^This interface disables all automatic extensions previously
 ** registered using [sqlite3_auto_extension()].
 */
-SQLITE_API void sqlite3_reset_auto_extension(void);
+SQLITE_API void SQLITE_STDCALL sqlite3_reset_auto_extension(void);
 
 /*
 ** The interface to the virtual-table mechanism is currently considered
@@ -5446,6 +5628,7 @@ struct sqlite3_index_info {
 
 /*
 ** CAPI3REF: Register A Virtual Table Implementation
+** METHOD: sqlite3
 **
 ** ^These routines are used to register a new [virtual table module] name.
 ** ^Module names must be registered before
@@ -5469,13 +5652,13 @@ struct sqlite3_index_info {
 ** interface is equivalent to sqlite3_create_module_v2() with a NULL
 ** destructor.
 */
-SQLITE_API int sqlite3_create_module(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_module(
   sqlite3 *db,               /* SQLite connection to register module with */
   const char *zName,         /* Name of the module */
   const sqlite3_module *p,   /* Methods for the module */
   void *pClientData          /* Client data for xCreate/xConnect */
 );
-SQLITE_API int sqlite3_create_module_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_create_module_v2(
   sqlite3 *db,               /* SQLite connection to register module with */
   const char *zName,         /* Name of the module */
   const sqlite3_module *p,   /* Methods for the module */
@@ -5503,7 +5686,7 @@ SQLITE_API int sqlite3_create_module_v2(
 */
 struct sqlite3_vtab {
   const sqlite3_module *pModule;  /* The module for this virtual table */
-  int nRef;                       /* NO LONGER USED */
+  int nRef;                       /* Number of open cursors */
   char *zErrMsg;                  /* Error message from sqlite3_mprintf() */
   /* Virtual table implementations will typically add additional fields */
 };
@@ -5538,10 +5721,11 @@ struct sqlite3_vtab_cursor {
 ** to declare the format (the names and datatypes of the columns) of
 ** the virtual tables they implement.
 */
-SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
+SQLITE_API int SQLITE_STDCALL sqlite3_declare_vtab(sqlite3*, const char *zSQL);
 
 /*
 ** CAPI3REF: Overload A Function For A Virtual Table
+** METHOD: sqlite3
 **
 ** ^(Virtual tables can provide alternative implementations of functions
 ** using the [xFindFunction] method of the [virtual table module].  
@@ -5556,7 +5740,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL);
 ** purpose is to be a placeholder function that can be overloaded
 ** by a [virtual table].
 */
-SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
+SQLITE_API int SQLITE_STDCALL sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg);
 
 /*
 ** The interface to the virtual-table mechanism defined above (back up
@@ -5584,6 +5768,8 @@ typedef struct sqlite3_blob sqlite3_blob;
 
 /*
 ** CAPI3REF: Open A BLOB For Incremental I/O
+** METHOD: sqlite3
+** CONSTRUCTOR: sqlite3_blob
 **
 ** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located
 ** in row iRow, column zColumn, table zTable in database zDb;
@@ -5593,26 +5779,42 @@ typedef struct sqlite3_blob sqlite3_blob;
 **     SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow;
 ** </pre>)^
 **
+** ^(Parameter zDb is not the filename that contains the database, but 
+** rather the symbolic name of the database. For attached databases, this is
+** the name that appears after the AS keyword in the [ATTACH] statement.
+** For the main database file, the database name is "main". For TEMP
+** tables, the database name is "temp".)^
+**
 ** ^If the flags parameter is non-zero, then the BLOB is opened for read
-** and write access. ^If it is zero, the BLOB is opened for read access.
-** ^It is not possible to open a column that is part of an index or primary 
-** key for writing. ^If [foreign key constraints] are enabled, it is 
-** not possible to open a column that is part of a [child key] for writing.
-**
-** ^Note that the database name is not the filename that contains
-** the database but rather the symbolic name of the database that
-** appears after the AS keyword when the database is connected using [ATTACH].
-** ^For the main database file, the database name is "main".
-** ^For TEMP tables, the database name is "temp".
-**
-** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is written
-** to *ppBlob. Otherwise an [error code] is returned and *ppBlob is set
-** to be a null pointer.)^
-** ^This function sets the [database connection] error code and message
-** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()] and related
-** functions. ^Note that the *ppBlob variable is always initialized in a
-** way that makes it safe to invoke [sqlite3_blob_close()] on *ppBlob
-** regardless of the success or failure of this routine.
+** and write access. ^If the flags parameter is zero, the BLOB is opened for
+** read-only access.
+**
+** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored
+** in *ppBlob. Otherwise an [error code] is returned and, unless the error
+** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided
+** the API is not misused, it is always safe to call [sqlite3_blob_close()] 
+** on *ppBlob after this function it returns.
+**
+** This function fails with SQLITE_ERROR if any of the following are true:
+** <ul>
+**   <li> ^(Database zDb does not exist)^, 
+**   <li> ^(Table zTable does not exist within database zDb)^, 
+**   <li> ^(Table zTable is a WITHOUT ROWID table)^, 
+**   <li> ^(Column zColumn does not exist)^,
+**   <li> ^(Row iRow is not present in the table)^,
+**   <li> ^(The specified column of row iRow contains a value that is not
+**         a TEXT or BLOB value)^,
+**   <li> ^(Column zColumn is part of an index, PRIMARY KEY or UNIQUE 
+**         constraint and the blob is being opened for read/write access)^,
+**   <li> ^([foreign key constraints | Foreign key constraints] are enabled, 
+**         column zColumn is part of a [child key] definition and the blob is
+**         being opened for read/write access)^.
+** </ul>
+**
+** ^Unless it returns SQLITE_MISUSE, this function sets the 
+** [database connection] error code and message accessible via 
+** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. 
+**
 **
 ** ^(If the row that a BLOB handle points to is modified by an
 ** [UPDATE], [DELETE], or by [ON CONFLICT] side-effects
@@ -5630,18 +5832,14 @@ typedef struct sqlite3_blob sqlite3_blob;
 ** interface.  Use the [UPDATE] SQL command to change the size of a
 ** blob.
 **
-** ^The [sqlite3_blob_open()] interface will fail for a [WITHOUT ROWID]
-** table.  Incremental BLOB I/O is not possible on [WITHOUT ROWID] tables.
-**
 ** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces
-** and the built-in [zeroblob] SQL function can be used, if desired,
-** to create an empty, zero-filled blob in which to read or write using
-** this interface.
+** and the built-in [zeroblob] SQL function may be used to create a 
+** zero-filled blob to read or write using the incremental-blob interface.
 **
 ** To avoid a resource leak, every open [BLOB handle] should eventually
 ** be released by a call to [sqlite3_blob_close()].
 */
-SQLITE_API int sqlite3_blob_open(
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_open(
   sqlite3*,
   const char *zDb,
   const char *zTable,
@@ -5653,6 +5851,7 @@ SQLITE_API int sqlite3_blob_open(
 
 /*
 ** CAPI3REF: Move a BLOB Handle to a New Row
+** METHOD: sqlite3_blob
 **
 ** ^This function is used to move an existing blob handle so that it points
 ** to a different row of the same database table. ^The new row is identified
@@ -5673,34 +5872,34 @@ SQLITE_API int sqlite3_blob_open(
 **
 ** ^This function sets the database handle error code and message.
 */
-SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
+SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
 
 /*
 ** CAPI3REF: Close A BLOB Handle
+** DESTRUCTOR: sqlite3_blob
 **
-** ^Closes an open [BLOB handle].
-**
-** ^Closing a BLOB shall cause the current transaction to commit
-** if there are no other BLOBs, no pending prepared statements, and the
-** database connection is in [autocommit mode].
-** ^If any writes were made to the BLOB, they might be held in cache
-** until the close operation if they will fit.
-**
-** ^(Closing the BLOB often forces the changes
-** out to disk and so if any I/O errors occur, they will likely occur
-** at the time when the BLOB is closed.  Any errors that occur during
-** closing are reported as a non-zero return value.)^
+** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed
+** unconditionally.  Even if this routine returns an error code, the 
+** handle is still closed.)^
 **
-** ^(The BLOB is closed unconditionally.  Even if this routine returns
-** an error code, the BLOB is still closed.)^
+** ^If the blob handle being closed was opened for read-write access, and if
+** the database is in auto-commit mode and there are no other open read-write
+** blob handles or active write statements, the current transaction is
+** committed. ^If an error occurs while committing the transaction, an error
+** code is returned and the transaction rolled back.
 **
-** ^Calling this routine with a null pointer (such as would be returned
-** by a failed call to [sqlite3_blob_open()]) is a harmless no-op.
+** Calling this function with an argument that is not a NULL pointer or an
+** open blob handle results in undefined behaviour. ^Calling this routine 
+** with a null pointer (such as would be returned by a failed call to 
+** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function
+** is passed a valid open blob handle, the values returned by the 
+** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning.
 */
-SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_close(sqlite3_blob *);
 
 /*
 ** CAPI3REF: Return The Size Of An Open BLOB
+** METHOD: sqlite3_blob
 **
 ** ^Returns the size in bytes of the BLOB accessible via the 
 ** successfully opened [BLOB handle] in its only argument.  ^The
@@ -5712,10 +5911,11 @@ SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
 ** been closed by [sqlite3_blob_close()].  Passing any other pointer in
 ** to this routine results in undefined and probably undesirable behavior.
 */
-SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_bytes(sqlite3_blob *);
 
 /*
 ** CAPI3REF: Read Data From A BLOB Incrementally
+** METHOD: sqlite3_blob
 **
 ** ^(This function is used to read data from an open [BLOB handle] into a
 ** caller-supplied buffer. N bytes of data are copied into buffer Z
@@ -5740,26 +5940,33 @@ SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
 **
 ** See also: [sqlite3_blob_write()].
 */
-SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
 
 /*
 ** CAPI3REF: Write Data Into A BLOB Incrementally
+** METHOD: sqlite3_blob
 **
-** ^This function is used to write data into an open [BLOB handle] from a
-** caller-supplied buffer. ^N bytes of data are copied from the buffer Z
-** into the open BLOB, starting at offset iOffset.
+** ^(This function is used to write data into an open [BLOB handle] from a
+** caller-supplied buffer. N bytes of data are copied from the buffer Z
+** into the open BLOB, starting at offset iOffset.)^
+**
+** ^(On success, sqlite3_blob_write() returns SQLITE_OK.
+** Otherwise, an  [error code] or an [extended error code] is returned.)^
+** ^Unless SQLITE_MISUSE is returned, this function sets the 
+** [database connection] error code and message accessible via 
+** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. 
 **
 ** ^If the [BLOB handle] passed as the first argument was not opened for
 ** writing (the flags parameter to [sqlite3_blob_open()] was zero),
 ** this function returns [SQLITE_READONLY].
 **
-** ^This function may only modify the contents of the BLOB; it is
+** This function may only modify the contents of the BLOB; it is
 ** not possible to increase the size of a BLOB using this API.
 ** ^If offset iOffset is less than N bytes from the end of the BLOB,
-** [SQLITE_ERROR] is returned and no data is written.  ^If N is
-** less than zero [SQLITE_ERROR] is returned and no data is written.
-** The size of the BLOB (and hence the maximum value of N+iOffset)
-** can be determined using the [sqlite3_blob_bytes()] interface.
+** [SQLITE_ERROR] is returned and no data is written. The size of the 
+** BLOB (and hence the maximum value of N+iOffset) can be determined 
+** using the [sqlite3_blob_bytes()] interface. ^If N or iOffset are less 
+** than zero [SQLITE_ERROR] is returned and no data is written.
 **
 ** ^An attempt to write to an expired [BLOB handle] fails with an
 ** error code of [SQLITE_ABORT].  ^Writes to the BLOB that occurred
@@ -5768,9 +5975,6 @@ SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
 ** have been overwritten by the statement that expired the BLOB handle
 ** or by other independent statements.
 **
-** ^(On success, sqlite3_blob_write() returns SQLITE_OK.
-** Otherwise, an  [error code] or an [extended error code] is returned.)^
-**
 ** This routine only works on a [BLOB handle] which has been created
 ** by a prior successful call to [sqlite3_blob_open()] and which has not
 ** been closed by [sqlite3_blob_close()].  Passing any other pointer in
@@ -5778,7 +5982,7 @@ SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
 **
 ** See also: [sqlite3_blob_read()].
 */
-SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
 
 /*
 ** CAPI3REF: Virtual File System Objects
@@ -5809,9 +6013,9 @@ SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOff
 ** ^(If the default VFS is unregistered, another VFS is chosen as
 ** the default.  The choice for the new VFS is arbitrary.)^
 */
-SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName);
-SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
-SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
+SQLITE_API sqlite3_vfs *SQLITE_STDCALL sqlite3_vfs_find(const char *zVfsName);
+SQLITE_API int SQLITE_STDCALL sqlite3_vfs_register(sqlite3_vfs*, int makeDflt);
+SQLITE_API int SQLITE_STDCALL sqlite3_vfs_unregister(sqlite3_vfs*);
 
 /*
 ** CAPI3REF: Mutexes
@@ -5823,34 +6027,34 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
 **
 ** The SQLite source code contains multiple implementations
 ** of these mutex routines.  An appropriate implementation
-** is selected automatically at compile-time.  ^(The following
+** is selected automatically at compile-time.  The following
 ** implementations are available in the SQLite core:
 **
 ** <ul>
 ** <li>   SQLITE_MUTEX_PTHREADS
 ** <li>   SQLITE_MUTEX_W32
 ** <li>   SQLITE_MUTEX_NOOP
-** </ul>)^
+** </ul>
 **
-** ^The SQLITE_MUTEX_NOOP implementation is a set of routines
+** The SQLITE_MUTEX_NOOP implementation is a set of routines
 ** that does no real locking and is appropriate for use in
-** a single-threaded application.  ^The SQLITE_MUTEX_PTHREADS and
+** a single-threaded application.  The SQLITE_MUTEX_PTHREADS and
 ** SQLITE_MUTEX_W32 implementations are appropriate for use on Unix
 ** and Windows.
 **
-** ^(If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
+** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
 ** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
 ** implementation is included with the library. In this case the
 ** application must supply a custom mutex implementation using the
 ** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function
 ** before calling sqlite3_initialize() or any other public sqlite3_
-** function that calls sqlite3_initialize().)^
+** function that calls sqlite3_initialize().
 **
 ** ^The sqlite3_mutex_alloc() routine allocates a new
-** mutex and returns a pointer to it. ^If it returns NULL
-** that means that a mutex could not be allocated.  ^SQLite
-** will unwind its stack and return an error.  ^(The argument
-** to sqlite3_mutex_alloc() is one of these integer constants:
+** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc()
+** routine returns NULL if it is unable to allocate the requested
+** mutex.  The argument to sqlite3_mutex_alloc() must one of these
+** integer constants:
 **
 ** <ul>
 ** <li>  SQLITE_MUTEX_FAST
@@ -5863,7 +6067,8 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
 ** <li>  SQLITE_MUTEX_STATIC_PMEM
 ** <li>  SQLITE_MUTEX_STATIC_APP1
 ** <li>  SQLITE_MUTEX_STATIC_APP2
-** </ul>)^
+** <li>  SQLITE_MUTEX_STATIC_APP3
+** </ul>
 **
 ** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE)
 ** cause sqlite3_mutex_alloc() to create
@@ -5871,14 +6076,14 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
 ** is used but not necessarily so when SQLITE_MUTEX_FAST is used.
 ** The mutex implementation does not need to make a distinction
 ** between SQLITE_MUTEX_RECURSIVE and SQLITE_MUTEX_FAST if it does
-** not want to.  ^SQLite will only request a recursive mutex in
-** cases where it really needs one.  ^If a faster non-recursive mutex
+** not want to.  SQLite will only request a recursive mutex in
+** cases where it really needs one.  If a faster non-recursive mutex
 ** implementation is available on the host platform, the mutex subsystem
 ** might return such a mutex in response to SQLITE_MUTEX_FAST.
 **
 ** ^The other allowed parameters to sqlite3_mutex_alloc() (anything other
 ** than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return
-** a pointer to a static preexisting mutex.  ^Six static mutexes are
+** a pointer to a static preexisting mutex.  ^Nine static mutexes are
 ** used by the current version of SQLite.  Future versions of SQLite
 ** may add additional static mutexes.  Static mutexes are for internal
 ** use by SQLite only.  Applications that use SQLite mutexes should
@@ -5887,16 +6092,13 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
 **
 ** ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST
 ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
-** returns a different mutex on every call.  ^But for the static
+** returns a different mutex on every call.  ^For the static
 ** mutex types, the same mutex is returned on every call that has
 ** the same type number.
 **
 ** ^The sqlite3_mutex_free() routine deallocates a previously
-** allocated dynamic mutex.  ^SQLite is careful to deallocate every
-** dynamic mutex that it allocates.  The dynamic mutexes must not be in
-** use when they are deallocated.  Attempting to deallocate a static
-** mutex results in undefined behavior.  ^SQLite never deallocates
-** a static mutex.
+** allocated dynamic mutex.  Attempting to deallocate a static
+** mutex results in undefined behavior.
 **
 ** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
 ** to enter a mutex.  ^If another thread is already within the mutex,
@@ -5904,23 +6106,21 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
 ** SQLITE_BUSY.  ^The sqlite3_mutex_try() interface returns [SQLITE_OK]
 ** upon successful entry.  ^(Mutexes created using
 ** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread.
-** In such cases the,
+** In such cases, the
 ** mutex must be exited an equal number of times before another thread
-** can enter.)^  ^(If the same thread tries to enter any other
-** kind of mutex more than once, the behavior is undefined.
-** SQLite will never exhibit
-** such behavior in its own use of mutexes.)^
+** can enter.)^  If the same thread tries to enter any mutex other
+** than an SQLITE_MUTEX_RECURSIVE more than once, the behavior is undefined.
 **
 ** ^(Some systems (for example, Windows 95) do not support the operation
 ** implemented by sqlite3_mutex_try().  On those systems, sqlite3_mutex_try()
-** will always return SQLITE_BUSY.  The SQLite core only ever uses
-** sqlite3_mutex_try() as an optimization so this is acceptable behavior.)^
+** will always return SQLITE_BUSY. The SQLite core only ever uses
+** sqlite3_mutex_try() as an optimization so this is acceptable 
+** behavior.)^
 **
 ** ^The sqlite3_mutex_leave() routine exits a mutex that was
-** previously entered by the same thread.   ^(The behavior
+** previously entered by the same thread.   The behavior
 ** is undefined if the mutex is not currently entered by the
-** calling thread or is not currently allocated.  SQLite will
-** never do either.)^
+** calling thread or is not currently allocated.
 **
 ** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or
 ** sqlite3_mutex_leave() is a NULL pointer, then all three routines
@@ -5928,11 +6128,11 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*);
 **
 ** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()].
 */
-SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
-SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*);
-SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*);
-SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*);
-SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
+SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_mutex_alloc(int);
+SQLITE_API void SQLITE_STDCALL sqlite3_mutex_free(sqlite3_mutex*);
+SQLITE_API void SQLITE_STDCALL sqlite3_mutex_enter(sqlite3_mutex*);
+SQLITE_API int SQLITE_STDCALL sqlite3_mutex_try(sqlite3_mutex*);
+SQLITE_API void SQLITE_STDCALL sqlite3_mutex_leave(sqlite3_mutex*);
 
 /*
 ** CAPI3REF: Mutex Methods Object
@@ -5941,9 +6141,9 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
 ** used to allocate and use mutexes.
 **
 ** Usually, the default mutex implementations provided by SQLite are
-** sufficient, however the user has the option of substituting a custom
+** sufficient, however the application has the option of substituting a custom
 ** implementation for specialized deployments or systems for which SQLite
-** does not provide a suitable implementation. In this case, the user
+** does not provide a suitable implementation. In this case, the application
 ** creates and populates an instance of this structure to pass
 ** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option.
 ** Additionally, an instance of this structure can be used as an
@@ -5984,13 +6184,13 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
 ** (i.e. it is acceptable to provide an implementation that segfaults if
 ** it is passed a NULL pointer).
 **
-** The xMutexInit() method must be threadsafe.  ^It must be harmless to
+** The xMutexInit() method must be threadsafe.  It must be harmless to
 ** invoke xMutexInit() multiple times within the same process and without
 ** intervening calls to xMutexEnd().  Second and subsequent calls to
 ** xMutexInit() must be no-ops.
 **
-** ^xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()]
-** and its associates).  ^Similarly, xMutexAlloc() must not use SQLite memory
+** xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()]
+** and its associates).  Similarly, xMutexAlloc() must not use SQLite memory
 ** allocation for a static mutex.  ^However xMutexAlloc() may use SQLite
 ** memory allocation for a fast or recursive mutex.
 **
@@ -6016,34 +6216,34 @@ struct sqlite3_mutex_methods {
 ** CAPI3REF: Mutex Verification Routines
 **
 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines
-** are intended for use inside assert() statements.  ^The SQLite core
+** are intended for use inside assert() statements.  The SQLite core
 ** never uses these routines except inside an assert() and applications
-** are advised to follow the lead of the core.  ^The SQLite core only
+** are advised to follow the lead of the core.  The SQLite core only
 ** provides implementations for these routines when it is compiled
-** with the SQLITE_DEBUG flag.  ^External mutex implementations
+** with the SQLITE_DEBUG flag.  External mutex implementations
 ** are only required to provide these routines if SQLITE_DEBUG is
 ** defined and if NDEBUG is not defined.
 **
-** ^These routines should return true if the mutex in their argument
+** These routines should return true if the mutex in their argument
 ** is held or not held, respectively, by the calling thread.
 **
-** ^The implementation is not required to provide versions of these
+** The implementation is not required to provide versions of these
 ** routines that actually work. If the implementation does not provide working
 ** versions of these routines, it should at least provide stubs that always
 ** return true so that one does not get spurious assertion failures.
 **
-** ^If the argument to sqlite3_mutex_held() is a NULL pointer then
+** If the argument to sqlite3_mutex_held() is a NULL pointer then
 ** the routine should return 1.   This seems counter-intuitive since
 ** clearly the mutex cannot be held if it does not exist.  But
 ** the reason the mutex does not exist is because the build is not
 ** using mutexes.  And we do not want the assert() containing the
 ** call to sqlite3_mutex_held() to fail, so a non-zero return is
-** the appropriate thing to do.  ^The sqlite3_mutex_notheld()
+** the appropriate thing to do.  The sqlite3_mutex_notheld()
 ** interface should also return 1 when given a NULL pointer.
 */
 #ifndef NDEBUG
-SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
-SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
+SQLITE_API int SQLITE_STDCALL sqlite3_mutex_held(sqlite3_mutex*);
+SQLITE_API int SQLITE_STDCALL sqlite3_mutex_notheld(sqlite3_mutex*);
 #endif
 
 /*
@@ -6072,6 +6272,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
 
 /*
 ** CAPI3REF: Retrieve the mutex for a database connection
+** METHOD: sqlite3
 **
 ** ^This interface returns a pointer the [sqlite3_mutex] object that 
 ** serializes access to the [database connection] given in the argument
@@ -6079,10 +6280,11 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*);
 ** ^If the [threading mode] is Single-thread or Multi-thread then this
 ** routine returns a NULL pointer.
 */
-SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
+SQLITE_API sqlite3_mutex *SQLITE_STDCALL sqlite3_db_mutex(sqlite3*);
 
 /*
 ** CAPI3REF: Low-Level Control Of Database Files
+** METHOD: sqlite3
 **
 ** ^The [sqlite3_file_control()] interface makes a direct call to the
 ** xFileControl method for the [sqlite3_io_methods] object associated
@@ -6113,7 +6315,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
 **
 ** See also: [SQLITE_FCNTL_LOCKSTATE]
 */
-SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
+SQLITE_API int SQLITE_STDCALL sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*);
 
 /*
 ** CAPI3REF: Testing Interface
@@ -6132,7 +6334,7 @@ SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*
 ** Unlike most of the SQLite API, this function is not guaranteed to
 ** operate consistently from one release to the next.
 */
-SQLITE_API int sqlite3_test_control(int op, ...);
+SQLITE_API int SQLITE_CDECL sqlite3_test_control(int op, ...);
 
 /*
 ** CAPI3REF: Testing Interface Operation Codes
@@ -6160,17 +6362,19 @@ SQLITE_API int sqlite3_test_control(int op, ...);
 #define SQLITE_TESTCTRL_ISKEYWORD               16
 #define SQLITE_TESTCTRL_SCRATCHMALLOC           17
 #define SQLITE_TESTCTRL_LOCALTIME_FAULT         18
-#define SQLITE_TESTCTRL_EXPLAIN_STMT            19
+#define SQLITE_TESTCTRL_EXPLAIN_STMT            19  /* NOT USED */
 #define SQLITE_TESTCTRL_NEVER_CORRUPT           20
 #define SQLITE_TESTCTRL_VDBE_COVERAGE           21
 #define SQLITE_TESTCTRL_BYTEORDER               22
 #define SQLITE_TESTCTRL_ISINIT                  23
-#define SQLITE_TESTCTRL_LAST                    23
+#define SQLITE_TESTCTRL_SORTER_MMAP             24
+#define SQLITE_TESTCTRL_IMPOSTER                25
+#define SQLITE_TESTCTRL_LAST                    25
 
 /*
 ** CAPI3REF: SQLite Runtime Status
 **
-** ^This interface is used to retrieve runtime status information
+** ^These interfaces are used to retrieve runtime status information
 ** about the performance of SQLite, and optionally to reset various
 ** highwater marks.  ^The first argument is an integer code for
 ** the specific parameter to measure.  ^(Recognized integer codes
@@ -6184,19 +6388,22 @@ SQLITE_API int sqlite3_test_control(int op, ...);
 ** ^(Other parameters record only the highwater mark and not the current
 ** value.  For these latter parameters nothing is written into *pCurrent.)^
 **
-** ^The sqlite3_status() routine returns SQLITE_OK on success and a
-** non-zero [error code] on failure.
+** ^The sqlite3_status() and sqlite3_status64() routines return
+** SQLITE_OK on success and a non-zero [error code] on failure.
 **
-** This routine is threadsafe but is not atomic.  This routine can be
-** called while other threads are running the same or different SQLite
-** interfaces.  However the values returned in *pCurrent and
-** *pHighwater reflect the status of SQLite at different points in time
-** and it is possible that another thread might change the parameter
-** in between the times when *pCurrent and *pHighwater are written.
+** If either the current value or the highwater mark is too large to
+** be represented by a 32-bit integer, then the values returned by
+** sqlite3_status() are undefined.
 **
 ** See also: [sqlite3_db_status()]
 */
-SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
+SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
+SQLITE_API int SQLITE_STDCALL sqlite3_status64(
+  int op,
+  sqlite3_int64 *pCurrent,
+  sqlite3_int64 *pHighwater,
+  int resetFlag
+);
 
 
 /*
@@ -6294,6 +6501,7 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF
 
 /*
 ** CAPI3REF: Database Connection Status
+** METHOD: sqlite3
 **
 ** ^This interface is used to retrieve runtime status information 
 ** about a single [database connection].  ^The first argument is the
@@ -6314,7 +6522,7 @@ SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetF
 **
 ** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
 */
-SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
+SQLITE_API int SQLITE_STDCALL sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
 
 /*
 ** CAPI3REF: Status Parameters for database connections
@@ -6356,12 +6564,12 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
 ** the current value is always zero.)^
 **
 ** [[SQLITE_DBSTATUS_CACHE_USED]] ^(<dt>SQLITE_DBSTATUS_CACHE_USED</dt>
-** <dd>This parameter returns the approximate number of of bytes of heap
+** <dd>This parameter returns the approximate number of bytes of heap
 ** memory used by all pager caches associated with the database connection.)^
 ** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0.
 **
 ** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(<dt>SQLITE_DBSTATUS_SCHEMA_USED</dt>
-** <dd>This parameter returns the approximate number of of bytes of heap
+** <dd>This parameter returns the approximate number of bytes of heap
 ** memory used to store the schema for all databases associated
 ** with the connection - main, temp, and any [ATTACH]-ed databases.)^ 
 ** ^The full amount of memory used by the schemas is reported, even if the
@@ -6370,7 +6578,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
 ** ^The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0.
 **
 ** [[SQLITE_DBSTATUS_STMT_USED]] ^(<dt>SQLITE_DBSTATUS_STMT_USED</dt>
-** <dd>This parameter returns the approximate number of of bytes of heap
+** <dd>This parameter returns the approximate number of bytes of heap
 ** and lookaside memory used by all prepared statements associated with
 ** the database connection.)^
 ** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0.
@@ -6422,6 +6630,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
 
 /*
 ** CAPI3REF: Prepared Statement Status
+** METHOD: sqlite3_stmt
 **
 ** ^(Each prepared statement maintains various
 ** [SQLITE_STMTSTATUS counters] that measure the number
@@ -6443,7 +6652,7 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
 **
 ** See also: [sqlite3_status()] and [sqlite3_db_status()].
 */
-SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
+SQLITE_API int SQLITE_STDCALL sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
 
 /*
 ** CAPI3REF: Status Parameters for prepared statements
@@ -6770,6 +6979,10 @@ typedef struct sqlite3_backup sqlite3_backup;
 ** must be different or else sqlite3_backup_init(D,N,S,M) will fail with
 ** an error.
 **
+** ^A call to sqlite3_backup_init() will fail, returning SQLITE_ERROR, if 
+** there is already a read or read-write transaction open on the 
+** destination database.
+**
 ** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is
 ** returned and an error code and error message are stored in the
 ** destination [database connection] D.
@@ -6862,20 +7075,20 @@ typedef struct sqlite3_backup sqlite3_backup;
 ** is not a permanent error and does not affect the return value of
 ** sqlite3_backup_finish().
 **
-** [[sqlite3_backup__remaining()]] [[sqlite3_backup_pagecount()]]
+** [[sqlite3_backup_remaining()]] [[sqlite3_backup_pagecount()]]
 ** <b>sqlite3_backup_remaining() and sqlite3_backup_pagecount()</b>
 **
-** ^Each call to sqlite3_backup_step() sets two values inside
-** the [sqlite3_backup] object: the number of pages still to be backed
-** up and the total number of pages in the source database file.
-** The sqlite3_backup_remaining() and sqlite3_backup_pagecount() interfaces
-** retrieve these two values, respectively.
-**
-** ^The values returned by these functions are only updated by
-** sqlite3_backup_step(). ^If the source database is modified during a backup
-** operation, then the values are not updated to account for any extra
-** pages that need to be updated or the size of the source database file
-** changing.
+** ^The sqlite3_backup_remaining() routine returns the number of pages still
+** to be backed up at the conclusion of the most recent sqlite3_backup_step().
+** ^The sqlite3_backup_pagecount() routine returns the total number of pages
+** in the source database at the conclusion of the most recent
+** sqlite3_backup_step().
+** ^(The values returned by these functions are only updated by
+** sqlite3_backup_step(). If the source database is modified in a way that
+** changes the size of the source database or the number of pages remaining,
+** those changes are not reflected in the output of sqlite3_backup_pagecount()
+** and sqlite3_backup_remaining() until after the next
+** sqlite3_backup_step().)^
 **
 ** <b>Concurrent Usage of Database Handles</b>
 **
@@ -6908,19 +7121,20 @@ typedef struct sqlite3_backup sqlite3_backup;
 ** same time as another thread is invoking sqlite3_backup_step() it is
 ** possible that they return invalid values.
 */
-SQLITE_API sqlite3_backup *sqlite3_backup_init(
+SQLITE_API sqlite3_backup *SQLITE_STDCALL sqlite3_backup_init(
   sqlite3 *pDest,                        /* Destination database handle */
   const char *zDestName,                 /* Destination database name */
   sqlite3 *pSource,                      /* Source database handle */
   const char *zSourceName                /* Source database name */
 );
-SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage);
-SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p);
-SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p);
-SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
+SQLITE_API int SQLITE_STDCALL sqlite3_backup_step(sqlite3_backup *p, int nPage);
+SQLITE_API int SQLITE_STDCALL sqlite3_backup_finish(sqlite3_backup *p);
+SQLITE_API int SQLITE_STDCALL sqlite3_backup_remaining(sqlite3_backup *p);
+SQLITE_API int SQLITE_STDCALL sqlite3_backup_pagecount(sqlite3_backup *p);
 
 /*
 ** CAPI3REF: Unlock Notification
+** METHOD: sqlite3
 **
 ** ^When running in shared-cache mode, a database operation may fail with
 ** an [SQLITE_LOCKED] error if the required locks on the shared-cache or
@@ -7033,7 +7247,7 @@ SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p);
 ** the special "DROP TABLE/INDEX" case, the extended error code is just 
 ** SQLITE_LOCKED.)^
 */
-SQLITE_API int sqlite3_unlock_notify(
+SQLITE_API int SQLITE_STDCALL sqlite3_unlock_notify(
   sqlite3 *pBlocked,                          /* Waiting connection */
   void (*xNotify)(void **apArg, int nArg),    /* Callback function to invoke */
   void *pNotifyArg                            /* Argument to pass to xNotify */
@@ -7048,8 +7262,8 @@ SQLITE_API int sqlite3_unlock_notify(
 ** strings in a case-independent fashion, using the same definition of "case
 ** independence" that SQLite uses internally when comparing identifiers.
 */
-SQLITE_API int sqlite3_stricmp(const char *, const char *);
-SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
+SQLITE_API int SQLITE_STDCALL sqlite3_stricmp(const char *, const char *);
+SQLITE_API int SQLITE_STDCALL sqlite3_strnicmp(const char *, const char *, int);
 
 /*
 ** CAPI3REF: String Globbing
@@ -7064,7 +7278,7 @@ SQLITE_API int sqlite3_strnicmp(const char *, const char *, int);
 ** Note that this routine returns zero on a match and non-zero if the strings
 ** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()].
 */
-SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr);
+SQLITE_API int SQLITE_STDCALL sqlite3_strglob(const char *zGlob, const char *zStr);
 
 /*
 ** CAPI3REF: Error Logging Interface
@@ -7087,18 +7301,17 @@ SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr);
 ** a few hundred characters, it will be truncated to the length of the
 ** buffer.
 */
-SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
+SQLITE_API void SQLITE_CDECL sqlite3_log(int iErrCode, const char *zFormat, ...);
 
 /*
 ** CAPI3REF: Write-Ahead Log Commit Hook
+** METHOD: sqlite3
 **
 ** ^The [sqlite3_wal_hook()] function is used to register a callback that
-** will be invoked each time a database connection commits data to a
-** [write-ahead log] (i.e. whenever a transaction is committed in
-** [journal_mode | journal_mode=WAL mode]). 
+** is invoked each time data is committed to a database in wal mode.
 **
-** ^The callback is invoked by SQLite after the commit has taken place and 
-** the associated write-lock on the database released, so the implementation 
+** ^(The callback is invoked by SQLite after the commit has taken place and 
+** the associated write-lock on the database released)^, so the implementation 
 ** may read, write or [checkpoint] the database as required.
 **
 ** ^The first parameter passed to the callback function when it is invoked
@@ -7124,7 +7337,7 @@ SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...);
 ** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will
 ** those overwrite any prior [sqlite3_wal_hook()] settings.
 */
-SQLITE_API void *sqlite3_wal_hook(
+SQLITE_API void *SQLITE_STDCALL sqlite3_wal_hook(
   sqlite3*, 
   int(*)(void *,sqlite3*,const char*,int),
   void*
@@ -7132,6 +7345,7 @@ SQLITE_API void *sqlite3_wal_hook(
 
 /*
 ** CAPI3REF: Configure an auto-checkpoint
+** METHOD: sqlite3
 **
 ** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around
 ** [sqlite3_wal_hook()] that causes any database on [database connection] D
@@ -7158,104 +7372,123 @@ SQLITE_API void *sqlite3_wal_hook(
 ** is only necessary if the default setting is found to be suboptimal
 ** for a particular application.
 */
-SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
+SQLITE_API int SQLITE_STDCALL sqlite3_wal_autocheckpoint(sqlite3 *db, int N);
 
 /*
 ** CAPI3REF: Checkpoint a database
+** METHOD: sqlite3
 **
-** ^The [sqlite3_wal_checkpoint(D,X)] interface causes database named X
-** on [database connection] D to be [checkpointed].  ^If X is NULL or an
-** empty string, then a checkpoint is run on all databases of
-** connection D.  ^If the database connection D is not in
-** [WAL | write-ahead log mode] then this interface is a harmless no-op.
-** ^The [sqlite3_wal_checkpoint(D,X)] interface initiates a
-** [sqlite3_wal_checkpoint_v2|PASSIVE] checkpoint.
-** Use the [sqlite3_wal_checkpoint_v2()] interface to get a FULL
-** or RESET checkpoint.
+** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to
+** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^
 **
-** ^The [wal_checkpoint pragma] can be used to invoke this interface
-** from SQL.  ^The [sqlite3_wal_autocheckpoint()] interface and the
-** [wal_autocheckpoint pragma] can be used to cause this interface to be
-** run whenever the WAL reaches a certain size threshold.
+** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the 
+** [write-ahead log] for database X on [database connection] D to be
+** transferred into the database file and for the write-ahead log to
+** be reset.  See the [checkpointing] documentation for addition
+** information.
 **
-** See also: [sqlite3_wal_checkpoint_v2()]
+** This interface used to be the only way to cause a checkpoint to
+** occur.  But then the newer and more powerful [sqlite3_wal_checkpoint_v2()]
+** interface was added.  This interface is retained for backwards
+** compatibility and as a convenience for applications that need to manually
+** start a callback but which do not need the full power (and corresponding
+** complication) of [sqlite3_wal_checkpoint_v2()].
 */
-SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
+SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb);
 
 /*
 ** CAPI3REF: Checkpoint a database
+** METHOD: sqlite3
 **
-** Run a checkpoint operation on WAL database zDb attached to database 
-** handle db. The specific operation is determined by the value of the 
-** eMode parameter:
+** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint
+** operation on database X of [database connection] D in mode M.  Status
+** information is written back into integers pointed to by L and C.)^
+** ^(The M parameter must be a valid [checkpoint mode]:)^
 **
 ** <dl>
 ** <dt>SQLITE_CHECKPOINT_PASSIVE<dd>
-**   Checkpoint as many frames as possible without waiting for any database 
-**   readers or writers to finish. Sync the db file if all frames in the log
-**   are checkpointed. This mode is the same as calling 
-**   sqlite3_wal_checkpoint(). The [sqlite3_busy_handler|busy-handler callback]
-**   is never invoked.
+**   ^Checkpoint as many frames as possible without waiting for any database 
+**   readers or writers to finish, then sync the database file if all frames 
+**   in the log were checkpointed. ^The [busy-handler callback]
+**   is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode.  
+**   ^On the other hand, passive mode might leave the checkpoint unfinished
+**   if there are concurrent readers or writers.
 **
 ** <dt>SQLITE_CHECKPOINT_FULL<dd>
-**   This mode blocks (it invokes the
+**   ^This mode blocks (it invokes the
 **   [sqlite3_busy_handler|busy-handler callback]) until there is no
 **   database writer and all readers are reading from the most recent database
-**   snapshot. It then checkpoints all frames in the log file and syncs the
-**   database file. This call blocks database writers while it is running,
-**   but not database readers.
+**   snapshot. ^It then checkpoints all frames in the log file and syncs the
+**   database file. ^This mode blocks new database writers while it is pending,
+**   but new database readers are allowed to continue unimpeded.
 **
 ** <dt>SQLITE_CHECKPOINT_RESTART<dd>
-**   This mode works the same way as SQLITE_CHECKPOINT_FULL, except after 
-**   checkpointing the log file it blocks (calls the 
-**   [sqlite3_busy_handler|busy-handler callback])
-**   until all readers are reading from the database file only. This ensures 
-**   that the next client to write to the database file restarts the log file 
-**   from the beginning. This call blocks database writers while it is running,
-**   but not database readers.
+**   ^This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition
+**   that after checkpointing the log file it blocks (calls the 
+**   [busy-handler callback])
+**   until all readers are reading from the database file only. ^This ensures 
+**   that the next writer will restart the log file from the beginning.
+**   ^Like SQLITE_CHECKPOINT_FULL, this mode blocks new
+**   database writer attempts while it is pending, but does not impede readers.
+**
+** <dt>SQLITE_CHECKPOINT_TRUNCATE<dd>
+**   ^This mode works the same way as SQLITE_CHECKPOINT_RESTART with the
+**   addition that it also truncates the log file to zero bytes just prior
+**   to a successful return.
 ** </dl>
 **
-** If pnLog is not NULL, then *pnLog is set to the total number of frames in
-** the log file before returning. If pnCkpt is not NULL, then *pnCkpt is set to
-** the total number of checkpointed frames (including any that were already
-** checkpointed when this function is called). *pnLog and *pnCkpt may be
-** populated even if sqlite3_wal_checkpoint_v2() returns other than SQLITE_OK.
-** If no values are available because of an error, they are both set to -1
-** before returning to communicate this to the caller.
-**
-** All calls obtain an exclusive "checkpoint" lock on the database file. If
+** ^If pnLog is not NULL, then *pnLog is set to the total number of frames in
+** the log file or to -1 if the checkpoint could not run because
+** of an error or because the database is not in [WAL mode]. ^If pnCkpt is not
+** NULL,then *pnCkpt is set to the total number of checkpointed frames in the
+** log file (including any that were already checkpointed before the function
+** was called) or to -1 if the checkpoint could not run due to an error or
+** because the database is not in WAL mode. ^Note that upon successful
+** completion of an SQLITE_CHECKPOINT_TRUNCATE, the log file will have been
+** truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero.
+**
+** ^All calls obtain an exclusive "checkpoint" lock on the database file. ^If
 ** any other process is running a checkpoint operation at the same time, the 
-** lock cannot be obtained and SQLITE_BUSY is returned. Even if there is a 
+** lock cannot be obtained and SQLITE_BUSY is returned. ^Even if there is a 
 ** busy-handler configured, it will not be invoked in this case.
 **
-** The SQLITE_CHECKPOINT_FULL and RESTART modes also obtain the exclusive 
-** "writer" lock on the database file. If the writer lock cannot be obtained
-** immediately, and a busy-handler is configured, it is invoked and the writer
-** lock retried until either the busy-handler returns 0 or the lock is
-** successfully obtained. The busy-handler is also invoked while waiting for
-** database readers as described above. If the busy-handler returns 0 before
+** ^The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the 
+** exclusive "writer" lock on the database file. ^If the writer lock cannot be
+** obtained immediately, and a busy-handler is configured, it is invoked and
+** the writer lock retried until either the busy-handler returns 0 or the lock
+** is successfully obtained. ^The busy-handler is also invoked while waiting for
+** database readers as described above. ^If the busy-handler returns 0 before
 ** the writer lock is obtained or while waiting for database readers, the
 ** checkpoint operation proceeds from that point in the same way as 
 ** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible 
-** without blocking any further. SQLITE_BUSY is returned in this case.
+** without blocking any further. ^SQLITE_BUSY is returned in this case.
 **
-** If parameter zDb is NULL or points to a zero length string, then the
-** specified operation is attempted on all WAL databases. In this case the
-** values written to output parameters *pnLog and *pnCkpt are undefined. If 
+** ^If parameter zDb is NULL or points to a zero length string, then the
+** specified operation is attempted on all WAL databases [attached] to 
+** [database connection] db.  In this case the
+** values written to output parameters *pnLog and *pnCkpt are undefined. ^If 
 ** an SQLITE_BUSY error is encountered when processing one or more of the 
 ** attached WAL databases, the operation is still attempted on any remaining 
-** attached databases and SQLITE_BUSY is returned to the caller. If any other 
+** attached databases and SQLITE_BUSY is returned at the end. ^If any other 
 ** error occurs while processing an attached database, processing is abandoned 
-** and the error code returned to the caller immediately. If no error 
+** and the error code is returned to the caller immediately. ^If no error 
 ** (SQLITE_BUSY or otherwise) is encountered while processing the attached 
 ** databases, SQLITE_OK is returned.
 **
-** If database zDb is the name of an attached database that is not in WAL
-** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. If
+** ^If database zDb is the name of an attached database that is not in WAL
+** mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. ^If
 ** zDb is not NULL (or a zero length string) and is not the name of any
 ** attached database, SQLITE_ERROR is returned to the caller.
+**
+** ^Unless it returns SQLITE_MISUSE,
+** the sqlite3_wal_checkpoint_v2() interface
+** sets the error information that is queried by
+** [sqlite3_errcode()] and [sqlite3_errmsg()].
+**
+** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface
+** from SQL.
 */
-SQLITE_API int sqlite3_wal_checkpoint_v2(
+SQLITE_API int SQLITE_STDCALL sqlite3_wal_checkpoint_v2(
   sqlite3 *db,                    /* Database handle */
   const char *zDb,                /* Name of attached database (or NULL) */
   int eMode,                      /* SQLITE_CHECKPOINT_* value */
@@ -7264,16 +7497,18 @@ SQLITE_API int sqlite3_wal_checkpoint_v2(
 );
 
 /*
-** CAPI3REF: Checkpoint operation parameters
+** CAPI3REF: Checkpoint Mode Values
+** KEYWORDS: {checkpoint mode}
 **
-** These constants can be used as the 3rd parameter to
-** [sqlite3_wal_checkpoint_v2()].  See the [sqlite3_wal_checkpoint_v2()]
-** documentation for additional information about the meaning and use of
-** each of these values.
+** These constants define all valid values for the "checkpoint mode" passed
+** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface.
+** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the
+** meaning of each of these checkpoint modes.
 */
-#define SQLITE_CHECKPOINT_PASSIVE 0
-#define SQLITE_CHECKPOINT_FULL    1
-#define SQLITE_CHECKPOINT_RESTART 2
+#define SQLITE_CHECKPOINT_PASSIVE  0  /* Do as much as possible w/o blocking */
+#define SQLITE_CHECKPOINT_FULL     1  /* Wait for writers, then checkpoint */
+#define SQLITE_CHECKPOINT_RESTART  2  /* Like FULL but wait for for readers */
+#define SQLITE_CHECKPOINT_TRUNCATE 3  /* Like RESTART but also truncate WAL */
 
 /*
 ** CAPI3REF: Virtual Table Interface Configuration
@@ -7289,7 +7524,7 @@ SQLITE_API int sqlite3_wal_checkpoint_v2(
 ** this function. (See [SQLITE_VTAB_CONSTRAINT_SUPPORT].)  Further options
 ** may be added in the future.
 */
-SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
+SQLITE_API int SQLITE_CDECL sqlite3_vtab_config(sqlite3*, int op, ...);
 
 /*
 ** CAPI3REF: Virtual Table Configuration Options
@@ -7342,7 +7577,7 @@ SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...);
 ** of the SQL statement that triggered the call to the [xUpdate] method of the
 ** [virtual table].
 */
-SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
+SQLITE_API int SQLITE_STDCALL sqlite3_vtab_on_conflict(sqlite3 *);
 
 /*
 ** CAPI3REF: Conflict resolution modes
@@ -7362,6 +7597,108 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
 /* #define SQLITE_ABORT 4  // Also an error code */
 #define SQLITE_REPLACE  5
 
+/*
+** CAPI3REF: Prepared Statement Scan Status Opcodes
+** KEYWORDS: {scanstatus options}
+**
+** The following constants can be used for the T parameter to the
+** [sqlite3_stmt_scanstatus(S,X,T,V)] interface.  Each constant designates a
+** different metric for sqlite3_stmt_scanstatus() to return.
+**
+** When the value returned to V is a string, space to hold that string is
+** managed by the prepared statement S and will be automatically freed when
+** S is finalized.
+**
+** <dl>
+** [[SQLITE_SCANSTAT_NLOOP]] <dt>SQLITE_SCANSTAT_NLOOP</dt>
+** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be
+** set to the total number of times that the X-th loop has run.</dd>
+**
+** [[SQLITE_SCANSTAT_NVISIT]] <dt>SQLITE_SCANSTAT_NVISIT</dt>
+** <dd>^The [sqlite3_int64] variable pointed to by the T parameter will be set
+** to the total number of rows examined by all iterations of the X-th loop.</dd>
+**
+** [[SQLITE_SCANSTAT_EST]] <dt>SQLITE_SCANSTAT_EST</dt>
+** <dd>^The "double" variable pointed to by the T parameter will be set to the
+** query planner's estimate for the average number of rows output from each
+** iteration of the X-th loop.  If the query planner's estimates was accurate,
+** then this value will approximate the quotient NVISIT/NLOOP and the
+** product of this value for all prior loops with the same SELECTID will
+** be the NLOOP value for the current loop.
+**
+** [[SQLITE_SCANSTAT_NAME]] <dt>SQLITE_SCANSTAT_NAME</dt>
+** <dd>^The "const char *" variable pointed to by the T parameter will be set
+** to a zero-terminated UTF-8 string containing the name of the index or table
+** used for the X-th loop.
+**
+** [[SQLITE_SCANSTAT_EXPLAIN]] <dt>SQLITE_SCANSTAT_EXPLAIN</dt>
+** <dd>^The "const char *" variable pointed to by the T parameter will be set
+** to a zero-terminated UTF-8 string containing the [EXPLAIN QUERY PLAN]
+** description for the X-th loop.
+**
+** [[SQLITE_SCANSTAT_SELECTID]] <dt>SQLITE_SCANSTAT_SELECT</dt>
+** <dd>^The "int" variable pointed to by the T parameter will be set to the
+** "select-id" for the X-th loop.  The select-id identifies which query or
+** subquery the loop is part of.  The main query has a select-id of zero.
+** The select-id is the same value as is output in the first column
+** of an [EXPLAIN QUERY PLAN] query.
+** </dl>
+*/
+#define SQLITE_SCANSTAT_NLOOP    0
+#define SQLITE_SCANSTAT_NVISIT   1
+#define SQLITE_SCANSTAT_EST      2
+#define SQLITE_SCANSTAT_NAME     3
+#define SQLITE_SCANSTAT_EXPLAIN  4
+#define SQLITE_SCANSTAT_SELECTID 5
+
+/*
+** CAPI3REF: Prepared Statement Scan Status
+** METHOD: sqlite3_stmt
+**
+** This interface returns information about the predicted and measured
+** performance for pStmt.  Advanced applications can use this
+** interface to compare the predicted and the measured performance and
+** issue warnings and/or rerun [ANALYZE] if discrepancies are found.
+**
+** Since this interface is expected to be rarely used, it is only
+** available if SQLite is compiled using the [SQLITE_ENABLE_STMT_SCANSTATUS]
+** compile-time option.
+**
+** The "iScanStatusOp" parameter determines which status information to return.
+** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior
+** of this interface is undefined.
+** ^The requested measurement is written into a variable pointed to by
+** the "pOut" parameter.
+** Parameter "idx" identifies the specific loop to retrieve statistics for.
+** Loops are numbered starting from zero. ^If idx is out of range - less than
+** zero or greater than or equal to the total number of loops used to implement
+** the statement - a non-zero value is returned and the variable that pOut
+** points to is unchanged.
+**
+** ^Statistics might not be available for all loops in all statements. ^In cases
+** where there exist loops with no available statistics, this function behaves
+** as if the loop did not exist - it returns non-zero and leave the variable
+** that pOut points to unchanged.
+**
+** See also: [sqlite3_stmt_scanstatus_reset()]
+*/
+SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_stmt_scanstatus(
+  sqlite3_stmt *pStmt,      /* Prepared statement for which info desired */
+  int idx,                  /* Index of loop to report on */
+  int iScanStatusOp,        /* Information desired.  SQLITE_SCANSTAT_* */
+  void *pOut                /* Result written here */
+);     
+
+/*
+** CAPI3REF: Zero Scan-Status Counters
+** METHOD: sqlite3_stmt
+**
+** ^Zero all [sqlite3_stmt_scanstatus()] related event counters.
+**
+** This API is only available if the library is built with pre-processor
+** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
+*/
+SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
 
 
 /*
@@ -7416,7 +7753,7 @@ typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info;
 **
 **   SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zGeom(... params ...)
 */
-SQLITE_API int sqlite3_rtree_geometry_callback(
+SQLITE_API int SQLITE_STDCALL sqlite3_rtree_geometry_callback(
   sqlite3 *db,
   const char *zGeom,
   int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*),
@@ -7442,7 +7779,7 @@ struct sqlite3_rtree_geometry {
 **
 **   SELECT ... FROM <rtree> WHERE <rtree col> MATCH $zQueryFunc(... params ...)
 */
-SQLITE_API int sqlite3_rtree_query_callback(
+SQLITE_API int SQLITE_STDCALL sqlite3_rtree_query_callback(
   sqlite3 *db,
   const char *zQueryFunc,
   int (*xQueryFunc)(sqlite3_rtree_query_info*),
diff --git a/providers/sqlcipher/sqlcipher.patch b/providers/sqlcipher/sqlcipher.patch
index 5d419a4..d47cdf4 100644
--- a/providers/sqlcipher/sqlcipher.patch
+++ b/providers/sqlcipher/sqlcipher.patch
@@ -1,6 +1,6 @@
---- sqlite3.c.sqlite   2014-11-08 15:18:19.125321039 +0100
-+++ sqlite3.c  2014-11-08 15:17:59.107894171 +0100
-@@ -13182,9 +13182,45 @@
+--- sqlite3.c.sqlite   2016-03-09 15:41:25.053136000 +0100
++++ sqlite3.c  2016-03-09 15:41:16.424942202 +0100
+@@ -13786,9 +13786,45 @@
  #endif /* _SQLITEINT_H_ */
  
  /************** End of sqliteInt.h *******************************************/
@@ -48,14 +48,14 @@
  **
  ** The author disclaims copyright to this source code.  In place of
  ** a legal notice, here is a blessing:
-@@ -13194,261 +13230,3776 @@
+@@ -13798,2674 +13834,3856 @@
  **    May you share freely, never taking more than you give.
  **
  *************************************************************************
-+** This file implements a external (disk-based) database using BTrees.
++** This file implements an external (disk-based) database using BTrees.
 +** For a detailed discussion of BTrees, refer to
  **
--** This file contains definitions of global variables and contants.
+-** This file contains definitions of global variables and constants.
 -*/
 -
 -/* An array to map all upper-case characters into their corresponding
@@ -93,16 +93,16 @@
 -     48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 3x */
 -     64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 4x */
 -     80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 5x */
--     96, 97, 66, 67, 68, 69, 70, 71, 72, 73,106,107,108,109,110,111, /* 6x */
--    112, 81, 82, 83, 84, 85, 86, 87, 88, 89,122,123,124,125,126,127, /* 7x */
+-     96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 6x */
+-    112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /* 7x */
 -    128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, /* 8x */
--    144,145,146,147,148,149,150,151,152,153,154,155,156,157,156,159, /* 9x */
+-    144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, /* 9x */
 -    160,161,162,163,164,165,166,167,168,169,170,171,140,141,142,175, /* Ax */
 -    176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, /* Bx */
 -    192,129,130,131,132,133,134,135,136,137,202,203,204,205,206,207, /* Cx */
 -    208,145,146,147,148,149,150,151,152,153,218,219,220,221,222,223, /* Dx */
--    224,225,162,163,164,165,166,167,168,169,232,203,204,205,206,207, /* Ex */
--    239,240,241,242,243,244,245,246,247,248,249,219,220,221,222,255, /* Fx */
+-    224,225,162,163,164,165,166,167,168,169,234,235,236,237,238,239, /* Ex */
+-    240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, /* Fx */
 -#endif
 -};
 -
@@ -157,16 +157,65 @@
  **
 -** SQLite's versions are identical to the standard versions assuming a
 -** locale of "C". They are implemented as macros in sqliteInt.h.
+-*/
+-#ifdef SQLITE_ASCII
+-SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 00..07    ........ */
+-  0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,  /* 08..0f    ........ */
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 10..17    ........ */
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 18..1f    ........ */
+-  0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,  /* 20..27     !"#$%&' */
+-  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 28..2f    ()*+,-./ */
+-  0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,  /* 30..37    01234567 */
+-  0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 38..3f    89:;<=>? */
+-
+-  0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x02,  /* 40..47    @ABCDEFG */
+-  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,  /* 48..4f    HIJKLMNO */
+-  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,  /* 50..57    PQRSTUVW */
+-  0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40,  /* 58..5f    XYZ[\]^_ */
+-  0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22,  /* 60..67    `abcdefg */
+-  0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,  /* 68..6f    hijklmno */
+-  0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,  /* 70..77    pqrstuvw */
+-  0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 78..7f    xyz{|}~. */
+-
+-  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* 80..87    ........ */
+-  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* 88..8f    ........ */
+-  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* 90..97    ........ */
+-  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* 98..9f    ........ */
+-  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* a0..a7    ........ */
+-  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* a8..af    ........ */
+-  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* b0..b7    ........ */
+-  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* b8..bf    ........ */
+-
+-  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* c0..c7    ........ */
+-  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* c8..cf    ........ */
+-  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* d0..d7    ........ */
+-  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* d8..df    ........ */
+-  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* e0..e7    ........ */
+-  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* e8..ef    ........ */
+-  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* f0..f7    ........ */
+-  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40   /* f8..ff    ........ */
+-};
+-#endif
+-
+-/* EVIDENCE-OF: R-02982-34736 In order to maintain full backwards
+-** compatibility for legacy applications, the URI filename capability is
+-** disabled by default.
 +** The file is divided into pages.  The first page is called page 1,
 +** the second is page 2, and so forth.  A page number of zero indicates
 +** "no such page".  The page size can be any power of 2 between 512 and 65536.
 +** Each page can be either a btree page, a freelist page, an overflow
 +** page, or a pointer-map page.
-+**
+ **
+-** EVIDENCE-OF: R-38799-08373 URI filenames can be enabled or disabled
+-** using the SQLITE_USE_URI=1 or SQLITE_USE_URI=0 compile-time options.
 +** The first page is always a btree page.  The first 100 bytes of the first
 +** page contain a special header (the "file header") that describes the file.
 +** The format of the file header is as follows:
-+**
+ **
+-** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally
+-** disabled. The default value may be changed by compiling with the
+-** SQLITE_USE_URI symbol defined.
 +**   OFFSET   SIZE    DESCRIPTION
 +**      0      16     Header string: "SQLite format 3\000"
 +**     16       2     Page size in bytes.  (1 means 65536)
@@ -248,7 +297,7 @@
 +**
 +** The flags define the format of this btree page.  The leaf flag means that
 +** this page has no children.  The zerodata flag means that this page carries
-+** only keys and no data.  The intkey flag means that the key is a integer
++** only keys and no data.  The intkey flag means that the key is an integer
 +** which is stored in the key size entry of the cell header rather than in
 +** the payload area.
 +**
@@ -326,63 +375,34 @@
 +**      4     Number of leaf pointers on this page
 +**      *     zero or more pages numbers of leaves
  */
--#ifdef SQLITE_ASCII
--SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
--  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 00..07    ........ */
--  0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,  /* 08..0f    ........ */
--  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 10..17    ........ */
--  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 18..1f    ........ */
--  0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,  /* 20..27     !"#$%&' */
--  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 28..2f    ()*+,-./ */
--  0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,  /* 30..37    01234567 */
--  0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 38..3f    89:;<=>? */
--
--  0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x02,  /* 40..47    @ABCDEFG */
--  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,  /* 48..4f    HIJKLMNO */
--  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,  /* 50..57    PQRSTUVW */
--  0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40,  /* 58..5f    XYZ[\]^_ */
--  0x00, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x22,  /* 60..67    `abcdefg */
--  0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,  /* 68..6f    hijklmno */
--  0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,  /* 70..77    pqrstuvw */
--  0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 78..7f    xyz{|}~. */
- 
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* 80..87    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* 88..8f    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* 90..97    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* 98..9f    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* a0..a7    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* a8..af    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* b0..b7    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* b8..bf    ........ */
- 
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* c0..c7    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* c8..cf    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* d0..d7    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* d8..df    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* e0..e7    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* e8..ef    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* f0..f7    ........ */
--  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40   /* f8..ff    ........ */
--};
+-#ifndef SQLITE_USE_URI
+-# define  SQLITE_USE_URI 0
 -#endif
+ 
+-/* EVIDENCE-OF: R-38720-18127 The default setting is determined by the
+-** SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option, or is "on" if
+-** that compile-time option is omitted.
++
 +/* The following value is the maximum cell size assuming a maximum page
 +** size give above.
-+*/
+ */
+-#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
+-# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
+-#endif
 +#define MX_CELL_SIZE(pBt)  ((int)(pBt->pageSize-8))
  
--#ifndef SQLITE_USE_URI
--# define  SQLITE_USE_URI 0
--#endif
+-/* The minimum PMA size is set to this value multiplied by the database
+-** page size in bytes.
 +/* The maximum number of cells on a single page of the database.  This
 +** assumes a minimum cell size of 6 bytes  (4 bytes for the cell itself
 +** plus 2 bytes for the index to the cell in the page header).  Such
 +** small cells will be rare, but they are possible.
-+*/
-+#define MX_CELL(pBt) ((pBt->pageSize-8)/6)
- 
--#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
--# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
+ */
+-#ifndef SQLITE_SORTER_PMASZ
+-# define SQLITE_SORTER_PMASZ 250
 -#endif
++#define MX_CELL(pBt) ((pBt->pageSize-8)/6)
++
 +/* Forward declarations */
 +typedef struct MemPage MemPage;
 +typedef struct BtLock BtLock;
@@ -427,6 +447,7 @@
 -   0,                         /* nPage */
 -   0,                         /* mxParserStack */
 -   0,                         /* sharedCacheEnabled */
+-   SQLITE_SORTER_PMASZ,       /* szPma */
 -   /* All the rest should always be initialized to zero */
 -   0,                         /* isInit */
 -   0,                         /* inProgress */
@@ -452,68 +473,48 @@
  #endif
 -   0                          /* bLocaltimeFault */
 -};
--
--/*
+ 
+ /*
 -** Hash table for global functions - functions common to all
 -** database connections.  After initialization, this table is
 -** read-only.
--*/
--SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
- 
- /*
--** Constant tokens for values 0 and 1.
 +** Page type flags.  An ORed combination of these flags appear as the
 +** first byte of on-disk image of every BTree page.
  */
--SQLITE_PRIVATE const Token sqlite3IntTokens[] = {
--   { "0", 1 },
--   { "1", 1 }
--};
--
+-SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
 +#define PTF_INTKEY    0x01
 +#define PTF_ZERODATA  0x02
 +#define PTF_LEAFDATA  0x04
 +#define PTF_LEAF      0x08
  
  /*
--** The value of the "pending" byte must be 0x40000000 (1 byte past the
--** 1-gibabyte boundary) in a compatible database.  SQLite never uses
--** the database page that contains the pending byte.  It never attempts
--** to read or write that page.  The pending byte page is set assign
--** for use by the VFS layers as space for managing file locks.
+-** Constant tokens for values 0 and 1.
 +** As each page of the file is loaded into memory, an instance of the following
 +** structure is appended and initialized to zero.  This structure stores
 +** information about the page that is decoded from the raw file page.
- **
--** During testing, it is often desirable to move the pending byte to
--** a different position in the file.  This allows code that has to
--** deal with the pending byte to run on files that are much smaller
--** than 1 GiB.  The sqlite3_test_control() interface can be used to
--** move the pending byte.
++**
 +** The pParent field points back to the parent page.  This allows us to
 +** walk up the BTree from any leaf to the root.  Care must be taken to
 +** unref() the parent page pointer when this page is no longer referenced.
 +** The pageDestructor() routine handles that chore.
- **
--** IMPORTANT:  Changing the pending byte to any value other than
--** 0x40000000 results in an incompatible database file format!
--** Changing the pending byte during operating results in undefined
--** and dileterious behavior.
++**
 +** Access to all fields of this structure is controlled by the mutex
 +** stored in MemPage.pBt->mutex.
  */
--#ifndef SQLITE_OMIT_WSD
--SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000;
--#endif
+-SQLITE_PRIVATE const Token sqlite3IntTokens[] = {
+-   { "0", 1 },
+-   { "1", 1 }
 +struct MemPage {
 +  u8 isInit;           /* True if previously initialized. MUST BE FIRST! */
 +  u8 nOverflow;        /* Number of overflow cell bodies in aCell[] */
-+  u8 intKey;           /* True if intkey flag is set */
-+  u8 leaf;             /* True if leaf flag is set */
-+  u8 hasData;          /* True if this page stores data */
++  u8 intKey;           /* True if table b-trees.  False for index b-trees */
++  u8 intKeyLeaf;       /* True if the leaf of an intKey table */
++  u8 noPayload;        /* True if internal intKey page (thus w/o data) */
++  u8 leaf;             /* True if a leaf page */
 +  u8 hdrOffset;        /* 100 for page 1.  0 otherwise */
 +  u8 childPtrSize;     /* 0 if leaf==1.  4 if leaf==0 */
 +  u8 max1bytePayload;  /* min(maxLocal,127) */
++  u8 bBusy;            /* Prevent endless loops on corrupt database files */
 +  u16 maxLocal;        /* Copy of BtShared.maxLocal or BtShared.maxLeaf */
 +  u16 minLocal;        /* Copy of BtShared.minLocal or BtShared.minLeaf */
 +  u16 cellOffset;      /* Index in aData of first cell pointer */
@@ -529,42 +530,47 @@
 +  u8 *aCellIdx;        /* The cell index area */
 +  DbPage *pDbPage;     /* Pager page handle */
 +  Pgno pgno;           /* Page number for this page */
-+};
+ };
  
+-
  /*
--** Properties of opcodes.  The OPFLG_INITIALIZER macro is
--** created by mkopcodeh.awk during compilation.  Data is obtained
--** from the comments following the "case OP_xxxx:" statements in
--** the vdbe.c file.  
+-** The value of the "pending" byte must be 0x40000000 (1 byte past the
+-** 1-gibabyte boundary) in a compatible database.  SQLite never uses
+-** the database page that contains the pending byte.  It never attempts
+-** to read or write that page.  The pending byte page is set assign
+-** for use by the VFS layers as space for managing file locks.
+-**
+-** During testing, it is often desirable to move the pending byte to
+-** a different position in the file.  This allows code that has to
+-** deal with the pending byte to run on files that are much smaller
+-** than 1 GiB.  The sqlite3_test_control() interface can be used to
+-** move the pending byte.
+-**
+-** IMPORTANT:  Changing the pending byte to any value other than
+-** 0x40000000 results in an incompatible database file format!
+-** Changing the pending byte during operation will result in undefined
+-** and incorrect behavior.
 +** The in-memory image of a disk page has the auxiliary information appended
 +** to the end.  EXTRA_SIZE is the number of bytes of space needed to hold
 +** that extra information.
  */
--SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER;
+-#ifndef SQLITE_OMIT_WSD
+-SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000;
+-#endif
 +#define EXTRA_SIZE sizeof(MemPage)
  
--/************** End of global.c **********************************************/
--/************** Begin file ctime.c *******************************************/
  /*
--** 2010 February 23
--**
--** The author disclaims copyright to this source code.  In place of
--** a legal notice, here is a blessing:
--**
--**    May you do good and not evil.
--**    May you find forgiveness for yourself and forgive others.
--**    May you share freely, never taking more than you give.
--**
--*************************************************************************
--**
--** This file implements routines used to report what compile-time options
--** SQLite was built with.
+-** Properties of opcodes.  The OPFLG_INITIALIZER macro is
+-** created by mkopcodeh.awk during compilation.  Data is obtained
+-** from the comments following the "case OP_xxxx:" statements in
+-** the vdbe.c file.  
 +** A linked list of the following structures is stored at BtShared.pLock.
 +** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor 
 +** is opened on the table with root page BtShared.iTable. Locks are removed
 +** from this list when a transaction is committed or rolled back, or when
 +** a btree handle is closed.
  */
+-SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER;
 +struct BtLock {
 +  Btree *pBtree;        /* Btree handle holding this lock */
 +  Pgno iTable;          /* Root page of table */
@@ -572,39 +578,47 @@
 +  BtLock *pNext;        /* Next in BtShared.pLock list */
 +};
  
--#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
--
+-/************** End of global.c **********************************************/
+-/************** Begin file ctime.c *******************************************/
+-/*
+-** 2010 February 23
+-**
+-** The author disclaims copyright to this source code.  In place of
+-** a legal notice, here is a blessing:
 +/* Candidate values for BtLock.eLock */
 +#define READ_LOCK     1
 +#define WRITE_LOCK    2
- 
--/*
--** An array of names of all compile-time options.  This array should 
--** be sorted A-Z.
++
 +/* A Btree handle
  **
--** This array looks large, but in a typical installation actually uses
--** only a handful of compile-time options, so most times this array is usually
--** rather short and uses little memory space.
+-**    May you do good and not evil.
+-**    May you find forgiveness for yourself and forgive others.
+-**    May you share freely, never taking more than you give.
 +** A database connection contains a pointer to an instance of
 +** this object for every database file that it has open.  This structure
 +** is opaque to the database connection.  The database connection cannot
 +** see the internals of this structure and only deals with pointers to
 +** this structure.
-+**
+ **
+-*************************************************************************
 +** For some database files, the same underlying database cache might be 
 +** shared between multiple connections.  In that case, each connection
 +** has it own instance of this object.  But each instance of this object
 +** points to the same BtShared object.  The database cache and the
 +** schema associated with the database file are all contained within
 +** the BtShared object.
-+**
+ **
+-** This file implements routines used to report what compile-time options
+-** SQLite was built with.
 +** All fields in this structure are accessed under sqlite3.mutex.
 +** The pBt pointer itself may not be changed while there exists cursors 
 +** in the referenced BtShared that point back to this Btree since those
 +** cursors have to go through this Btree to find their BtShared and
 +** they often do so without holding sqlite3.mutex.
-+*/
+ */
+-
+-#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+-
 +struct Btree {
 +  sqlite3 *db;       /* The database connection holding this btree */
 +  BtShared *pBt;     /* Sharable content of this btree */
@@ -613,24 +627,74 @@
 +  u8 locked;         /* True if db currently has pBt locked */
 +  int wantToLock;    /* Number of nested calls to sqlite3BtreeEnter() */
 +  int nBackup;       /* Number of backup operations reading this btree */
++  u32 iDataVersion;  /* Combines with pBt->pPager->iDataVersion */
 +  Btree *pNext;      /* List of other sharable Btrees from the same db */
 +  Btree *pPrev;      /* Back pointer of the same list */
 +#ifndef SQLITE_OMIT_SHARED_CACHE
 +  BtLock lock;       /* Object used to lock page 1 */
 +#endif
 +};
-+
-+/*
+ 
+ /*
+-** An array of names of all compile-time options.  This array should 
+-** be sorted A-Z.
 +** Btree.inTrans may take one of the following values.
-+**
+ **
+-** This array looks large, but in a typical installation actually uses
+-** only a handful of compile-time options, so most times this array is usually
+-** rather short and uses little memory space.
 +** If the shared-data extension is enabled, there may be multiple users
 +** of the Btree structure. At most one of these may open a write transaction,
 +** but any number may have active read transactions.
-+*/
+ */
+-static const char * const azCompileOpt[] = {
+-
+-/* These macros are provided to "stringify" the value of the define
+-** for those options in which the value is meaningful. */
+-#define CTIMEOPT_VAL_(opt) #opt
+-#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
 +#define TRANS_NONE  0
 +#define TRANS_READ  1
 +#define TRANS_WRITE 2
-+
+ 
+-#if SQLITE_32BIT_ROWID
+-  "32BIT_ROWID",
+-#endif
+-#if SQLITE_4_BYTE_ALIGNED_MALLOC
+-  "4_BYTE_ALIGNED_MALLOC",
+-#endif
+-#if SQLITE_CASE_SENSITIVE_LIKE
+-  "CASE_SENSITIVE_LIKE",
+-#endif
+-#if SQLITE_CHECK_PAGES
+-  "CHECK_PAGES",
+-#endif
+-#if SQLITE_COVERAGE_TEST
+-  "COVERAGE_TEST",
+-#endif
+-#if SQLITE_DEBUG
+-  "DEBUG",
+-#endif
+-#if SQLITE_DEFAULT_LOCKING_MODE
+-  "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
+-#endif
+-#if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc)
+-  "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE),
+-#endif
+-#if SQLITE_DISABLE_DIRSYNC
+-  "DISABLE_DIRSYNC",
+-#endif
+-#if SQLITE_DISABLE_LFS
+-  "DISABLE_LFS",
+-#endif
+-#if SQLITE_ENABLE_API_ARMOR
+-  "ENABLE_API_ARMOR",
+-#endif
+-#if SQLITE_ENABLE_ATOMIC_WRITE
+-  "ENABLE_ATOMIC_WRITE",
+-#endif
+-#if SQLITE_ENABLE_CEROD
+-  "ENABLE_CEROD",
 +/*
 +** An instance of this object represents a single database file.
 +** 
@@ -676,9 +740,16 @@
 +  u8 autoVacuum;        /* True if auto-vacuum is enabled */
 +  u8 incrVacuum;        /* True if incr-vacuum is enabled */
 +  u8 bDoTruncate;       /* True to truncate db on commit */
-+#endif
+ #endif
+-#if SQLITE_ENABLE_COLUMN_METADATA
+-  "ENABLE_COLUMN_METADATA",
 +  u8 inTransaction;     /* Transaction state */
 +  u8 max1bytePayload;   /* Maximum first byte of cell for a 1-byte payload */
++#ifdef SQLITE_HAS_CODEC
++  u8 optimalReserve;    /* Desired amount of reserved space per page */
+ #endif
+-#if SQLITE_ENABLE_DBSTAT_VTAB
+-  "ENABLE_DBSTAT_VTAB",
 +  u16 btsFlags;         /* Boolean parameters.  See BTS_* macros below */
 +  u16 maxLocal;         /* Maximum local payload in non-LEAFDATA tables */
 +  u16 minLocal;         /* Minimum local payload in non-LEAFDATA tables */
@@ -697,8 +768,10 @@
 +  BtShared *pNext;      /* Next on a list of sharable BtShared structs */
 +  BtLock *pLock;        /* List of locks held on this shared-btree struct */
 +  Btree *pWriter;       /* Btree with currently open write transaction */
-+#endif
-+  u8 *pTmpSpace;        /* BtShared.pageSize bytes of space for tmp use */
+ #endif
+-#if SQLITE_ENABLE_EXPENSIVE_ASSERT
+-  "ENABLE_EXPENSIVE_ASSERT",
++  u8 *pTmpSpace;        /* Temp space sufficient to hold a single cell */
 +};
 +
 +/*
@@ -719,12 +792,10 @@
 +*/
 +typedef struct CellInfo CellInfo;
 +struct CellInfo {
-+  i64 nKey;      /* The key for INTKEY tables, or number of bytes in key */
-+  u8 *pCell;     /* Pointer to the start of cell content */
-+  u32 nData;     /* Number of bytes of data */
-+  u32 nPayload;  /* Total amount of payload */
-+  u16 nHeader;   /* Size of the cell content header in bytes */
-+  u16 nLocal;    /* Amount of payload held locally */
++  i64 nKey;      /* The key for INTKEY tables, or nPayload otherwise */
++  u8 *pPayload;  /* Pointer to the start of payload */
++  u32 nPayload;  /* Bytes of payload */
++  u16 nLocal;    /* Amount of payload held locally, not on overflow */
 +  u16 iOverflow; /* Offset to overflow page number.  Zero if no overflow */
 +  u16 nSize;     /* Size of the cell content on the main b-tree page */
 +};
@@ -753,6 +824,11 @@
 +**
 +** Fields in this structure are accessed under the BtShared.mutex
 +** found at self->pBt->mutex. 
++**
++** skipNext meaning:
++**    eState==SKIPNEXT && skipNext>0:  Next sqlite3BtreeNext() is no-op.
++**    eState==SKIPNEXT && skipNext<0:  Next sqlite3BtreePrevious() is no-op.
++**    eState==FAULT:                   Cursor fault with skipNext as error code.
 +*/
 +struct BtCursor {
 +  Btree *pBtree;            /* The Btree to which this cursor belongs */
@@ -765,7 +841,8 @@
 +  void *pKey;               /* Saved key that was cursor last known position */
 +  Pgno pgnoRoot;            /* The root page of this tree */
 +  int nOvflAlloc;           /* Allocated size of aOverflow[] array */
-+  int skipNext;    /* Prev() is noop if negative. Next() is noop if positive */
++  int skipNext;    /* Prev() is noop if negative. Next() is noop if positive.
++                   ** Error code if eState==CURSOR_FAULT */
 +  u8 curFlags;              /* zero or more BTCF_* flags defined below */
 +  u8 eState;                /* One of the CURSOR_XXX constants (see below) */
 +  u8 hints;                             /* As configured by CursorSetHints() */
@@ -807,11 +884,11 @@
 +**   seek the cursor to the saved position.
 +**
 +** CURSOR_FAULT:
-+**   A unrecoverable error (an I/O error or a malloc failure) has occurred
++**   An unrecoverable error (an I/O error or a malloc failure) has occurred
 +**   on a different connection that shares the BtShared cache with this
 +**   cursor.  The error has left the cache in an inconsistent state.
 +**   Do nothing else with this cursor.  Any attempt to use the cursor
-+**   should return the error code stored in BtCursor.skip
++**   should return the error code stored in BtCursor.skipNext
 +*/
 +#define CURSOR_INVALID           0
 +#define CURSOR_VALID             1
@@ -899,7 +976,9 @@
 +#define ISAUTOVACUUM (pBt->autoVacuum)
 +#else
 +#define ISAUTOVACUUM 0
-+#endif
+ #endif
+-#if SQLITE_ENABLE_FTS1
+-  "ENABLE_FTS1",
 +
 +
 +/*
@@ -921,6 +1000,8 @@
 +  int mxErr;        /* Stop accumulating errors when this reaches zero */
 +  int nErr;         /* Number of messages written to zErrMsg so far */
 +  int mallocFailed; /* A memory allocation error has occurred */
++  const char *zPfx; /* Error message prefix */
++  int v1, v2;       /* Values for up to two %d fields in zPfx */
 +  StrAccum errMsg;  /* Accumulate the error message text here */
 +};
 +
@@ -977,17 +1058,29 @@
 +   && !defined (SQLCIPHER_CRYPTO_LIBTOMCRYPT) \
 +   && !defined (SQLCIPHER_CRYPTO_OPENSSL)
 +#define SQLCIPHER_CRYPTO_OPENSSL
-+#endif
+ #endif
+-#if SQLITE_ENABLE_FTS2
+-  "ENABLE_FTS2",
 +
 +#define FILE_HEADER_SZ 16
 +
 +#ifndef CIPHER_VERSION
-+#define CIPHER_VERSION "3.2.0"
-+#endif
++#ifdef SQLCIPHER_FIPS
++#define CIPHER_VERSION "3.3.1 FIPS"
++#else
++#define CIPHER_VERSION "3.3.1"
+ #endif
+-#if SQLITE_ENABLE_FTS3
+-  "ENABLE_FTS3",
+ #endif
+-#if SQLITE_ENABLE_FTS3_PARENTHESIS
+-  "ENABLE_FTS3_PARENTHESIS",
 +
 +#ifndef CIPHER
 +#define CIPHER "aes-256-cbc"
-+#endif
+ #endif
+-#if SQLITE_ENABLE_FTS4
+-  "ENABLE_FTS4",
 +
 +#define CIPHER_DECRYPT 0
 +#define CIPHER_ENCRYPT 1
@@ -998,7 +1091,9 @@
 +
 +#ifndef PBKDF2_ITER
 +#define PBKDF2_ITER 64000
-+#endif
+ #endif
+-#if SQLITE_ENABLE_ICU
+-  "ENABLE_ICU",
 +
 +/* possible flags for cipher_ctx->flags */
 +#define CIPHER_FLAG_HMAC          0x01
@@ -1007,7 +1102,9 @@
 +
 +#ifndef DEFAULT_CIPHER_FLAGS
 +#define DEFAULT_CIPHER_FLAGS CIPHER_FLAG_HMAC | CIPHER_FLAG_LE_PGNO
-+#endif
+ #endif
+-#if SQLITE_ENABLE_IOTRACE
+-  "ENABLE_IOTRACE",
 +
 +
 +/* by default, sqlcipher will use a reduced number of iterations to generate
@@ -1015,7 +1112,9 @@
 +   */
 +#ifndef FAST_PBKDF2_ITER
 +#define FAST_PBKDF2_ITER 2
-+#endif
+ #endif
+-#if SQLITE_ENABLE_LOAD_EXTENSION
+-  "ENABLE_LOAD_EXTENSION",
 +
 +/* this if a fixed random array that will be xor'd with the database salt to ensure that the
 +   salt passed to the HMAC key derivation function is not the same as that used to derive
@@ -1024,22 +1123,30 @@
 +   will likely allow this to be defined at runtime via pragma */ 
 +#ifndef HMAC_SALT_MASK
 +#define HMAC_SALT_MASK 0x3a
-+#endif
+ #endif
+-#if SQLITE_ENABLE_LOCKING_STYLE
+-  "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE),
 +
 +#ifndef CIPHER_MAX_IV_SZ
 +#define CIPHER_MAX_IV_SZ 16
-+#endif
+ #endif
+-#if SQLITE_ENABLE_MEMORY_MANAGEMENT
+-  "ENABLE_MEMORY_MANAGEMENT",
 +
 +#ifndef CIPHER_MAX_KEY_SZ
 +#define CIPHER_MAX_KEY_SZ 64
-+#endif
+ #endif
+-#if SQLITE_ENABLE_MEMSYS3
+-  "ENABLE_MEMSYS3",
 +
 +
 +#ifdef CODEC_DEBUG
 +#define CODEC_TRACE(X)  {printf X;fflush(stdout);}
 +#else
 +#define CODEC_TRACE(X)
-+#endif
+ #endif
+-#if SQLITE_ENABLE_MEMSYS5
+-  "ENABLE_MEMSYS5",
 +
 +#ifdef CODEC_DEBUG_PAGEDATA
 +#define CODEC_HEXDUMP(DESC,BUFFER,LEN)  \
@@ -1055,7 +1162,9 @@
 +  }
 +#else
 +#define CODEC_HEXDUMP(DESC,BUFFER,LEN)
-+#endif
+ #endif
+-#if SQLITE_ENABLE_OVERSIZE_CELL_CHECK
+-  "ENABLE_OVERSIZE_CELL_CHECK",
 +
 +/* extensions defined in pager.c */ 
 +SQLITE_PRIVATE void sqlite3pager_get_codec(Pager *pPager, void **ctx);
@@ -1118,6 +1227,9 @@
 +int sqlcipher_codec_ctx_get_pagesize(codec_ctx *);
 +int sqlcipher_codec_ctx_get_reservesize(codec_ctx *);
 +
++void sqlcipher_set_default_pagesize(int page_size);
++int sqlcipher_get_default_pagesize();
++
 +void sqlcipher_set_default_kdf_iter(int iter);
 +int sqlcipher_get_default_kdf_iter();
 +
@@ -1157,14 +1269,291 @@
 +static int sqlcipher_codec_get_store_pass(codec_ctx *ctx);
 +static void sqlcipher_codec_get_pass(codec_ctx *ctx, void **zKey, int *nKey);
 +static void sqlcipher_codec_set_store_pass(codec_ctx *ctx, int value);
++int sqlcipher_codec_fips_status(codec_ctx *ctx);
 +
-+#endif
-+#endif
+ #endif
+-#if SQLITE_ENABLE_RTREE
+-  "ENABLE_RTREE",
+ #endif
+-#if defined(SQLITE_ENABLE_STAT4)
+-  "ENABLE_STAT4",
+-#elif defined(SQLITE_ENABLE_STAT3)
+-  "ENABLE_STAT3",
+-#endif
+-#if SQLITE_ENABLE_UNLOCK_NOTIFY
+-  "ENABLE_UNLOCK_NOTIFY",
+-#endif
+-#if SQLITE_ENABLE_UPDATE_DELETE_LIMIT
+-  "ENABLE_UPDATE_DELETE_LIMIT",
+-#endif
+-#if SQLITE_HAS_CODEC
+-  "HAS_CODEC",
+-#endif
+-#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
+-  "HAVE_ISNAN",
+-#endif
+-#if SQLITE_HOMEGROWN_RECURSIVE_MUTEX
+-  "HOMEGROWN_RECURSIVE_MUTEX",
+-#endif
+-#if SQLITE_IGNORE_AFP_LOCK_ERRORS
+-  "IGNORE_AFP_LOCK_ERRORS",
+-#endif
+-#if SQLITE_IGNORE_FLOCK_LOCK_ERRORS
+-  "IGNORE_FLOCK_LOCK_ERRORS",
+-#endif
+-#ifdef SQLITE_INT64_TYPE
+-  "INT64_TYPE",
+-#endif
+-#if SQLITE_LOCK_TRACE
+-  "LOCK_TRACE",
+-#endif
+-#if defined(SQLITE_MAX_MMAP_SIZE) && !defined(SQLITE_MAX_MMAP_SIZE_xc)
+-  "MAX_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE),
+-#endif
+-#ifdef SQLITE_MAX_SCHEMA_RETRY
+-  "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY),
+-#endif
+-#if SQLITE_MEMDEBUG
+-  "MEMDEBUG",
+-#endif
+-#if SQLITE_MIXED_ENDIAN_64BIT_FLOAT
+-  "MIXED_ENDIAN_64BIT_FLOAT",
+-#endif
+-#if SQLITE_NO_SYNC
+-  "NO_SYNC",
+-#endif
+-#if SQLITE_OMIT_ALTERTABLE
+-  "OMIT_ALTERTABLE",
+-#endif
+-#if SQLITE_OMIT_ANALYZE
+-  "OMIT_ANALYZE",
+-#endif
+-#if SQLITE_OMIT_ATTACH
+-  "OMIT_ATTACH",
+-#endif
+-#if SQLITE_OMIT_AUTHORIZATION
+-  "OMIT_AUTHORIZATION",
+-#endif
+-#if SQLITE_OMIT_AUTOINCREMENT
+-  "OMIT_AUTOINCREMENT",
+-#endif
+-#if SQLITE_OMIT_AUTOINIT
+-  "OMIT_AUTOINIT",
+-#endif
+-#if SQLITE_OMIT_AUTOMATIC_INDEX
+-  "OMIT_AUTOMATIC_INDEX",
+-#endif
+-#if SQLITE_OMIT_AUTORESET
+-  "OMIT_AUTORESET",
+-#endif
+-#if SQLITE_OMIT_AUTOVACUUM
+-  "OMIT_AUTOVACUUM",
+-#endif
+-#if SQLITE_OMIT_BETWEEN_OPTIMIZATION
+-  "OMIT_BETWEEN_OPTIMIZATION",
+-#endif
+-#if SQLITE_OMIT_BLOB_LITERAL
+-  "OMIT_BLOB_LITERAL",
+-#endif
+-#if SQLITE_OMIT_BTREECOUNT
+-  "OMIT_BTREECOUNT",
+-#endif
+-#if SQLITE_OMIT_BUILTIN_TEST
+-  "OMIT_BUILTIN_TEST",
+-#endif
+-#if SQLITE_OMIT_CAST
+-  "OMIT_CAST",
+-#endif
+-#if SQLITE_OMIT_CHECK
+-  "OMIT_CHECK",
+-#endif
+-#if SQLITE_OMIT_COMPLETE
+-  "OMIT_COMPLETE",
+-#endif
+-#if SQLITE_OMIT_COMPOUND_SELECT
+-  "OMIT_COMPOUND_SELECT",
+-#endif
+-#if SQLITE_OMIT_CTE
+-  "OMIT_CTE",
+-#endif
+-#if SQLITE_OMIT_DATETIME_FUNCS
+-  "OMIT_DATETIME_FUNCS",
+-#endif
+-#if SQLITE_OMIT_DECLTYPE
+-  "OMIT_DECLTYPE",
+-#endif
+-#if SQLITE_OMIT_DEPRECATED
+-  "OMIT_DEPRECATED",
+-#endif
+-#if SQLITE_OMIT_DISKIO
+-  "OMIT_DISKIO",
+-#endif
+-#if SQLITE_OMIT_EXPLAIN
+-  "OMIT_EXPLAIN",
+-#endif
+-#if SQLITE_OMIT_FLAG_PRAGMAS
+-  "OMIT_FLAG_PRAGMAS",
+-#endif
+-#if SQLITE_OMIT_FLOATING_POINT
+-  "OMIT_FLOATING_POINT",
+-#endif
+-#if SQLITE_OMIT_FOREIGN_KEY
+-  "OMIT_FOREIGN_KEY",
+-#endif
+-#if SQLITE_OMIT_GET_TABLE
+-  "OMIT_GET_TABLE",
+-#endif
+-#if SQLITE_OMIT_INCRBLOB
+-  "OMIT_INCRBLOB",
+-#endif
+-#if SQLITE_OMIT_INTEGRITY_CHECK
+-  "OMIT_INTEGRITY_CHECK",
+-#endif
+-#if SQLITE_OMIT_LIKE_OPTIMIZATION
+-  "OMIT_LIKE_OPTIMIZATION",
+-#endif
+-#if SQLITE_OMIT_LOAD_EXTENSION
+-  "OMIT_LOAD_EXTENSION",
+-#endif
+-#if SQLITE_OMIT_LOCALTIME
+-  "OMIT_LOCALTIME",
+-#endif
+-#if SQLITE_OMIT_LOOKASIDE
+-  "OMIT_LOOKASIDE",
+-#endif
+-#if SQLITE_OMIT_MEMORYDB
+-  "OMIT_MEMORYDB",
+-#endif
+-#if SQLITE_OMIT_OR_OPTIMIZATION
+-  "OMIT_OR_OPTIMIZATION",
+-#endif
+-#if SQLITE_OMIT_PAGER_PRAGMAS
+-  "OMIT_PAGER_PRAGMAS",
+-#endif
+-#if SQLITE_OMIT_PRAGMA
+-  "OMIT_PRAGMA",
+-#endif
+-#if SQLITE_OMIT_PROGRESS_CALLBACK
+-  "OMIT_PROGRESS_CALLBACK",
+-#endif
+-#if SQLITE_OMIT_QUICKBALANCE
+-  "OMIT_QUICKBALANCE",
+-#endif
+-#if SQLITE_OMIT_REINDEX
+-  "OMIT_REINDEX",
+-#endif
+-#if SQLITE_OMIT_SCHEMA_PRAGMAS
+-  "OMIT_SCHEMA_PRAGMAS",
+-#endif
+-#if SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
+-  "OMIT_SCHEMA_VERSION_PRAGMAS",
+-#endif
+-#if SQLITE_OMIT_SHARED_CACHE
+-  "OMIT_SHARED_CACHE",
+-#endif
+-#if SQLITE_OMIT_SUBQUERY
+-  "OMIT_SUBQUERY",
+-#endif
+-#if SQLITE_OMIT_TCL_VARIABLE
+-  "OMIT_TCL_VARIABLE",
+-#endif
+-#if SQLITE_OMIT_TEMPDB
+-  "OMIT_TEMPDB",
+-#endif
+-#if SQLITE_OMIT_TRACE
+-  "OMIT_TRACE",
+-#endif
+-#if SQLITE_OMIT_TRIGGER
+-  "OMIT_TRIGGER",
+-#endif
+-#if SQLITE_OMIT_TRUNCATE_OPTIMIZATION
+-  "OMIT_TRUNCATE_OPTIMIZATION",
+-#endif
+-#if SQLITE_OMIT_UTF16
+-  "OMIT_UTF16",
+-#endif
+-#if SQLITE_OMIT_VACUUM
+-  "OMIT_VACUUM",
+-#endif
+-#if SQLITE_OMIT_VIEW
+-  "OMIT_VIEW",
+-#endif
+-#if SQLITE_OMIT_VIRTUALTABLE
+-  "OMIT_VIRTUALTABLE",
+-#endif
+-#if SQLITE_OMIT_WAL
+-  "OMIT_WAL",
+-#endif
+-#if SQLITE_OMIT_WSD
+-  "OMIT_WSD",
+-#endif
+-#if SQLITE_OMIT_XFER_OPT
+-  "OMIT_XFER_OPT",
+-#endif
+-#if SQLITE_PERFORMANCE_TRACE
+-  "PERFORMANCE_TRACE",
+-#endif
+-#if SQLITE_PROXY_DEBUG
+-  "PROXY_DEBUG",
+-#endif
+-#if SQLITE_RTREE_INT_ONLY
+-  "RTREE_INT_ONLY",
+-#endif
+-#if SQLITE_SECURE_DELETE
+-  "SECURE_DELETE",
+-#endif
+-#if SQLITE_SMALL_STACK
+-  "SMALL_STACK",
+-#endif
+-#if SQLITE_SOUNDEX
+-  "SOUNDEX",
+-#endif
+-#if SQLITE_SYSTEM_MALLOC
+-  "SYSTEM_MALLOC",
+-#endif
+-#if SQLITE_TCL
+-  "TCL",
+-#endif
+-#if defined(SQLITE_TEMP_STORE) && !defined(SQLITE_TEMP_STORE_xc)
+-  "TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE),
+-#endif
+-#if SQLITE_TEST
+-  "TEST",
+-#endif
+-#if defined(SQLITE_THREADSAFE)
+-  "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE),
+-#endif
+-#if SQLITE_USE_ALLOCA
+-  "USE_ALLOCA",
+-#endif
+-#if SQLITE_USER_AUTHENTICATION
+-  "USER_AUTHENTICATION",
+-#endif
+-#if SQLITE_WIN32_MALLOC
+-  "WIN32_MALLOC",
+-#endif
+-#if SQLITE_ZERO_MALLOC
+-  "ZERO_MALLOC"
+-#endif
+-};
 +/* END SQLCIPHER */
-+
+ 
+-/*
+-** Given the name of a compile-time option, return true if that option
+-** was used and false if not.
+-**
+-** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix
+-** is not required for a match.
+-*/
+-SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName){
+-  int i, n;
 +/************** End of crypto.h **********************************************/
 +/************** Continuing where we left off in crypto.c *********************/
-+
+ 
+-#if SQLITE_ENABLE_API_ARMOR
+-  if( zOptName==0 ){
+-    (void)SQLITE_MISUSE_BKPT;
+-    return 0;
 +static const char* codec_get_cipher_version() {
 +  return CIPHER_VERSION;
 +}
@@ -1203,10 +1592,20 @@
 +    codec_ctx *ctx;
 +    sqlite3pager_get_codec(pDb->pBt->pBt->pPager, (void **) &ctx);
 +    if(ctx) return sqlcipher_codec_ctx_set_pass(ctx, zKey, nKey, for_ctx);
-+  }
+   }
+-#endif
+-  if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7;
+-  n = sqlite3Strlen30(zOptName);
 +  return SQLITE_ERROR;
 +} 
-+
+ 
+-  /* Since ArraySize(azCompileOpt) is normally in single digits, a
+-  ** linear search is adequate.  No need for a binary search. */
+-  for(i=0; i<ArraySize(azCompileOpt); i++){
+-    if( sqlite3StrNICmp(zOptName, azCompileOpt[i], n)==0
+-     && sqlite3IsIdChar((unsigned char)azCompileOpt[i][n])==0
+-    ){
+-      return 1;
 +int sqlcipher_codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLeft, const char *zRight) {
 +  struct Db *pDb = &db->aDb[iDb];
 +  codec_ctx *ctx = NULL;
@@ -1218,14 +1617,26 @@
 +
 +  CODEC_TRACE(("sqlcipher_codec_pragma: entered db=%p iDb=%d pParse=%p zLeft=%s zRight=%s ctx=%p\n", db, 
iDb, pParse, zLeft, zRight, ctx));
 +  
++  if( sqlite3StrICmp(zLeft, "cipher_fips_status")== 0 && !zRight ){
++    if(ctx) {
++      char *fips_mode_status = sqlite3_mprintf("%d", sqlcipher_codec_fips_status(ctx));
++      codec_vdbe_return_static_string(pParse, "cipher_fips_status", fips_mode_status);
++      sqlite3_free(fips_mode_status);
++    }
++  } else
 +  if( sqlite3StrICmp(zLeft, "cipher_store_pass")==0 && zRight ) {
-+    sqlcipher_codec_set_store_pass(ctx, sqlite3GetBoolean(zRight, 1));
++    if(ctx) {
++      sqlcipher_codec_set_store_pass(ctx, sqlite3GetBoolean(zRight, 1));
++    }
 +  } else
 +  if( sqlite3StrICmp(zLeft, "cipher_store_pass")==0 && !zRight ) {
-+    char *store_pass_value = sqlite3_mprintf("%d", sqlcipher_codec_get_store_pass(ctx));
-+    codec_vdbe_return_static_string(pParse, "cipher_store_pass", store_pass_value);
-+    sqlite3_free(store_pass_value);
-+  }
++    if(ctx){
++      char *store_pass_value = sqlite3_mprintf("%d", sqlcipher_codec_get_store_pass(ctx));
++      codec_vdbe_return_static_string(pParse, "cipher_store_pass", store_pass_value);
++      sqlite3_free(store_pass_value);
+     }
+   }
+-  return 0;
 +  if( sqlite3StrICmp(zLeft, "cipher_profile")== 0 && zRight ){
 +      char *profile_status = sqlite3_mprintf("%d", sqlcipher_cipher_profile(db, zRight));
 +      codec_vdbe_return_static_string(pParse, "cipher_profile", profile_status);
@@ -1315,6 +1726,15 @@
 +      }
 +    }
 +  }else
++  if( sqlite3StrICmp(zLeft,"cipher_default_page_size")==0 ){
++    if( zRight ) {
++      sqlcipher_set_default_pagesize(atoi(zRight));
++    } else {
++      char *default_page_size = sqlite3_mprintf("%d", sqlcipher_get_default_pagesize());
++      codec_vdbe_return_static_string(pParse, "cipher_default_page_size", default_page_size);
++      sqlite3_free(default_page_size);
++    }
++  }else
 +  if( sqlite3StrICmp(zLeft,"cipher_default_use_hmac")==0 ){
 +    if( zRight ) {
 +      sqlcipher_set_default_use_hmac(sqlite3GetBoolean(zRight,1));
@@ -1383,10 +1803,16 @@
 +    return 0;
 +  }
 +  return 1;
-+}
-+
+ }
+ 
 +
-+/*
+ /*
+-** Return the N-th compile-time option string.  If N is out of range,
+-** return a NULL pointer.
+-*/
+-SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N){
+-  if( N>=0 && N<ArraySize(azCompileOpt) ){
+-    return azCompileOpt[N];
 + * sqlite3Codec can be called in multiple modes.
 + * encrypt mode - expected to return a pointer to the 
 + *   encrypted data without altering pData.
@@ -1487,7 +1913,7 @@
 +  return SQLITE_OK;
 +}
 +
-+SQLITE_API void sqlite3_activate_see(const char* in) {
++SQLITE_API void SQLITE_STDCALL sqlite3_activate_see(const char* in) {
 +  /* do nothing, security enhancements are always active */
 +}
 +
@@ -1501,16 +1927,17 @@
 +    if(strcmp(pDb->zName, zDb) == 0) {
 +      return db_index;
 +    }
-+  }
-+  return 0;
-+}
-+
-+SQLITE_API int sqlite3_key(sqlite3 *db, const void *pKey, int nKey) {
+   }
+   return 0;
+ }
+ 
+-#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
++SQLITE_API int SQLITE_STDCALL sqlite3_key(sqlite3 *db, const void *pKey, int nKey) {
 +  CODEC_TRACE(("sqlite3_key entered: db=%p pKey=%s nKey=%d\n", db, (char *)pKey, nKey));
 +  return sqlite3_key_v2(db, "main", pKey, nKey);
 +}
 +
-+SQLITE_API int sqlite3_key_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) {
++SQLITE_API int SQLITE_STDCALL sqlite3_key_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) {
 +  CODEC_TRACE(("sqlite3_key_v2: entered db=%p zDb=%s pKey=%s nKey=%d\n", db, zDb, (char *)pKey, nKey));
 +  /* attach key if db and pKey are not null and nKey is > 0 */
 +  if(db && pKey && nKey) {
@@ -1520,7 +1947,7 @@
 +  return SQLITE_ERROR;
 +}
 +
-+SQLITE_API int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey) {
++SQLITE_API int SQLITE_STDCALL sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey) {
 +  CODEC_TRACE(("sqlite3_rekey entered: db=%p pKey=%s nKey=%d\n", db, (char *)pKey, nKey));
 +  return sqlite3_rekey_v2(db, "main", pKey, nKey);
 +}
@@ -1535,7 +1962,7 @@
 +** 2. If there is NOT already a key present do nothing
 +** 3. If there is a key present, re-encrypt the database with the new key
 +*/
-+SQLITE_API int sqlite3_rekey_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) {
++SQLITE_API int SQLITE_STDCALL sqlite3_rekey_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) {
 +  CODEC_TRACE(("sqlite3_rekey_v2: entered db=%p zDb=%s pKey=%s, nKey=%d\n", db, zDb, (char *)pKey, nKey));
 +  if(db && pKey && nKey) {
 +    int db_index = sqlcipher_find_db_index(db, zDb);
@@ -1591,7 +2018,7 @@
 +        sqlcipher_codec_key_copy(ctx, CIPHER_WRITE_CTX);
 +      } else {
 +        CODEC_TRACE(("sqlite3_rekey_v2: rollback\n"));
-+        sqlite3BtreeRollback(pDb->pBt, SQLITE_ABORT_ROLLBACK);
++        sqlite3BtreeRollback(pDb->pBt, SQLITE_ABORT_ROLLBACK, 0);
 +      }
 +
 +      sqlite3_mutex_leave(db->mutex);
@@ -1621,8 +2048,45 @@
 +}
 +
 +#ifndef OMIT_EXPORT
-+
-+/*
+ 
+-/************** End of ctime.c ***********************************************/
+-/************** Begin file status.c ******************************************/
+-/*
+-** 2008 June 18
+-**
+-** The author disclaims copyright to this source code.  In place of
+-** a legal notice, here is a blessing:
+-**
+-**    May you do good and not evil.
+-**    May you find forgiveness for yourself and forgive others.
+-**    May you share freely, never taking more than you give.
+-**
+-*************************************************************************
+-**
+-** This module implements the sqlite3_status() interface and related
+-** functionality.
+-*/
+-/************** Include vdbeInt.h in the middle of status.c ******************/
+-/************** Begin file vdbeInt.h *****************************************/
+ /*
+-** 2003 September 6
+-**
+-** The author disclaims copyright to this source code.  In place of
+-** a legal notice, here is a blessing:
+-**
+-**    May you do good and not evil.
+-**    May you find forgiveness for yourself and forgive others.
+-**    May you share freely, never taking more than you give.
+-**
+-*************************************************************************
+-** This is the header file for information that is private to the
+-** VDBE.  This information used to all be at the top of the single
+-** source code file "vdbe.c".  When that file became too big (over
+-** 6000 lines long) it was split up into several smaller files and
+-** this header information was factored out.
+-*/
+-#ifndef _VDBEINT_H_
+-#define _VDBEINT_H_
 + * Implementation of an "export" function that allows a caller
 + * to duplicate the main database to an attached database. This is intended
 + * as a conveneince for users who need to:
@@ -1635,13 +2099,18 @@
 + * in vacuum.c, but is exposed as a function that allows export to any
 + * named attached database.
 + */
-+
-+/*
+ 
+ /*
+-** The maximum number of times that a statement will try to reparse
+-** itself before giving up and returning SQLITE_SCHEMA.
 +** Finalize a prepared statement.  If there was an error, store the
 +** text of the error message in *pzErrMsg.  Return the result code.
 +** 
 +** Based on vacuumFinalize from vacuum.c
-+*/
+ */
+-#ifndef SQLITE_MAX_SCHEMA_RETRY
+-# define SQLITE_MAX_SCHEMA_RETRY 50
+-#endif
 +static int sqlcipher_finalize(sqlite3 *db, sqlite3_stmt *pStmt, char **pzErrMsg){
 +  int rc;
 +  rc = sqlite3VdbeFinalize((Vdbe*)pStmt);
@@ -1650,12 +2119,16 @@
 +  }
 +  return rc;
 +}
-+
-+/*
+ 
+ /*
+-** SQL is translated into a sequence of instructions to be
+-** executed by a virtual machine.  Each instruction is an instance
+-** of the following structure.
 +** Execute zSql on database db. Return an error code.
 +** 
 +** Based on execSql from vacuum.c
-+*/
+ */
+-typedef struct VdbeOp Op;
 +static int sqlcipher_execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
 +  sqlite3_stmt *pStmt;
 +  VVA_ONLY( int rc; )
@@ -1670,20 +2143,29 @@
 +  assert( rc!=SQLITE_ROW );
 +  return sqlcipher_finalize(db, pStmt, pzErrMsg);
 +}
-+
-+/*
+ 
+ /*
+-** Boolean values
 +** Execute zSql on database db. The statement returns exactly
 +** one column. Execute this as SQL on the same database.
 +** 
 +** Based on execExecSql from vacuum.c
-+*/
+ */
+-typedef unsigned Bool;
+-
+-/* Opaque type used by code in vdbesort.c */
+-typedef struct VdbeSorter VdbeSorter;
 +static int sqlcipher_execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){
 +  sqlite3_stmt *pStmt;
 +  int rc;
-+
+ 
+-/* Opaque type used by the explainer */
+-typedef struct Explain Explain;
 +  rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
 +  if( rc!=SQLITE_OK ) return rc;
-+
+ 
+-/* Elements of the linked list at Vdbe.pAuxData */
+-typedef struct AuxData AuxData;
 +  while( SQLITE_ROW==sqlite3_step(pStmt) ){
 +    rc = sqlcipher_execSql(db, pzErrMsg, (char*)sqlite3_column_text(pStmt, 0));
 +    if( rc!=SQLITE_OK ){
@@ -1694,12 +2176,33 @@
 +
 +  return sqlcipher_finalize(db, pStmt, pzErrMsg);
 +}
-+
-+/*
+ 
+ /*
+-** A cursor is a pointer into a single BTree within a database file.
+-** The cursor can seek to a BTree entry with a particular key, or
+-** loop over all entries of the Btree.  You can also insert new BTree
+-** entries or retrieve the key or data from the entry that the cursor
+-** is currently pointing to.
+-**
+-** Cursors can also point to virtual tables, sorters, or "pseudo-tables".
+-** A pseudo-table is a single-row table implemented by registers.
+-** 
+-** Every cursor that the virtual machine has open is represented by an
+-** instance of the following structure.
 + * copy database and schema from the main database to an attached database
 + * 
 + * Based on sqlite3RunVacuum from vacuum.c
-+*/
+ */
+-struct VdbeCursor {
+-  BtCursor *pCursor;    /* The cursor structure of the backend */
+-  Btree *pBt;           /* Separate file holding temporary table */
+-  KeyInfo *pKeyInfo;    /* Info about index keys needed by index cursors */
+-  int seekResult;       /* Result of previous sqlite3BtreeMoveto() */
+-  int pseudoTableReg;   /* Register holding pseudotable content. */
+-  i16 nField;           /* Number of fields in the header */
+-  u16 nHdrParsed;       /* Number of header fields parsed so far */
+-#ifdef SQLITE_DEBUG
+-  u8 seekOp;            /* Most recent seek operation on this cursor */
 +void sqlcipher_exportFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
 +  sqlite3 *db = sqlite3_context_db_handle(context);
 +  const char* attachedDb = (const char*) sqlite3_value_text(argv[0]);
@@ -1816,11 +2319,64 @@
 +  }
 +}
 +
-+#endif
-+
+ #endif
+-  i8 iDb;               /* Index of cursor database in db->aDb[] (or -1) */
+-  u8 nullRow;           /* True if pointing to a row with no data */
+-  u8 deferredMoveto;    /* A call to sqlite3BtreeMoveto() is needed */
+-  Bool isEphemeral:1;   /* True for an ephemeral table */
+-  Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
+-  Bool isTable:1;       /* True if a table requiring integer keys */
+-  Bool isOrdered:1;     /* True if the underlying table is BTREE_UNORDERED */
+-  Pgno pgnoRoot;        /* Root page of the open btree cursor */
+-  sqlite3_vtab_cursor *pVtabCursor;  /* The cursor for a virtual table */
+-  i64 seqCount;         /* Sequence counter */
+-  i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
+-  VdbeSorter *pSorter;  /* Sorter object for OP_SorterOpen cursors */
+ 
+-  /* Cached information about the header for the data record that the
+-  ** cursor is currently pointing to.  Only valid if cacheStatus matches
+-  ** Vdbe.cacheCtr.  Vdbe.cacheCtr will never take on the value of
+-  ** CACHE_STALE and so setting cacheStatus=CACHE_STALE guarantees that
+-  ** the cache is out of date.
+-  **
+-  ** aRow might point to (ephemeral) data for the current row, or it might
+-  ** be NULL.
+-  */
+-  u32 cacheStatus;      /* Cache is valid if this matches Vdbe.cacheCtr */
+-  u32 payloadSize;      /* Total number of bytes in the record */
+-  u32 szRow;            /* Byte available in aRow */
+-  u32 iHdrOffset;       /* Offset to next unparsed byte of the header */
+-  const u8 *aRow;       /* Data for the current row, if all on one page */
+-  u32 *aOffset;         /* Pointer to aType[nField] */
+-  u32 aType[1];         /* Type values for all entries in the record */
+-  /* 2*nField extra array elements allocated for aType[], beyond the one
+-  ** static element declared in the structure.  nField total array slots for
+-  ** aType[] and nField+1 array slots for aOffset[] */
+-};
+-typedef struct VdbeCursor VdbeCursor;
 +/* END SQLCIPHER */
 +#endif
-+
+ 
+-/*
+-** When a sub-program is executed (OP_Program), a structure of this type
+-** is allocated to store the current value of the program counter, as
+-** well as the current memory cell array and various other frame specific
+-** values stored in the Vdbe struct. When the sub-program is finished, 
+-** these values are copied back to the Vdbe from the VdbeFrame structure,
+-** restoring the state of the VM to as it was before the sub-program
+-** began executing.
+-**
+-** The memory for a VdbeFrame object is allocated and managed by a memory
+-** cell in the parent (calling) frame. When the memory cell is deleted or
+-** overwritten, the VdbeFrame object is not freed immediately. Instead, it
+-** is linked into the Vdbe.pDelFrame list. The contents of the Vdbe.pDelFrame
+-** list is deleted when the VM is reset in VdbeHalt(). The reason for doing
+-** this instead of deleting the VdbeFrame immediately is to avoid recursive
+-** calls to sqlite3VdbeMemRelease() when the memory cells belonging to the
+-** child frame are released.
+-**
+-** The currently executing frame is stored in Vdbe.pFrame. Vdbe.pFrame is
+-** set to NULL if the currently executing frame is the main program.
 +/************** End of crypto.c **********************************************/
 +/************** Begin file crypto_impl.c *************************************/
 +/* 
@@ -1852,10 +2408,35 @@
 +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 +**  
-+*/
+ */
+-typedef struct VdbeFrame VdbeFrame;
+-struct VdbeFrame {
+-  Vdbe *v;                /* VM this frame belongs to */
+-  VdbeFrame *pParent;     /* Parent of this frame, or NULL if parent is main */
+-  Op *aOp;                /* Program instructions for parent frame */
+-  i64 *anExec;            /* Event counters from parent frame */
+-  Mem *aMem;              /* Array of memory cells for parent frame */
+-  u8 *aOnceFlag;          /* Array of OP_Once flags for parent frame */
+-  VdbeCursor **apCsr;     /* Array of Vdbe cursors for parent frame */
+-  void *token;            /* Copy of SubProgram.token */
+-  i64 lastRowid;          /* Last insert rowid (sqlite3.lastRowid) */
+-  int nCursor;            /* Number of entries in apCsr */
+-  int pc;                 /* Program Counter in parent (calling) frame */
+-  int nOp;                /* Size of aOp array */
+-  int nMem;               /* Number of entries in aMem */
+-  int nOnceFlag;          /* Number of entries in aOnceFlag */
+-  int nChildMem;          /* Number of memory cells for child frame */
+-  int nChildCsr;          /* Number of cursors for child frame */
+-  int nChange;            /* Statement changes (Vdbe.nChange)     */
+-  int nDbChange;          /* Value of db->nChange */
+-};
+-
+-#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
 +/* BEGIN SQLCIPHER */
 +#ifdef SQLITE_HAS_CODEC
-+
+ 
+-/*
+-** A value for VdbeCursor.cacheValid that means the cache is always invalid.
 +/************** Include sqlcipher.h in the middle of crypto_impl.c ***********/
 +/************** Begin file sqlcipher.h ***************************************/
 +/* 
@@ -1889,12 +2470,41 @@
 +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 +**  
-+*/
+ */
+-#define CACHE_STALE 0
 +/* BEGIN SQLCIPHER */
 +#ifdef SQLITE_HAS_CODEC
 +#ifndef SQLCIPHER_H
 +#define SQLCIPHER_H
-+
+ 
+-/*
+-** Internally, the vdbe manipulates nearly all SQL values as Mem
+-** structures. Each Mem struct may cache multiple representations (string,
+-** integer etc.) of the same value.
+-*/
+-struct Mem {
+-  union MemValue {
+-    double r;           /* Real value used when MEM_Real is set in flags */
+-    i64 i;              /* Integer value used when MEM_Int is set in flags */
+-    int nZero;          /* Used when bit MEM_Zero is set in flags */
+-    FuncDef *pDef;      /* Used only when flags==MEM_Agg */
+-    RowSet *pRowSet;    /* Used only when flags==MEM_RowSet */
+-    VdbeFrame *pFrame;  /* Used when flags==MEM_Frame */
+-  } u;
+-  u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
+-  u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
+-  int n;              /* Number of characters in string value, excluding '\0' */
+-  char *z;            /* String or BLOB value */
+-  /* ShallowCopy only needs to copy the information above */
+-  char *zMalloc;      /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
+-  int szMalloc;       /* Size of the zMalloc allocation */
+-  u32 uTemp;          /* Transient storage for serial_type in OP_MakeRecord */
+-  sqlite3 *db;        /* The associated database connection */
+-  void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
+-#ifdef SQLITE_DEBUG
+-  Mem *pScopyFrom;    /* This Mem is a shallow copy of pScopyFrom */
+-  void *pFiller;      /* So that sizeof(Mem) is a multiple of 8 */
+-#endif
 +
 +typedef struct {
 +  int (*activate)(void *ctx);
@@ -1915,6 +2525,7 @@
 +  int (*ctx_cmp)(void *c1, void *c2);
 +  int (*ctx_init)(void **ctx);
 +  int (*ctx_free)(void **ctx);
++  int (*fips_status)(void *ctx);
 +} sqlcipher_provider;
 +
 +/* utility functions */
@@ -1937,7 +2548,7 @@
 +/************** End of sqlcipher.h *******************************************/
 +/************** Continuing where we left off in crypto_impl.c ****************/
 +#ifndef OMIT_MEMLOCK
-+#if defined(__unix__) || defined(__APPLE__) 
++#if defined(__unix__) || defined(__APPLE__) || defined(_AIX)
 +#include <sys/mman.h>
 +#elif defined(_WIN32)
 +# include <windows.h>
@@ -1971,6 +2582,7 @@
 +static unsigned int default_flags = DEFAULT_CIPHER_FLAGS;
 +static unsigned char hmac_salt_mask = HMAC_SALT_MASK;
 +static int default_kdf_iter = PBKDF2_ITER;
++static int default_page_size = SQLITE_DEFAULT_PAGE_SIZE;
 +static unsigned int sqlcipher_activate_count = 0;
 +static sqlite3_mutex* sqlcipher_provider_mutex = NULL;
 +static sqlcipher_provider *default_provider = NULL;
@@ -1986,8 +2598,31 @@
 +  cipher_ctx *write_ctx;
 +  unsigned int skip_read_hmac;
 +  unsigned int need_kdf_salt;
-+};
-+
+ };
+ 
+-/* One or more of the following flags are set to indicate the validOK
+-** representations of the value stored in the Mem struct.
+-**
+-** If the MEM_Null flag is set, then the value is an SQL NULL value.
+-** No other flags may be set in this case.
+-**
+-** If the MEM_Str flag is set then Mem.z points at a string representation.
+-** Usually this is encoded in the same unicode encoding as the main
+-** database (see below for exceptions). If the MEM_Term flag is also
+-** set, then the string is nul terminated. The MEM_Int and MEM_Real 
+-** flags may coexist with the MEM_Str flag.
+-*/
+-#define MEM_Null      0x0001   /* Value is NULL */
+-#define MEM_Str       0x0002   /* Value is a string */
+-#define MEM_Int       0x0004   /* Value is an integer */
+-#define MEM_Real      0x0008   /* Value is a real number */
+-#define MEM_Blob      0x0010   /* Value is a BLOB */
+-#define MEM_AffMask   0x001f   /* Mask of affinity bits */
+-#define MEM_RowSet    0x0020   /* Value is a RowSet object */
+-#define MEM_Frame     0x0040   /* Value is a VdbeFrame object */
+-#define MEM_Undefined 0x0080   /* Value is undefined */
+-#define MEM_Cleared   0x0100   /* NULL set by OP_Null, not from data */
+-#define MEM_TypeMask  0x01ff   /* Mask of type bits */
 +int sqlcipher_register_provider(sqlcipher_provider *p) {
 +  sqlite3_mutex_enter(sqlcipher_provider_mutex);
 +  if(default_provider != NULL && default_provider != p) {
@@ -2000,22 +2635,48 @@
 +  sqlite3_mutex_leave(sqlcipher_provider_mutex);
 +  return SQLITE_OK;
 +}
-+
+ 
 +/* return a pointer to the currently registered provider. This will
 +   allow an application to fetch the current registered provider and
 +   make minor changes to it */
 +sqlcipher_provider* sqlcipher_get_provider() {
 +  return default_provider;
 +}
-+
+ 
+-/* Whenever Mem contains a valid string or blob representation, one of
+-** the following flags must be set to determine the memory management
+-** policy for Mem.z.  The MEM_Term flag tells us whether or not the
+-** string is \000 or \u0000 terminated
+-*/
+-#define MEM_Term      0x0200   /* String rep is nul terminated */
+-#define MEM_Dyn       0x0400   /* Need to call Mem.xDel() on Mem.z */
+-#define MEM_Static    0x0800   /* Mem.z points to a static string */
+-#define MEM_Ephem     0x1000   /* Mem.z points to an ephemeral string */
+-#define MEM_Agg       0x2000   /* Mem.z points to an agg function context */
+-#define MEM_Zero      0x4000   /* Mem.i contains count of 0s appended to blob */
+-#ifdef SQLITE_OMIT_INCRBLOB
+-  #undef MEM_Zero
+-  #define MEM_Zero 0x0000
+-#endif
 +void sqlcipher_activate() {
 +  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
-+
+ 
+-/*
+-** Clear any existing type flags from a Mem and replace them with f
+-*/
+-#define MemSetTypeFlag(p, f) \
+-   ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f)
 +  if(sqlcipher_provider_mutex == NULL) {
 +    /* allocate a new mutex to guard access to the provider */
 +    sqlcipher_provider_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
 +  }
-+
+ 
+-/*
+-** Return true if a memory cell is not marked as invalid.  This macro
+-** is for use inside assert() statements only.
+-*/
+-#ifdef SQLITE_DEBUG
+-#define memIsValid(M)  ((M)->flags & MEM_Undefined)==0
 +  /* check to see if there is a provider registered at this point
 +     if there no provider registered at this point, register the 
 +     default provider */
@@ -2032,15 +2693,63 @@
 +    sqlcipher_openssl_setup(p);
 +#else
 +#error "NO DEFAULT SQLCIPHER CRYPTO PROVIDER DEFINED"
-+#endif
+ #endif
 +    sqlcipher_register_provider(p);
 +  }
-+
+ 
+-/*
+-** Each auxiliary data pointer stored by a user defined function 
+-** implementation calling sqlite3_set_auxdata() is stored in an instance
+-** of this structure. All such structures associated with a single VM
+-** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed
+-** when the VM is halted (if not before).
+-*/
+-struct AuxData {
+-  int iOp;                        /* Instruction number of OP_Function opcode */
+-  int iArg;                       /* Index of function argument. */
+-  void *pAux;                     /* Aux data pointer */
+-  void (*xDelete)(void *);        /* Destructor for the aux data */
+-  AuxData *pNext;                 /* Next element in list */
+-};
 +  sqlcipher_activate_count++; /* increment activation count */
-+
+ 
+-/*
+-** The "context" argument for an installable function.  A pointer to an
+-** instance of this structure is the first argument to the routines used
+-** implement the SQL functions.
+-**
+-** There is a typedef for this structure in sqlite.h.  So all routines,
+-** even the public interface to SQLite, can use a pointer to this structure.
+-** But this file is the only place where the internal details of this
+-** structure are known.
+-**
+-** This structure is defined inside of vdbeInt.h because it uses substructures
+-** (Mem) which are only defined there.
+-*/
+-struct sqlite3_context {
+-  Mem *pOut;            /* The return value is stored here */
+-  FuncDef *pFunc;       /* Pointer to function information */
+-  Mem *pMem;            /* Memory cell used to store aggregate context */
+-  Vdbe *pVdbe;          /* The VM that owns this context */
+-  int iOp;              /* Instruction number of OP_Function */
+-  int isError;          /* Error code returned by the function. */
+-  u8 skipFlag;          /* Skip accumulator loading if true */
+-  u8 fErrorOrAux;       /* isError!=0 or pVdbe->pAuxData modified */
+-};
 +  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
 +}
-+
+ 
+-/*
+-** An Explain object accumulates indented output which is helpful
+-** in describing recursive data structures.
+-*/
+-struct Explain {
+-  Vdbe *pVdbe;       /* Attach the explanation to this Vdbe */
+-  StrAccum str;      /* The string being accumulated */
+-  int nIndent;       /* Number of elements in aIndent */
+-  u16 aIndent[100];  /* Levels of indentation */
+-  char zBase[100];   /* Initial space */
+-};
 +void sqlcipher_deactivate() {
 +  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
 +  sqlcipher_activate_count--;
@@ -2056,7 +2765,9 @@
 +    /* last connection closed, free provider mutex*/
 +    sqlite3_mutex_free(sqlcipher_provider_mutex); 
 +    sqlcipher_provider_mutex = NULL;
-+
+ 
+-/* A bitfield type for use inside of structures.  Always follow with :N where
+-** N is the number of bits.
 +    sqlcipher_activate_count = 0; /* reset activation count */
 +  }
 +  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
@@ -2065,47 +2776,218 @@
 +/* constant time memset using volitile to avoid having the memset
 +   optimized out by the compiler. 
 +   Note: As suggested by Joachim Schipper (joachim schipper fox-it com)
-+*/
+ */
+-typedef unsigned bft;  /* Bit Field Type */
 +void* sqlcipher_memset(void *v, unsigned char value, int len) {
 +  int i = 0;
 +  volatile unsigned char *a = v;
-+
+ 
+-typedef struct ScanStatus ScanStatus;
+-struct ScanStatus {
+-  int addrExplain;                /* OP_Explain for loop */
+-  int addrLoop;                   /* Address of "loops" counter */
+-  int addrVisit;                  /* Address of "rows visited" counter */
+-  int iSelectID;                  /* The "Select-ID" for this loop */
+-  LogEst nEst;                    /* Estimated output rows per loop */
+-  char *zName;                    /* Name of table or index */
+-};
 +  if (v == NULL) return v;
-+
+ 
+-/*
+-** An instance of the virtual machine.  This structure contains the complete
+-** state of the virtual machine.
+-**
+-** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare()
+-** is really a pointer to an instance of this structure.
+-*/
+-struct Vdbe {
+-  sqlite3 *db;            /* The database connection that owns this statement */
+-  Op *aOp;                /* Space to hold the virtual machine's program */
+-  Mem *aMem;              /* The memory locations */
+-  Mem **apArg;            /* Arguments to currently executing user function */
+-  Mem *aColName;          /* Column names to return */
+-  Mem *pResultSet;        /* Pointer to an array of results */
+-  Parse *pParse;          /* Parsing context used to create this Vdbe */
+-  int nMem;               /* Number of memory locations currently allocated */
+-  int nOp;                /* Number of instructions in the program */
+-  int nCursor;            /* Number of slots in apCsr[] */
+-  u32 magic;              /* Magic number for sanity checking */
+-  char *zErrMsg;          /* Error message written here */
+-  Vdbe *pPrev,*pNext;     /* Linked list of VDBEs with the same Vdbe.db */
+-  VdbeCursor **apCsr;     /* One element of this array for each open cursor */
+-  Mem *aVar;              /* Values for the OP_Variable opcode. */
+-  char **azVar;           /* Name of variables */
+-  ynVar nVar;             /* Number of entries in aVar[] */
+-  ynVar nzVar;            /* Number of entries in azVar[] */
+-  u32 cacheCtr;           /* VdbeCursor row cache generation counter */
+-  int pc;                 /* The program counter */
+-  int rc;                 /* Value to return */
+-#ifdef SQLITE_DEBUG
+-  int rcApp;              /* errcode set by sqlite3_result_error_code() */
+-#endif
+-  u16 nResColumn;         /* Number of columns in one row of the result set */
+-  u8 errorAction;         /* Recovery action to do in case of an error */
+-  u8 minWriteFileFormat;  /* Minimum file format for writable database files */
+-  bft explain:2;          /* True if EXPLAIN present on SQL command */
+-  bft changeCntOn:1;      /* True to update the change-counter */
+-  bft expired:1;          /* True if the VM needs to be recompiled */
+-  bft runOnlyOnce:1;      /* Automatically expire on reset */
+-  bft usesStmtJournal:1;  /* True if uses a statement journal */
+-  bft readOnly:1;         /* True for statements that do not write */
+-  bft bIsReader:1;        /* True for statements that read */
+-  bft isPrepareV2:1;      /* True if prepared with prepare_v2() */
+-  bft doingRerun:1;       /* True if rerunning after an auto-reprepare */
+-  int nChange;            /* Number of db changes made since last reset */
+-  yDbMask btreeMask;      /* Bitmask of db->aDb[] entries referenced */
+-  yDbMask lockMask;       /* Subset of btreeMask that requires a lock */
+-  int iStatement;         /* Statement number (or 0 if has not opened stmt) */
+-  u32 aCounter[5];        /* Counters used by sqlite3_stmt_status() */
+-#ifndef SQLITE_OMIT_TRACE
+-  i64 startTime;          /* Time when query started - used for profiling */
+-#endif
+-  i64 iCurrentTime;       /* Value of julianday('now') for this statement */
+-  i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
+-  i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
+-  i64 nStmtDefImmCons;    /* Number of def. imm constraints when stmt started */
+-  char *zSql;             /* Text of the SQL statement that generated this */
+-  void *pFree;            /* Free this when deleting the vdbe */
+-  VdbeFrame *pFrame;      /* Parent frame */
+-  VdbeFrame *pDelFrame;   /* List of frame objects to free on VM reset */
+-  int nFrame;             /* Number of frames in pFrame list */
+-  u32 expmask;            /* Binding to these vars invalidates VM */
+-  SubProgram *pProgram;   /* Linked list of all sub-programs used by VM */
+-  int nOnceFlag;          /* Size of array aOnceFlag[] */
+-  u8 *aOnceFlag;          /* Flags for OP_Once */
+-  AuxData *pAuxData;      /* Linked list of auxdata allocations */
+-#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+-  i64 *anExec;            /* Number of times each op has been executed */
+-  int nScan;              /* Entries in aScan[] */
+-  ScanStatus *aScan;      /* Scan definitions for sqlite3_stmt_scanstatus() */
+-#endif
+-};
 +  for(i = 0; i < len; i++) {
 +    a[i] = value;
 +  }
-+
+ 
+-/*
+-** The following are allowed values for Vdbe.magic
+-*/
+-#define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */
+-#define VDBE_MAGIC_RUN      0xbdf20da3    /* VDBE is ready to execute */
+-#define VDBE_MAGIC_HALT     0x519c2973    /* VDBE has completed execution */
+-#define VDBE_MAGIC_DEAD     0xb606c3c8    /* The VDBE has been deallocated */
 +  return v;
 +}
-+
+ 
+-/*
+-** Function prototypes
+-*/
+-SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
+-void sqliteVdbePopStack(Vdbe*,int);
+-SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*);
+-SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
+-#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
+-SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
+-#endif
+-SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
+-SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
+-SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
+-SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
+-SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
 +/* constant time memory check tests every position of a memory segement
 +   matches a single value (i.e. the memory is all zeros)
 +   returns 0 if match, 1 of no match */
 +int sqlcipher_ismemset(const void *v, unsigned char value, int len) {
 +  const unsigned char *a = v;
 +  int i = 0, result = 0;
-+
+ 
+-int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
+-SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
+-SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
+-SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
+-SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
+-SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
+-SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int);
+-SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*);
+-SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem*, const Mem*);
+-SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int);
+-SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem*, Mem*);
+-SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem*);
+-SQLITE_PRIVATE int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*));
+-SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem*, i64);
+-#ifdef SQLITE_OMIT_FLOATING_POINT
+-# define sqlite3VdbeMemSetDouble sqlite3VdbeMemSetInt64
+-#else
+-SQLITE_PRIVATE   void sqlite3VdbeMemSetDouble(Mem*, double);
+-#endif
+-SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
+-SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*);
+-SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int);
+-SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem*);
+-SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
+-SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8);
+-SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*);
+-SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*);
+-SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*);
+-SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*);
+-SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*);
+-SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
+-SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem*,u8,u8);
+-SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*);
+-SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
+-#define VdbeMemDynamic(X)  \
+-  (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
+-SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
+-SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
+-SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
+-SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
+-SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
+-SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*);
+-SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *);
+-SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p);
 +  for(i = 0; i < len; i++) {
 +    result |= a[i] ^ value;
 +  }
-+
+ 
+-SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, int, VdbeCursor *);
+-SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *, VdbeSorter *);
+-SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *);
+-SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *);
+-SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *);
+-SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *, int *);
+-SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *);
+-SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
 +  return (result != 0);
 +}
-+
+ 
+-#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
+-SQLITE_PRIVATE   void sqlite3VdbeEnter(Vdbe*);
+-SQLITE_PRIVATE   void sqlite3VdbeLeave(Vdbe*);
+-#else
+-# define sqlite3VdbeEnter(X)
+-# define sqlite3VdbeLeave(X)
+-#endif
 +/* constant time memory comparison routine. 
 +   returns 0 if match, 1 if no match */
 +int sqlcipher_memcmp(const void *v0, const void *v1, int len) {
 +  const unsigned char *a0 = v0, *a1 = v1;
 +  int i = 0, result = 0;
-+
+ 
+-#ifdef SQLITE_DEBUG
+-SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe*,Mem*);
+-SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem*);
+-#endif
 +  for(i = 0; i < len; i++) {
 +    result |= a0[i] ^ a1[i];
 +  }
 +  
 +  return (result != 0);
 +}
-+
+ 
+-#ifndef SQLITE_OMIT_FOREIGN_KEY
+-SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *, int);
+-#else
+-# define sqlite3VdbeCheckFk(p,i) 0
 +/**
 +  * Free and wipe memory. Uses SQLites internal sqlite3_free so that memory
 +  * can be countend and memory leak detection works in the test suite. 
@@ -2124,14 +3006,26 @@
 +#elif defined(_WIN32)
 +#if !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP || WINAPI_FAMILY == 
WINAPI_FAMILY_APP))
 +VirtualUnlock(ptr, sz);
-+#endif
-+#endif
+ #endif
+-
+-SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem*, u8);
+-#ifdef SQLITE_DEBUG
+-SQLITE_PRIVATE   void sqlite3VdbePrintSql(Vdbe*);
+-SQLITE_PRIVATE   void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
+ #endif
+-SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem);
 +#endif
 +    }
 +    sqlite3_free(ptr);
 +  }
 +}
-+
+ 
+-#ifndef SQLITE_OMIT_INCRBLOB
+-SQLITE_PRIVATE   int sqlite3VdbeMemExpandBlob(Mem *);
+-  #define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0)
+-#else
+-  #define sqlite3VdbeMemExpandBlob(x) SQLITE_OK
+-  #define ExpandBlob(P) SQLITE_OK
 +/**
 +  * allocate memory. Uses sqlite's internall malloc wrapper so memory can be 
 +  * reference counted and leak detection works. Unless compiled with OMIT_MEMLOCK
@@ -2148,13 +3042,16 @@
 +#if !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP || WINAPI_FAMILY == 
WINAPI_FAMILY_APP))
 +    VirtualLock(ptr, sz);
 +#endif
-+#endif
+ #endif
 +  }
 +#endif
 +  return ptr;
 +}
-+
-+
+ 
+-#endif /* !defined(_VDBEINT_H_) */
+ 
+-/************** End of vdbeInt.h *********************************************/
+-/************** Continuing where we left off in status.c *********************/
 +/**
 +  * Initialize new cipher_ctx struct. This function will allocate memory
 +  * for the cipher context and for the key
@@ -2182,13 +3079,42 @@
 +  ctx->hmac_key = (unsigned char *) sqlcipher_malloc(CIPHER_MAX_KEY_SZ);
 +  if(ctx->key == NULL) return SQLITE_NOMEM;
 +  if(ctx->hmac_key == NULL) return SQLITE_NOMEM;
-+
+ 
+-/*
+-** Variables in which to record status information.
+-*/
+-typedef struct sqlite3StatType sqlite3StatType;
+-static SQLITE_WSD struct sqlite3StatType {
+-#if SQLITE_PTRSIZE>4
+-  sqlite3_int64 nowValue[10];         /* Current value */
+-  sqlite3_int64 mxValue[10];          /* Maximum value */
+-#else
+-  u32 nowValue[10];                   /* Current value */
+-  u32 mxValue[10];                    /* Maximum value */
+-#endif
+-} sqlite3Stat = { {0,}, {0,} };
 +  /* setup default flags */
 +  ctx->flags = default_flags;
-+
+ 
+-/*
+-** Elements of sqlite3Stat[] are protected by either the memory allocator
+-** mutex, or by the pcache1 mutex.  The following array determines which.
+-*/
+-static const char statMutex[] = {
+-  0,  /* SQLITE_STATUS_MEMORY_USED */
+-  1,  /* SQLITE_STATUS_PAGECACHE_USED */
+-  1,  /* SQLITE_STATUS_PAGECACHE_OVERFLOW */
+-  0,  /* SQLITE_STATUS_SCRATCH_USED */
+-  0,  /* SQLITE_STATUS_SCRATCH_OVERFLOW */
+-  0,  /* SQLITE_STATUS_MALLOC_SIZE */
+-  0,  /* SQLITE_STATUS_PARSER_STACK */
+-  1,  /* SQLITE_STATUS_PAGECACHE_SIZE */
+-  0,  /* SQLITE_STATUS_SCRATCH_SIZE */
+-  0,  /* SQLITE_STATUS_MALLOC_COUNT */
+-};
 +  return SQLITE_OK;
 +}
-+
+ 
 +/**
 +  * Free and wipe memory associated with a cipher_ctx
 +  */
@@ -2307,7 +3233,20 @@
 +  }
 +  return SQLITE_OK;
 +}
-+
+ 
+-/* The "wsdStat" macro will resolve to the status information
+-** state vector.  If writable static data is unsupported on the target,
+-** we have to locate the state vector at run-time.  In the more common
+-** case where writable static data is supported, wsdStat can refer directly
+-** to the "sqlite3Stat" state vector declared above.
+-*/
+-#ifdef SQLITE_OMIT_WSD
+-# define wsdStatInit  sqlite3StatType *x = &GLOBAL(sqlite3StatType,sqlite3Stat)
+-# define wsdStat x[0]
+-#else
+-# define wsdStatInit
+-# define wsdStat sqlite3Stat
+-#endif
 +/**
 +  * Set the keyspec for the cipher_ctx
 +  * 
@@ -2334,20 +3273,74 @@
 +  ctx->keyspec[ctx->keyspec_sz - 1] = '\'';
 +  return SQLITE_OK;
 +}
-+
-+static int sqlcipher_codec_get_store_pass(codec_ctx *ctx) {
+ 
+-/*
+-** Return the current value of a status parameter.  The caller must
+-** be holding the appropriate mutex.
+-*/
+-SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int op){
+-  wsdStatInit;
+-  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
+-  assert( op>=0 && op<ArraySize(statMutex) );
+-  assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
+-                                           : sqlite3MallocMutex()) );
+-  return wsdStat.nowValue[op];
++int sqlcipher_codec_get_store_pass(codec_ctx *ctx) {
 +  return ctx->read_ctx->store_pass;
-+}
-+
-+static void sqlcipher_codec_set_store_pass(codec_ctx *ctx, int value) {
+ }
+ 
+-/*
+-** Add N to the value of a status record.  The caller must hold the
+-** appropriate mutex.  (Locking is checked by assert()).
+-**
+-** The StatusUp() routine can accept positive or negative values for N.
+-** The value of N is added to the current status value and the high-water
+-** mark is adjusted if necessary.
+-**
+-** The StatusDown() routine lowers the current value by N.  The highwater
+-** mark is unchanged.  N must be non-negative for StatusDown().
+-*/
+-SQLITE_PRIVATE void sqlite3StatusUp(int op, int N){
+-  wsdStatInit;
+-  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
+-  assert( op>=0 && op<ArraySize(statMutex) );
+-  assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
+-                                           : sqlite3MallocMutex()) );
+-  wsdStat.nowValue[op] += N;
+-  if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
+-    wsdStat.mxValue[op] = wsdStat.nowValue[op];
+-  }
++void sqlcipher_codec_set_store_pass(codec_ctx *ctx, int value) {
 +  ctx->read_ctx->store_pass = value;
-+}
-+
-+static void sqlcipher_codec_get_pass(codec_ctx *ctx, void **zKey, int *nKey) {
+ }
+-SQLITE_PRIVATE void sqlite3StatusDown(int op, int N){
+-  wsdStatInit;
+-  assert( N>=0 );
+-  assert( op>=0 && op<ArraySize(statMutex) );
+-  assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
+-                                           : sqlite3MallocMutex()) );
+-  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
+-  wsdStat.nowValue[op] -= N;
++
++void sqlcipher_codec_get_pass(codec_ctx *ctx, void **zKey, int *nKey) {
 +  *zKey = ctx->read_ctx->pass;
 +  *nKey = ctx->read_ctx->pass_sz;
-+}
-+
+ }
+ 
+-/*
+-** Set the value of a status to X.  The highwater mark is adjusted if
+-** necessary.  The caller must hold the appropriate mutex.
+-*/
+-SQLITE_PRIVATE void sqlite3StatusSet(int op, int X){
+-  wsdStatInit;
+-  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
+-  assert( op>=0 && op<ArraySize(statMutex) );
+-  assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
+-                                           : sqlite3MallocMutex()) );
+-  wsdStat.nowValue[op] = X;
+-  if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
+-    wsdStat.mxValue[op] = wsdStat.nowValue[op];
+-  }
 +/**
 +  * Set the passphrase for the cipher_ctx
 +  * 
@@ -2368,8 +3361,34 @@
 +    memcpy(ctx->pass, zKey, nKey);
 +  } 
 +  return SQLITE_OK;
-+}
-+
+ }
+ 
+-/*
+-** Query status information.
+-*/
+-SQLITE_API int SQLITE_STDCALL sqlite3_status64(
+-  int op,
+-  sqlite3_int64 *pCurrent,
+-  sqlite3_int64 *pHighwater,
+-  int resetFlag
+-){
+-  sqlite3_mutex *pMutex;
+-  wsdStatInit;
+-  if( op<0 || op>=ArraySize(wsdStat.nowValue) ){
+-    return SQLITE_MISUSE_BKPT;
+-  }
+-#ifdef SQLITE_ENABLE_API_ARMOR
+-  if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT;
+-#endif
+-  pMutex = statMutex[op] ? sqlite3Pcache1Mutex() : sqlite3MallocMutex();
+-  sqlite3_mutex_enter(pMutex);
+-  *pCurrent = wsdStat.nowValue[op];
+-  *pHighwater = wsdStat.mxValue[op];
+-  if( resetFlag ){
+-    wsdStat.mxValue[op] = wsdStat.nowValue[op];
+-  }
+-  sqlite3_mutex_leave(pMutex);
+-  (void)pMutex;  /* Prevent warning when SQLITE_THREADSAFE=0 */
 +int sqlcipher_codec_ctx_set_pass(codec_ctx *ctx, const void *zKey, int nKey, int for_ctx) {
 +  cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
 +  int rc;
@@ -2400,8 +3419,10 @@
 +    if((rc = sqlcipher_cipher_ctx_copy( for_ctx ? ctx->read_ctx : ctx->write_ctx, c_ctx)) != SQLITE_OK)
 +      return rc; 
 +
-+  return SQLITE_OK;
-+}
+   return SQLITE_OK;
+ }
+-SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
+-  sqlite3_int64 iCur, iHwtr;
 +
 +const char* sqlcipher_codec_ctx_get_cipher(codec_ctx *ctx, int for_ctx) {
 +  cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
@@ -2419,7 +3440,14 @@
 +
 +int sqlcipher_codec_ctx_set_kdf_iter(codec_ctx *ctx, int kdf_iter, int for_ctx) {
 +  cipher_ctx *c_ctx = for_ctx ? ctx->write_ctx : ctx->read_ctx;
-+  int rc;
+   int rc;
+-#ifdef SQLITE_ENABLE_API_ARMOR
+-  if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT;
+-#endif
+-  rc = sqlite3_status64(op, &iCur, &iHwtr, resetFlag);
+-  if( rc==0 ){
+-    *pCurrent = (int)iCur;
+-    *pHighwater = (int)iHwtr;
 +
 +  c_ctx->kdf_iter = kdf_iter;
 +  c_ctx->derive_key = 1;
@@ -2562,6 +3590,14 @@
 +  return ctx->page_sz;
 +}
 +
++void sqlcipher_set_default_pagesize(int page_size) {
++  default_page_size = page_size;
++}
++
++int sqlcipher_get_default_pagesize() {
++  return default_page_size;
++}
++
 +int sqlcipher_codec_ctx_init(codec_ctx **iCtx, Db *pDb, Pager *pPager, sqlite3_file *fd, const void *zKey, 
int nKey) {
 +  int rc;
 +  codec_ctx *ctx;
@@ -2592,14 +3628,15 @@
 +     in encrypted and thus sqlite can't effectively determine the pagesize. this causes an issue in 
 +     cases where bytes 16 & 17 of the page header are a power of 2 as reported by John Lehman
 +  */
-+  if((rc = sqlcipher_codec_ctx_set_pagesize(ctx, SQLITE_DEFAULT_PAGE_SIZE)) != SQLITE_OK) return rc;
++  if((rc = sqlcipher_codec_ctx_set_pagesize(ctx, default_page_size)) != SQLITE_OK) return rc;
 +
 +  if((rc = sqlcipher_cipher_ctx_init(&ctx->read_ctx)) != SQLITE_OK) return rc; 
 +  if((rc = sqlcipher_cipher_ctx_init(&ctx->write_ctx)) != SQLITE_OK) return rc; 
 +
 +  if(fd == NULL || sqlite3OsRead(fd, ctx->kdf_salt, FILE_HEADER_SZ, 0) != SQLITE_OK) {
 +    ctx->need_kdf_salt = 1;
-+  }
+   }
+-  return rc;
 +
 +  if((rc = sqlcipher_codec_ctx_set_cipher(ctx, CIPHER, 0)) != SQLITE_OK) return rc;
 +  if((rc = sqlcipher_codec_ctx_set_kdf_iter(ctx, default_kdf_iter, 0)) != SQLITE_OK) return rc;
@@ -2665,9 +3702,33 @@
 +    in_sz, (unsigned char*) &pgno_raw,
 +    sizeof(pgno), out);
 +  return SQLITE_OK; 
-+}
-+
-+/*
+ }
+ 
+ /*
+-** Query status information for a single database connection
+-*/
+-SQLITE_API int SQLITE_STDCALL sqlite3_db_status(
+-  sqlite3 *db,          /* The database connection whose status is desired */
+-  int op,               /* Status verb */
+-  int *pCurrent,        /* Write current value here */
+-  int *pHighwater,      /* Write high-water mark here */
+-  int resetFlag         /* Reset high-water mark if true */
+-){
+-  int rc = SQLITE_OK;   /* Return code */
+-#ifdef SQLITE_ENABLE_API_ARMOR
+-  if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwater==0 ){
+-    return SQLITE_MISUSE_BKPT;
+-  }
+-#endif
+-  sqlite3_mutex_enter(db->mutex);
+-  switch( op ){
+-    case SQLITE_DBSTATUS_LOOKASIDE_USED: {
+-      *pCurrent = db->lookaside.nOut;
+-      *pHighwater = db->lookaside.mxOut;
+-      if( resetFlag ){
+-        db->lookaside.mxOut = db->lookaside.nOut;
+-      }
+-      break;
 + * ctx - codec context
 + * pgno - page number in database
 + * size - size in bytes of input and output buffers
@@ -2713,8 +3774,20 @@
 +      sqlcipher_memset(out, 0, page_sz); 
 +      CODEC_TRACE(("codec_cipher: hmac operations failed for pgno=%d\n", pgno));
 +      return SQLITE_ERROR;
-+    }
-+
+     }
+ 
+-    case SQLITE_DBSTATUS_LOOKASIDE_HIT:
+-    case SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE:
+-    case SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL: {
+-      testcase( op==SQLITE_DBSTATUS_LOOKASIDE_HIT );
+-      testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE );
+-      testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL );
+-      assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)>=0 );
+-      assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)<3 );
+-      *pCurrent = 0;
+-      *pHighwater = db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT];
+-      if( resetFlag ){
+-        db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT] = 0;
 +    CODEC_TRACE(("codec_cipher: comparing hmac on in=%p out=%p hmac_sz=%d\n", hmac_in, hmac_out, 
c_ctx->hmac_sz));
 +    if(sqlcipher_memcmp(hmac_in, hmac_out, c_ctx->hmac_sz) != 0) { /* the hmac check failed */ 
 +      if(sqlcipher_ismemset(in, 0, page_sz) == 0) {
@@ -2732,12 +3805,20 @@
 +              CODEC_TRACE(("codec_cipher: hmac check failed for pgno=%d returning SQLITE_ERROR\n", pgno));
 +        sqlcipher_memset(out, 0, page_sz); 
 +              return SQLITE_ERROR;
-+      }
-+    }
+       }
+-      break;
+     }
 +  } 
 +  
 +  c_ctx->provider->cipher(c_ctx->provider_ctx, mode, c_ctx->key, c_ctx->key_sz, iv_out, in, size, out);
-+
+ 
+-    /* 
+-    ** Return an approximation for the amount of memory currently used
+-    ** by all pagers associated with the given database connection.  The
+-    ** highwater mark is meaningless and is returned as zero.
+-    */
+-    case SQLITE_DBSTATUS_CACHE_USED: {
+-      int totalUsed = 0;
 +  if((c_ctx->flags & CIPHER_FLAG_HMAC) && (mode == CIPHER_ENCRYPT)) {
 +    sqlcipher_page_hmac(c_ctx, pgno, out_start, size + c_ctx->iv_sz, hmac_out); 
 +  }
@@ -2801,8 +3882,29 @@
 +       key for HMAC. In this case, we use the output of the previous KDF as the input to 
 +       this KDF run. This ensures a distinct but predictable HMAC key. */
 +    if(c_ctx->flags & CIPHER_FLAG_HMAC) {
-+      int i;
-+
+       int i;
+-      sqlite3BtreeEnterAll(db);
+-      for(i=0; i<db->nDb; i++){
+-        Btree *pBt = db->aDb[i].pBt;
+-        if( pBt ){
+-          Pager *pPager = sqlite3BtreePager(pBt);
+-          totalUsed += sqlite3PagerMemUsed(pPager);
+-        }
+-      }
+-      sqlite3BtreeLeaveAll(db);
+-      *pCurrent = totalUsed;
+-      *pHighwater = 0;
+-      break;
+-    }
+ 
+-    /*
+-    ** *pCurrent gets an accurate estimate of the amount of memory used
+-    ** to store the schema for all databases (main, temp, and any ATTACHed
+-    ** databases.  *pHighwater is set to zero.
+-    */
+-    case SQLITE_DBSTATUS_SCHEMA_USED: {
+-      int i;                      /* Used to iterate through schemas */
+-      int nByte = 0;              /* Used to accumulate return value */
 +      /* start by copying the kdf key into the hmac salt slot
 +         then XOR it with the fixed hmac salt defined at compile time
 +         this ensures that the salt passed in to derive the hmac key, while 
@@ -2812,22 +3914,51 @@
 +      for(i = 0; i < ctx->kdf_salt_sz; i++) {
 +        ctx->hmac_kdf_salt[i] ^= hmac_salt_mask;
 +      } 
-+
+ 
+-      sqlite3BtreeEnterAll(db);
+-      db->pnBytesFreed = &nByte;
+-      for(i=0; i<db->nDb; i++){
+-        Schema *pSchema = db->aDb[i].pSchema;
+-        if( ALWAYS(pSchema!=0) ){
+-          HashElem *p;
 +      CODEC_TRACE(("cipher_ctx_key_derive: deriving hmac key from encryption key using PBKDF2 with %d 
iterations\n", 
 +        c_ctx->fast_kdf_iter)); 
-+
+ 
+-          nByte += sqlite3GlobalConfig.m.xRoundup(sizeof(HashElem)) * (
+-              pSchema->tblHash.count 
+-            + pSchema->trigHash.count
+-            + pSchema->idxHash.count
+-            + pSchema->fkeyHash.count
+-          );
+-          nByte += sqlite3MallocSize(pSchema->tblHash.ht);
+-          nByte += sqlite3MallocSize(pSchema->trigHash.ht);
+-          nByte += sqlite3MallocSize(pSchema->idxHash.ht);
+-          nByte += sqlite3MallocSize(pSchema->fkeyHash.ht);
 +      
 +      c_ctx->provider->kdf(c_ctx->provider_ctx, c_ctx->key, c_ctx->key_sz, 
 +                    ctx->hmac_kdf_salt, ctx->kdf_salt_sz, c_ctx->fast_kdf_iter,
 +                    c_ctx->key_sz, c_ctx->hmac_key); 
 +    }
-+
+ 
+-          for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){
+-            sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p));
+-          }
+-          for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){
+-            sqlite3DeleteTable(db, (Table *)sqliteHashData(p));
+-          }
+-        }
+-      }
+-      db->pnBytesFreed = 0;
+-      sqlite3BtreeLeaveAll(db);
 +    c_ctx->derive_key = 0;
 +    return SQLITE_OK;
 +  };
 +  return SQLITE_ERROR;
 +}
-+
+ 
+-      *pHighwater = 0;
+-      *pCurrent = nByte;
+-      break;
 +int sqlcipher_codec_key_derive(codec_ctx *ctx) {
 +  /* derive key on first use if necessary */
 +  if(ctx->read_ctx->derive_key) {
@@ -2840,18 +3971,34 @@
 +      if(sqlcipher_cipher_ctx_copy(ctx->write_ctx, ctx->read_ctx) != SQLITE_OK) return SQLITE_ERROR;
 +    } else {
 +      if(sqlcipher_cipher_ctx_key_derive(ctx, ctx->write_ctx) != SQLITE_OK) return SQLITE_ERROR;
-+    }
+     }
 +  }
-+
+ 
+-    /*
+-    ** *pCurrent gets an accurate estimate of the amount of memory used
+-    ** to store all prepared statements.
+-    ** *pHighwater is set to zero.
+-    */
+-    case SQLITE_DBSTATUS_STMT_USED: {
+-      struct Vdbe *pVdbe;         /* Used to iterate through VMs */
+-      int nByte = 0;              /* Used to accumulate return value */
 +  /* TODO: wipe and free passphrase after key derivation */
 +  if(ctx->read_ctx->store_pass  != 1) {
 +    sqlcipher_cipher_ctx_set_pass(ctx->read_ctx, NULL, 0);
 +    sqlcipher_cipher_ctx_set_pass(ctx->write_ctx, NULL, 0);
 +  }
-+
+ 
+-      db->pnBytesFreed = &nByte;
+-      for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
+-        sqlite3VdbeClearObject(db, pVdbe);
+-        sqlite3DbFree(db, pVdbe);
+-      }
+-      db->pnBytesFreed = 0;
 +  return SQLITE_OK; 
 +}
-+
+ 
+-      *pHighwater = 0;  /* IMP: R-64479-57858 */
+-      *pCurrent = nByte;
 +int sqlcipher_codec_key_copy(codec_ctx *ctx, int source) {
 +  if(source == CIPHER_READ_CTX) { 
 +      return sqlcipher_cipher_ctx_copy(ctx->write_ctx, ctx->read_ctx); 
@@ -2859,12 +4006,31 @@
 +      return sqlcipher_cipher_ctx_copy(ctx->read_ctx, ctx->write_ctx); 
 +  }
 +}
-+
+ 
+-      break;
+-    }
 +const char* sqlcipher_codec_get_cipher_provider(codec_ctx *ctx) {
 +  return ctx->read_ctx->provider->get_provider_name(ctx->read_ctx);
 +}
-+
-+
+ 
+-    /*
+-    ** Set *pCurrent to the total cache hits or misses encountered by all
+-    ** pagers the database handle is connected to. *pHighwater is always set 
+-    ** to zero.
+-    */
+-    case SQLITE_DBSTATUS_CACHE_HIT:
+-    case SQLITE_DBSTATUS_CACHE_MISS:
+-    case SQLITE_DBSTATUS_CACHE_WRITE:{
+-      int i;
+-      int nRet = 0;
+-      assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 );
+-      assert( SQLITE_DBSTATUS_CACHE_WRITE==SQLITE_DBSTATUS_CACHE_HIT+2 );
+ 
+-      for(i=0; i<db->nDb; i++){
+-        if( db->aDb[i].pBt ){
+-          Pager *pPager = sqlite3BtreePager(db->aDb[i].pBt);
+-          sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet);
+-        }
 +static int sqlcipher_check_connection(const char *filename, char *key, int key_sz, char *sql, int 
*user_version) {
 +  int rc;
 +  sqlite3 *db = NULL;
@@ -2988,8 +4154,13 @@
 +      rc = sqlite3_exec(db, command, NULL, NULL, NULL);
 +      if(rc != SQLITE_OK){
 +        break;
-+      }
-+    }
+       }
+-      *pHighwater = 0; /* IMP: R-42420-56072 */
+-                       /* IMP: R-54100-20147 */
+-                       /* IMP: R-29431-39229 */
+-      *pCurrent = nRet;
+-      break;
+     }
 +    sqlite3_free(attach_command);
 +    sqlite3_free(set_user_version);
 +    sqlcipher_free(key, key_sz);
@@ -2998,7 +4169,16 @@
 +      Btree *pDest;
 +      Btree *pSrc;
 +      int i = 0;
-+
+ 
+-    /* Set *pCurrent to non-zero if there are unresolved deferred foreign
+-    ** key constraints.  Set *pCurrent to zero if all foreign key constraints
+-    ** have been satisfied.  The *pHighwater is always set to zero.
+-    */
+-    case SQLITE_DBSTATUS_DEFERRED_FKS: {
+-      *pHighwater = 0;  /* IMP: R-11967-56545 */
+-      *pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0;
+-      break;
+-    }
 +      if( !db->autoCommit ){
 +        CODEC_TRACE(("cannot migrate from within a transaction"));
 +        goto handle_error;
@@ -3029,7 +4209,9 @@
 +      
 +      assert( 1==sqlite3BtreeIsInTrans(pDest) );
 +      assert( 1==sqlite3BtreeIsInTrans(pSrc) );
-+
+ 
+-    default: {
+-      rc = SQLITE_ERROR;
 +      sqlite3CodecGetKey(db, db->nDb - 1, (void**)&key, &password_sz);
 +      sqlite3CodecAttach(db, 0, key, password_sz);
 +      sqlite3pager_get_codec(pDest->pBt->pPager, (void**)&ctx);
@@ -3050,19 +4232,18 @@
 +      db->nTotalChange = saved_nTotalChange;
 +      db->xTrace = saved_xTrace;
 +      db->autoCommit = 1;
-+      if( pDb ){
-+        sqlite3BtreeClose(pDb->pBt);
-+        pDb->pBt = 0;
-+        pDb->pSchema = 0;
-+      }
++      sqlite3BtreeClose(pDb->pBt);
++      pDb->pBt = 0;
++      pDb->pSchema = 0;
 +      sqlite3ResetAllSchemasOfConnection(db);
 +      remove(migrated_db_filename);
 +      sqlite3_free(migrated_db_filename);
 +    } else {
 +      CODEC_TRACE(("*** migration failure** \n\n"));
-+    }
+     }
 +    
-+  }
+   }
+-  sqlite3_mutex_leave(db->mutex);
 +  goto exit;
 +
 + handle_error:
@@ -3070,9 +4251,11 @@
 +  rc = SQLITE_ERROR;
 +
 + exit:
-+  return rc;
-+}
-+
+   return rc;
+ }
+ 
+-/************** End of status.c **********************************************/
+-/************** Begin file date.c ********************************************/
 +int sqlcipher_codec_add_random(codec_ctx *ctx, const char *zRight, int random_sz){
 +  const char *suffix = &zRight[random_sz-1];
 +  int n = random_sz - 3; /* adjust for leading x' and tailing ' */
@@ -3119,19 +4302,54 @@
 +  if( f ) fprintf(f, "Elapsed time:%.3f ms - %s\n", elapsed, sql);
 +}
 +
++int sqlcipher_codec_fips_status(codec_ctx *ctx) {
++  return ctx->read_ctx->provider->fips_status(ctx->read_ctx);
++}
 +
 +#endif
 +/* END SQLCIPHER */
 +
 +/************** End of crypto_impl.c *****************************************/
 +/************** Begin file crypto_libtomcrypt.c ******************************/
-+/*
+ /*
+-** 2003 October 31
+-**
+-** The author disclaims copyright to this source code.  In place of
+-** a legal notice, here is a blessing:
 +** SQLCipher
 +** http://sqlcipher.net
-+**
+ **
+-**    May you do good and not evil.
+-**    May you find forgiveness for yourself and forgive others.
+-**    May you share freely, never taking more than you give.
+-**
+-*************************************************************************
+-** This file contains the C functions that implement date and time
+-** functions for SQLite.  
+-**
+-** There is only one exported symbol in this file - the function
+-** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
+-** All other code has file scope.
+-**
+-** SQLite processes all times and dates as julian day numbers.  The
+-** dates and times are stored as the number of days since noon
+-** in Greenwich on November 24, 4714 B.C. according to the Gregorian
+-** calendar system. 
 +** Copyright (c) 2008 - 2013, ZETETIC LLC
 +** All rights reserved.
-+**
+ **
+-** 1970-01-01 00:00:00 is JD 2440587.5
+-** 2000-01-01 00:00:00 is JD 2451544.5
+-**
+-** This implementation requires years to be expressed as a 4-digit number
+-** which means that only dates between 0000-01-01 and 9999-12-31 can
+-** be represented, even though julian day numbers allow a much wider
+-** range of dates.
+-**
+-** The Gregorian calendar system is used for all dates and times,
+-** even those that predate the Gregorian calendar.  Historians usually
+-** use the julian calendar for dates prior to 1582-10-15 and for some
+-** dates afterwards, depending on locale.  Beware of this difference.
 +** Redistribution and use in source and binary forms, with or without
 +** modification, are permitted provided that the following conditions are met:
 +**     * Redistributions of source code must retain the above copyright
@@ -3142,7 +4360,9 @@
 +**     * Neither the name of the ZETETIC LLC nor the
 +**       names of its contributors may be used to endorse or promote products
 +**       derived from this software without specific prior written permission.
-+**
+ **
+-** The conversion algorithms are implemented based on descriptions
+-** in the following text:
 +** THIS SOFTWARE IS PROVIDED BY ZETETIC LLC ''AS IS'' AND ANY
 +** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -3153,19 +4373,45 @@
 +** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+**
-+*/
+ **
+-**      Jean Meeus
+-**      Astronomical Algorithms, 2nd Edition, 1998
+-**      ISBM 0-943396-61-1
+-**      Willmann-Bell, Inc
+-**      Richmond, Virginia (USA)
+ */
+-/* #include <stdlib.h> */
+-/* #include <assert.h> */
+-#include <time.h>
+-
+-#ifndef SQLITE_OMIT_DATETIME_FUNCS
+-
 +/* BEGIN SQLCIPHER */
 +#ifdef SQLITE_HAS_CODEC
 +#ifdef SQLCIPHER_CRYPTO_LIBTOMCRYPT
 +#include <tomcrypt.h>
-+
+ 
+-/*
+-** A structure for holding a single date and time.
+-*/
+-typedef struct DateTime DateTime;
+-struct DateTime {
+-  sqlite3_int64 iJD; /* The julian day number times 86400000 */
+-  int Y, M, D;       /* Year, month, and day */
+-  int h, m;          /* Hour and minutes */
+-  int tz;            /* Timezone offset in minutes */
+-  double s;          /* Seconds */
+-  char validYMD;     /* True (1) if Y,M,D are valid */
+-  char validHMS;     /* True (1) if h,m,s are valid */
+-  char validJD;      /* True (1) if iJD is valid */
+-  char validTZ;      /* True (1) if tz is valid */
+-};
 +#define FORTUNA_MAX_SZ 32
 +static prng_state prng;
 +static unsigned int ltc_init = 0;
 +static unsigned int ltc_ref_count = 0;
 +static sqlite3_mutex* ltc_rand_mutex = NULL;
-+
+ 
 +static int sqlcipher_ltc_add_random(void *ctx, void *buffer, int length) {
 +  int rc = 0;
 +  int data_to_read = length;
@@ -3190,7 +4436,46 @@
 +#endif
 +  return rc;
 +}
-+
+ 
+-/*
+-** Convert zDate into one or more integers.  Additional arguments
+-** come in groups of 5 as follows:
+-**
+-**       N       number of digits in the integer
+-**       min     minimum allowed value of the integer
+-**       max     maximum allowed value of the integer
+-**       nextC   first character after the integer
+-**       pVal    where to write the integers value.
+-**
+-** Conversions continue until one with nextC==0 is encountered.
+-** The function returns the number of successful conversions.
+-*/
+-static int getDigits(const char *zDate, ...){
+-  va_list ap;
+-  int val;
+-  int N;
+-  int min;
+-  int max;
+-  int nextC;
+-  int *pVal;
+-  int cnt = 0;
+-  va_start(ap, zDate);
+-  do{
+-    N = va_arg(ap, int);
+-    min = va_arg(ap, int);
+-    max = va_arg(ap, int);
+-    nextC = va_arg(ap, int);
+-    pVal = va_arg(ap, int*);
+-    val = 0;
+-    while( N-- ){
+-      if( !sqlite3Isdigit(*zDate) ){
+-        goto end_getDigits;
+-      }
+-      val = val*10 + *zDate - '0';
+-      zDate++;
+-    }
+-    if( val<min || val>max || (nextC!=0 && nextC!=*zDate) ){
+-      goto end_getDigits;
 +static int sqlcipher_ltc_activate(void *ctx) {
 +  unsigned char random_buffer[FORTUNA_MAX_SZ];
 +#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
@@ -3206,7 +4491,14 @@
 +    if(register_hash(&sha1_desc) != CRYPT_OK) return SQLITE_ERROR;
 +    if(fortuna_start(&prng) != CRYPT_OK) {
 +      return SQLITE_ERROR;
-+    }
+     }
+-    *pVal = val;
+-    zDate++;
+-    cnt++;
+-  }while( nextC );
+-end_getDigits:
+-  va_end(ap);
+-  return cnt;
 +    ltc_init = 1;
 +  }
 +  ltc_ref_count++;
@@ -3221,8 +4513,44 @@
 +  }
 +  sqlcipher_memset(random_buffer, 0, FORTUNA_MAX_SZ);
 +  return SQLITE_OK;
-+}
-+
+ }
+ 
+-/*
+-** Parse a timezone extension on the end of a date-time.
+-** The extension is of the form:
+-**
+-**        (+/-)HH:MM
+-**
+-** Or the "zulu" notation:
+-**
+-**        Z
+-**
+-** If the parse is successful, write the number of minutes
+-** of change in p->tz and return 0.  If a parser error occurs,
+-** return non-zero.
+-**
+-** A missing specifier is not considered an error.
+-*/
+-static int parseTimezone(const char *zDate, DateTime *p){
+-  int sgn = 0;
+-  int nHr, nMn;
+-  int c;
+-  while( sqlite3Isspace(*zDate) ){ zDate++; }
+-  p->tz = 0;
+-  c = *zDate;
+-  if( c=='-' ){
+-    sgn = -1;
+-  }else if( c=='+' ){
+-    sgn = +1;
+-  }else if( c=='Z' || c=='z' ){
+-    zDate++;
+-    goto zulu_time;
+-  }else{
+-    return c!=0;
+-  }
+-  zDate++;
+-  if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){
+-    return 1;
 +static int sqlcipher_ltc_deactivate(void *ctx) {
 +#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
 +  sqlite3_mutex_enter(ltc_rand_mutex);
@@ -3240,11 +4568,28 @@
 +#ifndef SQLCIPHER_LTC_NO_MUTEX_RAND
 +  else {
 +    sqlite3_mutex_leave(ltc_rand_mutex);
-+  }
+   }
+-  zDate += 5;
+-  p->tz = sgn*(nMn + nHr*60);
+-zulu_time:
+-  while( sqlite3Isspace(*zDate) ){ zDate++; }
+-  return *zDate!=0;
 +#endif    
 +  return SQLITE_OK;
-+}
-+
+ }
+ 
+-/*
+-** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF.
+-** The HH, MM, and SS must each be exactly 2 digits.  The
+-** fractional seconds FFFF can be one or more digits.
+-**
+-** Return 1 if there is a parsing error and 0 on success.
+-*/
+-static int parseHhMmSs(const char *zDate, DateTime *p){
+-  int h, m, s;
+-  double ms = 0.0;
+-  if( getDigits(zDate, 2, 0, 24, ':', &h, 2, 0, 59, 0, &m)!=2 ){
+-    return 1;
 +static const char* sqlcipher_ltc_get_provider_name(void *ctx) {
 +  return "libtomcrypt";
 +}
@@ -3284,11 +4629,37 @@
 +  if((rc = pkcs_5_alg2(pass, pass_sz, salt, salt_sz,
 +                       workfactor, hash_idx, key, &outlen)) != CRYPT_OK) {
 +    return SQLITE_ERROR;
-+  }
+   }
+-  zDate += 5;
+-  if( *zDate==':' ){
+-    zDate++;
+-    if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){
+-      return 1;
+-    }
+-    zDate += 2;
+-    if( *zDate=='.' && sqlite3Isdigit(zDate[1]) ){
+-      double rScale = 1.0;
+-      zDate++;
+-      while( sqlite3Isdigit(*zDate) ){
+-        ms = ms*10.0 + *zDate - '0';
+-        rScale *= 10.0;
+-        zDate++;
+-      }
+-      ms /= rScale;
+-    }
+-  }else{
+-    s = 0;
 +  if((rc = pkcs_5_alg2(key, key_sz, salt, salt_sz,
 +                       1, hash_idx, random_buffer, &random_buffer_sz)) != CRYPT_OK) {
 +    return SQLITE_ERROR;
-+  }
+   }
+-  p->validJD = 0;
+-  p->validHMS = 1;
+-  p->h = h;
+-  p->m = m;
+-  p->s = s + ms;
+-  if( parseTimezone(zDate, p) ) return 1;
+-  p->validTZ = (p->tz!=0)?1:0;
 +  sqlcipher_ltc_add_random(ctx, random_buffer, random_buffer_sz);
 +  sqlcipher_free(random_buffer, random_buffer_sz);
 +  return SQLITE_OK;
@@ -3352,6 +4723,10 @@
 +  return SQLITE_OK;
 +}
 +
++static int sqlcipher_ltc_fips_status(void *ctx) {
+   return 0;
+ }
+ 
 +int sqlcipher_ltc_setup(sqlcipher_provider *p) {
 +  p->activate = sqlcipher_ltc_activate;
 +  p->deactivate = sqlcipher_ltc_deactivate;
@@ -3371,6 +4746,7 @@
 +  p->ctx_init = sqlcipher_ltc_ctx_init;
 +  p->ctx_free = sqlcipher_ltc_ctx_free;
 +  p->add_random = sqlcipher_ltc_add_random;
++  p->fips_status = sqlcipher_ltc_fips_status;
 +  return SQLITE_OK;
 +}
 +
@@ -3380,7 +4756,9 @@
 +
 +/************** End of crypto_libtomcrypt.c **********************************/
 +/************** Begin file crypto_openssl.c **********************************/
-+/*
+ /*
+-** Convert from YYYY-MM-DD HH:MM:SS to julian day.  We always assume
+-** that the YYYY-MM-DD is according to the Gregorian calendar.
 +** SQLCipher
 +** http://sqlcipher.net
 +**
@@ -3408,8 +4786,11 @@
 +** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+**
-+*/
+ **
+-** Reference:  Meeus page 61
+ */
+-static void computeJD(DateTime *p){
+-  int Y, M, D, A, B, X1, X2;
 +/* BEGIN SQLCIPHER */
 +#ifdef SQLITE_HAS_CODEC
 +#ifdef SQLCIPHER_CRYPTO_OPENSSL
@@ -3421,7 +4802,6 @@
 +  EVP_CIPHER *evp_cipher;
 +} openssl_ctx;
 +
-+
 +static unsigned int openssl_external_init = 0;
 +static unsigned int openssl_init_count = 0;
 +static sqlite3_mutex* openssl_rand_mutex = NULL;
@@ -3436,7 +4816,20 @@
 +#endif
 +  return SQLITE_OK;
 +}
-+
+ 
+-  if( p->validJD ) return;
+-  if( p->validYMD ){
+-    Y = p->Y;
+-    M = p->M;
+-    D = p->D;
+-  }else{
+-    Y = 2000;  /* If no YMD specified, assume 2000-Jan-01 */
+-    M = 1;
+-    D = 1;
+-  }
+-  if( M<=2 ){
+-    Y--;
+-    M += 12;
 +/* activate and initialize sqlcipher. Most importantly, this will automatically
 +   intialize OpenSSL's EVP system if it hasn't already be externally. Note that 
 +   this function may be called multiple times as new codecs are intiialized. 
@@ -3454,18 +4847,71 @@
 +       a call to get_cipherbyname works, then the openssl library
 +       has been initialized externally already. */
 +    openssl_external_init = 1;
-+  }
-+
+   }
+-  A = Y/100;
+-  B = 2 - A + (A/4);
+-  X1 = 36525*(Y+4716)/100;
+-  X2 = 306001*(M+1)/10000;
+-  p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000);
+-  p->validJD = 1;
+-  if( p->validHMS ){
+-    p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000);
+-    if( p->validTZ ){
+-      p->iJD -= p->tz*60000;
+-      p->validYMD = 0;
+-      p->validHMS = 0;
+-      p->validTZ = 0;
++
++#ifdef SQLCIPHER_FIPS
++  if(!FIPS_mode()){
++    if(!FIPS_mode_set(1)){
++      ERR_load_crypto_strings();
++      ERR_print_errors_fp(stderr);
+     }
+   }
+-}
++#endif
+ 
+-/*
+-** Parse dates of the form
+-**
+-**     YYYY-MM-DD HH:MM:SS.FFF
+-**     YYYY-MM-DD HH:MM:SS
+-**     YYYY-MM-DD HH:MM
+-**     YYYY-MM-DD
+-**
+-** Write the result into the DateTime structure and return 0
+-** on success and 1 if the input string is not a well-formed
+-** date.
+-*/
+-static int parseYyyyMmDd(const char *zDate, DateTime *p){
+-  int Y, M, D, neg;
 +  if(openssl_init_count == 0 && openssl_external_init == 0)  {
 +    /* if the library was not externally initialized, then should be now */
 +    OpenSSL_add_all_algorithms();
 +  } 
-+
+ 
+-  if( zDate[0]=='-' ){
+-    zDate++;
+-    neg = 1;
+-  }else{
+-    neg = 0;
+-  }
+-  if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){
+-    return 1;
 +#ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND
 +  if(openssl_rand_mutex == NULL) {
 +    /* allocate a mutex to guard against concurrent calls to RAND_bytes() */
 +    openssl_rand_mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
-+  }
+   }
+-  zDate += 10;
+-  while( sqlite3Isspace(*zDate) || 'T'==*(u8*)zDate ){ zDate++; }
+-  if( parseHhMmSs(zDate, p)==0 ){
+-    /* We got the time */
+-  }else if( *zDate==0 ){
+-    p->validHMS = 0;
+-  }else{
+-    return 1;
 +#endif
 +
 +  openssl_init_count++; 
@@ -3493,7 +4939,14 @@
 +    sqlite3_mutex_free(openssl_rand_mutex);
 +    openssl_rand_mutex = NULL;
 +#endif
-+  }
+   }
+-  p->validJD = 0;
+-  p->validYMD = 1;
+-  p->Y = neg ? -Y : Y;
+-  p->M = M;
+-  p->D = D;
+-  if( p->validTZ ){
+-    computeJD(p);
 +  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
 +  return SQLITE_OK;
 +}
@@ -3557,8 +5010,11 @@
 +
 +static int sqlcipher_openssl_set_cipher(void *ctx, const char *cipher_name) {
 +  openssl_ctx *o_ctx = (openssl_ctx *)ctx;
-+  o_ctx->evp_cipher = (EVP_CIPHER *) EVP_get_cipherbyname(cipher_name);
-+  return SQLITE_OK;
++  EVP_CIPHER* cipher = (EVP_CIPHER *) EVP_get_cipherbyname(cipher_name);
++  if(cipher != NULL) {
++    o_ctx->evp_cipher = cipher;
+   }
++  return cipher != NULL ? SQLITE_OK : SQLITE_ERROR;
 +}
 +
 +static const char* sqlcipher_openssl_get_cipher(void *ctx) {
@@ -3603,6 +5059,27 @@
 +  return SQLITE_OK;
 +}
 +
++static int sqlcipher_openssl_fips_status(void *ctx) {
++#ifdef SQLCIPHER_FIPS  
++  return FIPS_mode();
++#else
+   return 0;
++#endif
+ }
+ 
+-/*
+-** Set the time to the current time reported by the VFS.
+-**
+-** Return the number of errors.
+-*/
+-static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
+-  p->iJD = sqlite3StmtCurrentTime(context);
+-  if( p->iJD>0 ){
+-    p->validJD = 1;
+-    return 0;
+-  }else{
+-    return 1;
+-  }
 +int sqlcipher_openssl_setup(sqlcipher_provider *p) {
 +  p->activate = sqlcipher_openssl_activate;  
 +  p->deactivate = sqlcipher_openssl_deactivate;
@@ -3622,19 +5099,27 @@
 +  p->ctx_init = sqlcipher_openssl_ctx_init;
 +  p->ctx_free = sqlcipher_openssl_ctx_free;
 +  p->add_random = sqlcipher_openssl_add_random;
++  p->fips_status = sqlcipher_openssl_fips_status;
 +  return SQLITE_OK;
-+}
-+
+ }
+ 
 +#endif
 +#endif
 +/* END SQLCIPHER */
 +
 +/************** End of crypto_openssl.c **************************************/
 +/************** Begin file crypto_cc.c ***************************************/
-+/*
+ /*
+-** Attempt to parse the given string into a julian day number.  Return
+-** the number of errors.
+-**
+-** The following are acceptable forms for the input string:
 +** SQLCipher
 +** http://sqlcipher.net
-+**
+ **
+-**      YYYY-MM-DD HH:MM:SS.FFF  +/-HH:MM
+-**      DDDD.DD 
+-**      now
 +** Copyright (c) 2008 - 2013, ZETETIC LLC
 +** All rights reserved.
 +**
@@ -3659,8 +5144,31 @@
 +** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-+**
-+*/
+ **
+-** In the first form, the +/-HH:MM is always optional.  The fractional
+-** seconds extension (the ".FFF") is optional.  The seconds portion
+-** (":SS.FFF") is option.  The year and date can be omitted as long
+-** as there is a time string.  The time string can be omitted as long
+-** as there is a year and date.
+ */
+-static int parseDateOrTime(
+-  sqlite3_context *context, 
+-  const char *zDate, 
+-  DateTime *p
+-){
+-  double r;
+-  if( parseYyyyMmDd(zDate,p)==0 ){
+-    return 0;
+-  }else if( parseHhMmSs(zDate, p)==0 ){
+-    return 0;
+-  }else if( sqlite3StrICmp(zDate,"now")==0){
+-    return setDateTimeToCurrent(context, p);
+-  }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
+-    p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
+-    p->validJD = 1;
+-    return 0;
+-  }
+-  return 1;
 +/* BEGIN SQLCIPHER */
 +#ifdef SQLITE_HAS_CODEC
 +#ifdef SQLCIPHER_CRYPTO_CC
@@ -3669,17 +5177,63 @@
 +
 +static int sqlcipher_cc_add_random(void *ctx, void *buffer, int length) {
 +  return SQLITE_OK;
-+}
-+
+ }
+ 
+-/*
+-** Compute the Year, Month, and Day from the julian day number.
+-*/
+-static void computeYMD(DateTime *p){
+-  int Z, A, B, C, D, E, X1;
+-  if( p->validYMD ) return;
+-  if( !p->validJD ){
+-    p->Y = 2000;
+-    p->M = 1;
+-    p->D = 1;
+-  }else{
+-    Z = (int)((p->iJD + 43200000)/86400000);
+-    A = (int)((Z - 1867216.25)/36524.25);
+-    A = Z + 1 + A - (A/4);
+-    B = A + 1524;
+-    C = (int)((B - 122.1)/365.25);
+-    D = (36525*C)/100;
+-    E = (int)((B-D)/30.6001);
+-    X1 = (int)(30.6001*E);
+-    p->D = B - D - X1;
+-    p->M = E<14 ? E-1 : E-13;
+-    p->Y = p->M>2 ? C - 4716 : C - 4715;
+-  }
+-  p->validYMD = 1;
 +/* generate a defined number of random bytes */
 +static int sqlcipher_cc_random (void *ctx, void *buffer, int length) {
 +  return (SecRandomCopyBytes(kSecRandomDefault, length, (uint8_t *)buffer) == 0) ? SQLITE_OK : SQLITE_ERROR;
-+}
-+
+ }
+ 
+-/*
+-** Compute the Hour, Minute, and Seconds from the julian day number.
+-*/
+-static void computeHMS(DateTime *p){
+-  int s;
+-  if( p->validHMS ) return;
+-  computeJD(p);
+-  s = (int)((p->iJD + 43200000) % 86400000);
+-  p->s = s/1000.0;
+-  s = (int)p->s;
+-  p->s -= s;
+-  p->h = s/3600;
+-  s -= p->h*3600;
+-  p->m = s/60;
+-  p->s += s - p->m*60;
+-  p->validHMS = 1;
 +static const char* sqlcipher_cc_get_provider_name(void *ctx) {
 +  return "commoncrypto";
-+}
-+
+ }
+ 
+-/*
+-** Compute both YMD and HMS
+-*/
+-static void computeYMD_HMS(DateTime *p){
+-  computeYMD(p);
+-  computeHMS(p);
 +static int sqlcipher_cc_hmac(void *ctx, unsigned char *hmac_key, int key_sz, unsigned char *in, int in_sz, 
unsigned char *in2, int in2_sz, unsigned char *out) {
 +  CCHmacContext hmac_context;
 +  CCHmacInit(&hmac_context, kCCHmacAlgSHA1, hmac_key, key_sz);
@@ -3687,8 +5241,15 @@
 +  CCHmacUpdate(&hmac_context, in2, in2_sz);
 +  CCHmacFinal(&hmac_context, out);
 +  return SQLITE_OK; 
-+}
-+
+ }
+ 
+-/*
+-** Clear the YMD and HMS and the TZ
+-*/
+-static void clearYMD_HMS_TZ(DateTime *p){
+-  p->validYMD = 0;
+-  p->validHMS = 0;
+-  p->validTZ = 0;
 +static int sqlcipher_cc_kdf(void *ctx, const unsigned char *pass, int pass_sz, unsigned char* salt, int 
salt_sz, int workfactor, int key_sz, unsigned char *key) {
 +  CCKeyDerivationPBKDF(kCCPBKDF2, (const char *)pass, pass_sz, salt, salt_sz, kCCPRFHmacAlgSHA1, 
workfactor, key, key_sz);
 +  return SQLITE_OK; 
@@ -3751,6 +5312,10 @@
 +  return SQLITE_OK;
 +}
 +
++static int sqlcipher_cc_fips_status(void *ctx) {
++  return 0;
++}
++
 +int sqlcipher_cc_setup(sqlcipher_provider *p) {
 +  p->random = sqlcipher_cc_random;
 +  p->get_provider_name = sqlcipher_cc_get_provider_name;
@@ -3768,37 +5333,81 @@
 +  p->ctx_init = sqlcipher_cc_ctx_init;
 +  p->ctx_free = sqlcipher_cc_ctx_free;
 +  p->add_random = sqlcipher_cc_add_random;
++  p->fips_status = sqlcipher_cc_fips_status;
 +  return SQLITE_OK;
-+}
-+
+ }
+ 
 +#endif
 +#endif
 +/* END SQLCIPHER */
 +
 +/************** End of crypto_cc.c *******************************************/
 +/************** Begin file global.c ******************************************/
-+/*
+ /*
+-** On recent Windows platforms, the localtime_s() function is available
+-** as part of the "Secure CRT". It is essentially equivalent to 
+-** localtime_r() available under most POSIX platforms, except that the 
+-** order of the parameters is reversed.
 +** 2008 June 13
-+**
+ **
+-** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx.
 +** The author disclaims copyright to this source code.  In place of
 +** a legal notice, here is a blessing:
-+**
+ **
+-** If the user has not indicated to use localtime_r() or localtime_s()
+-** already, check for an MSVC build environment that provides 
+-** localtime_s().
 +**    May you do good and not evil.
 +**    May you find forgiveness for yourself and forgive others.
 +**    May you share freely, never taking more than you give.
 +**
 +*************************************************************************
 +**
-+** This file contains definitions of global variables and contants.
-+*/
-+
++** This file contains definitions of global variables and constants.
+ */
+-#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S \
+-    && defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE)
+-#undef  HAVE_LOCALTIME_S
+-#define HAVE_LOCALTIME_S 1
+-#endif
+ 
+-#ifndef SQLITE_OMIT_LOCALTIME
+-/*
+-** The following routine implements the rough equivalent of localtime_r()
+-** using whatever operating-system specific localtime facility that
+-** is available.  This routine returns 0 on success and
+-** non-zero on any kind of error.
+-**
+-** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this
+-** routine will always fail.
 +/* An array to map all upper-case characters into their corresponding
 +** lower-case character. 
-+**
+ **
+-** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C
+-** library function localtime_r() is used to assist in the calculation of
+-** local time.
 +** SQLite only considers US-ASCII (or EBCDIC) characters.  We do not
 +** handle case conversions for the UTF character set since the tables
 +** involved are nearly as big or bigger than SQLite itself.
-+*/
+ */
+-static int osLocaltime(time_t *t, struct tm *pTm){
+-  int rc;
+-#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S
+-  struct tm *pX;
+-#if SQLITE_THREADSAFE>0
+-  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
+-#endif
+-  sqlite3_mutex_enter(mutex);
+-  pX = localtime(t);
+-#ifndef SQLITE_OMIT_BUILTIN_TEST
+-  if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0;
+-#endif
+-  if( pX ) *pTm = *pX;
+-  sqlite3_mutex_leave(mutex);
+-  rc = pX==0;
+-#else
+-#ifndef SQLITE_OMIT_BUILTIN_TEST
+-  if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
 +SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[] = {
 +#ifdef SQLITE_ASCII
 +      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
@@ -3816,7 +5425,17 @@
 +    216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,
 +    234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
 +    252,253,254,255
-+#endif
+ #endif
+-#if HAVE_LOCALTIME_R
+-  rc = localtime_r(t, pTm)==0;
+-#else
+-  rc = localtime_s(pTm, t);
+-#endif /* HAVE_LOCALTIME_R */
+-#endif /* HAVE_LOCALTIME_R || HAVE_LOCALTIME_S */
+-  return rc;
+-}
+-#endif /* SQLITE_OMIT_LOCALTIME */
+-
 +#ifdef SQLITE_EBCDIC
 +      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, /* 0x */
 +     16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 1x */
@@ -3824,23 +5443,29 @@
 +     48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 3x */
 +     64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 4x */
 +     80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 5x */
-+     96, 97, 66, 67, 68, 69, 70, 71, 72, 73,106,107,108,109,110,111, /* 6x */
-+    112, 81, 82, 83, 84, 85, 86, 87, 88, 89,122,123,124,125,126,127, /* 7x */
++     96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111, /* 6x */
++    112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127, /* 7x */
 +    128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, /* 8x */
-+    144,145,146,147,148,149,150,151,152,153,154,155,156,157,156,159, /* 9x */
++    144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, /* 9x */
 +    160,161,162,163,164,165,166,167,168,169,170,171,140,141,142,175, /* Ax */
 +    176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, /* Bx */
 +    192,129,130,131,132,133,134,135,136,137,202,203,204,205,206,207, /* Cx */
 +    208,145,146,147,148,149,150,151,152,153,218,219,220,221,222,223, /* Dx */
-+    224,225,162,163,164,165,166,167,168,169,232,203,204,205,206,207, /* Ex */
-+    239,240,241,242,243,244,245,246,247,248,249,219,220,221,222,255, /* Fx */
++    224,225,162,163,164,165,166,167,168,169,234,235,236,237,238,239, /* Ex */
++    240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255, /* Fx */
 +#endif
 +};
-+
-+/*
+ 
+-#ifndef SQLITE_OMIT_LOCALTIME
+ /*
+-** Compute the difference (in milliseconds) between localtime and UTC
+-** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs,
+-** return this value and set *pRc to SQLITE_OK. 
 +** The following 256 byte lookup table is used to support SQLites built-in
 +** equivalents to the following standard library functions:
-+**
+ **
+-** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value
+-** is undefined in this case.
 +**   isspace()                        0x01
 +**   isalpha()                        0x02
 +**   isdigit()                        0x04
@@ -3866,7 +5491,15 @@
 +**
 +** SQLite's versions are identical to the standard versions assuming a
 +** locale of "C". They are implemented as macros in sqliteInt.h.
-+*/
+ */
+-static sqlite3_int64 localtimeOffset(
+-  DateTime *p,                    /* Date at which to calculate offset */
+-  sqlite3_context *pCtx,          /* Write error here if one occurs */
+-  int *pRc                        /* OUT: Error code. SQLITE_OK or ERROR */
+-){
+-  DateTime x, y;
+-  time_t t;
+-  struct tm sLocal;
 +#ifdef SQLITE_ASCII
 +SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = {
 +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 00..07    ........ */
@@ -3877,7 +5510,9 @@
 +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 28..2f    ()*+,-./ */
 +  0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,  /* 30..37    01234567 */
 +  0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 38..3f    89:;<=>? */
-+
+ 
+-  /* Initialize the contents of sLocal to avoid a compiler warning. */
+-  memset(&sLocal, 0, sizeof(sLocal));
 +  0x00, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x02,  /* 40..47    @ABCDEFG */
 +  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,  /* 48..4f    HIJKLMNO */
 +  0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,  /* 50..57    PQRSTUVW */
@@ -3886,7 +5521,49 @@
 +  0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,  /* 68..6f    hijklmno */
 +  0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,  /* 70..77    pqrstuvw */
 +  0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00,  /* 78..7f    xyz{|}~. */
-+
+ 
+-  x = *p;
+-  computeYMD_HMS(&x);
+-  if( x.Y<1971 || x.Y>=2038 ){
+-    /* EVIDENCE-OF: R-55269-29598 The localtime_r() C function normally only
+-    ** works for years between 1970 and 2037. For dates outside this range,
+-    ** SQLite attempts to map the year into an equivalent year within this
+-    ** range, do the calculation, then map the year back.
+-    */
+-    x.Y = 2000;
+-    x.M = 1;
+-    x.D = 1;
+-    x.h = 0;
+-    x.m = 0;
+-    x.s = 0.0;
+-  } else {
+-    int s = (int)(x.s + 0.5);
+-    x.s = s;
+-  }
+-  x.tz = 0;
+-  x.validJD = 0;
+-  computeJD(&x);
+-  t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
+-  if( osLocaltime(&t, &sLocal) ){
+-    sqlite3_result_error(pCtx, "local time unavailable", -1);
+-    *pRc = SQLITE_ERROR;
+-    return 0;
+-  }
+-  y.Y = sLocal.tm_year + 1900;
+-  y.M = sLocal.tm_mon + 1;
+-  y.D = sLocal.tm_mday;
+-  y.h = sLocal.tm_hour;
+-  y.m = sLocal.tm_min;
+-  y.s = sLocal.tm_sec;
+-  y.validYMD = 1;
+-  y.validHMS = 1;
+-  y.validJD = 0;
+-  y.validTZ = 0;
+-  computeJD(&y);
+-  *pRc = SQLITE_OK;
+-  return y.iJD - x.iJD;
+-}
+-#endif /* SQLITE_OMIT_LOCALTIME */
 +  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* 80..87    ........ */
 +  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* 88..8f    ........ */
 +  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* 90..97    ........ */
@@ -3895,7 +5572,10 @@
 +  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* a8..af    ........ */
 +  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* b0..b7    ........ */
 +  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* b8..bf    ........ */
-+
+ 
+-/*
+-** Process a modifier to a date-time stamp.  The modifiers are
+-** as follows:
 +  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* c0..c7    ........ */
 +  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* c8..cf    ........ */
 +  0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,  /* d0..d7    ........ */
@@ -3907,14 +5587,284 @@
 +};
 +#endif
 +
++/* EVIDENCE-OF: R-02982-34736 In order to maintain full backwards
++** compatibility for legacy applications, the URI filename capability is
++** disabled by default.
+ **
+-**     NNN days
+-**     NNN hours
+-**     NNN minutes
+-**     NNN.NNNN seconds
+-**     NNN months
+-**     NNN years
+-**     start of month
+-**     start of year
+-**     start of week
+-**     start of day
+-**     weekday N
+-**     unixepoch
+-**     localtime
+-**     utc
++** EVIDENCE-OF: R-38799-08373 URI filenames can be enabled or disabled
++** using the SQLITE_USE_URI=1 or SQLITE_USE_URI=0 compile-time options.
+ **
+-** Return 0 on success and 1 if there is any kind of error. If the error
+-** is in a system call (i.e. localtime()), then an error message is written
+-** to context pCtx. If the error is an unrecognized modifier, no error is
+-** written to pCtx.
++** EVIDENCE-OF: R-43642-56306 By default, URI handling is globally
++** disabled. The default value may be changed by compiling with the
++** SQLITE_USE_URI symbol defined.
+ */
+-static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
+-  int rc = 1;
+-  int n;
+-  double r;
+-  char *z, zBuf[30];
+-  z = zBuf;
+-  for(n=0; n<ArraySize(zBuf)-1 && zMod[n]; n++){
+-    z[n] = (char)sqlite3UpperToLower[(u8)zMod[n]];
+-  }
+-  z[n] = 0;
+-  switch( z[0] ){
+-#ifndef SQLITE_OMIT_LOCALTIME
+-    case 'l': {
+-      /*    localtime
+-      **
+-      ** Assuming the current time value is UTC (a.k.a. GMT), shift it to
+-      ** show local time.
+-      */
+-      if( strcmp(z, "localtime")==0 ){
+-        computeJD(p);
+-        p->iJD += localtimeOffset(p, pCtx, &rc);
+-        clearYMD_HMS_TZ(p);
+-      }
+-      break;
+-    }
 +#ifndef SQLITE_USE_URI
 +# define  SQLITE_USE_URI 0
-+#endif
+ #endif
+-    case 'u': {
+-      /*
+-      **    unixepoch
+-      **
+-      ** Treat the current value of p->iJD as the number of
+-      ** seconds since 1970.  Convert to a real julian day number.
+-      */
+-      if( strcmp(z, "unixepoch")==0 && p->validJD ){
+-        p->iJD = (p->iJD + 43200)/86400 + 21086676*(i64)10000000;
+-        clearYMD_HMS_TZ(p);
+-        rc = 0;
+-      }
+-#ifndef SQLITE_OMIT_LOCALTIME
+-      else if( strcmp(z, "utc")==0 ){
+-        sqlite3_int64 c1;
+-        computeJD(p);
+-        c1 = localtimeOffset(p, pCtx, &rc);
+-        if( rc==SQLITE_OK ){
+-          p->iJD -= c1;
+-          clearYMD_HMS_TZ(p);
+-          p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
+-        }
+-      }
 +
++/* EVIDENCE-OF: R-38720-18127 The default setting is determined by the
++** SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option, or is "on" if
++** that compile-time option is omitted.
++*/
 +#ifndef SQLITE_ALLOW_COVERING_INDEX_SCAN
 +# define SQLITE_ALLOW_COVERING_INDEX_SCAN 1
+ #endif
+-      break;
+-    }
+-    case 'w': {
+-      /*
+-      **    weekday N
+-      **
+-      ** Move the date to the same time on the next occurrence of
+-      ** weekday N where 0==Sunday, 1==Monday, and so forth.  If the
+-      ** date is already on the appropriate weekday, this is a no-op.
+-      */
+-      if( strncmp(z, "weekday ", 8)==0
+-               && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)
+-               && (n=(int)r)==r && n>=0 && r<7 ){
+-        sqlite3_int64 Z;
+-        computeYMD_HMS(p);
+-        p->validTZ = 0;
+-        p->validJD = 0;
+-        computeJD(p);
+-        Z = ((p->iJD + 129600000)/86400000) % 7;
+-        if( Z>n ) Z -= 7;
+-        p->iJD += (n - Z)*86400000;
+-        clearYMD_HMS_TZ(p);
+-        rc = 0;
+-      }
+-      break;
+-    }
+-    case 's': {
+-      /*
+-      **    start of TTTTT
+-      **
+-      ** Move the date backwards to the beginning of the current day,
+-      ** or month or year.
+-      */
+-      if( strncmp(z, "start of ", 9)!=0 ) break;
+-      z += 9;
+-      computeYMD(p);
+-      p->validHMS = 1;
+-      p->h = p->m = 0;
+-      p->s = 0.0;
+-      p->validTZ = 0;
+-      p->validJD = 0;
+-      if( strcmp(z,"month")==0 ){
+-        p->D = 1;
+-        rc = 0;
+-      }else if( strcmp(z,"year")==0 ){
+-        computeYMD(p);
+-        p->M = 1;
+-        p->D = 1;
+-        rc = 0;
+-      }else if( strcmp(z,"day")==0 ){
+-        rc = 0;
+-      }
+-      break;
+-    }
+-    case '+':
+-    case '-':
+-    case '0':
+-    case '1':
+-    case '2':
+-    case '3':
+-    case '4':
+-    case '5':
+-    case '6':
+-    case '7':
+-    case '8':
+-    case '9': {
+-      double rRounder;
+-      for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
+-      if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){
+-        rc = 1;
+-        break;
+-      }
+-      if( z[n]==':' ){
+-        /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the
+-        ** specified number of hours, minutes, seconds, and fractional seconds
+-        ** to the time.  The ".FFF" may be omitted.  The ":SS.FFF" may be
+-        ** omitted.
+-        */
+-        const char *z2 = z;
+-        DateTime tx;
+-        sqlite3_int64 day;
+-        if( !sqlite3Isdigit(*z2) ) z2++;
+-        memset(&tx, 0, sizeof(tx));
+-        if( parseHhMmSs(z2, &tx) ) break;
+-        computeJD(&tx);
+-        tx.iJD -= 43200000;
+-        day = tx.iJD/86400000;
+-        tx.iJD -= day*86400000;
+-        if( z[0]=='-' ) tx.iJD = -tx.iJD;
+-        computeJD(p);
+-        clearYMD_HMS_TZ(p);
+-        p->iJD += tx.iJD;
+-        rc = 0;
+-        break;
+-      }
+-      z += n;
+-      while( sqlite3Isspace(*z) ) z++;
+-      n = sqlite3Strlen30(z);
+-      if( n>10 || n<3 ) break;
+-      if( z[n-1]=='s' ){ z[n-1] = 0; n--; }
+-      computeJD(p);
+-      rc = 0;
+-      rRounder = r<0 ? -0.5 : +0.5;
+-      if( n==3 && strcmp(z,"day")==0 ){
+-        p->iJD += (sqlite3_int64)(r*86400000.0 + rRounder);
+-      }else if( n==4 && strcmp(z,"hour")==0 ){
+-        p->iJD += (sqlite3_int64)(r*(86400000.0/24.0) + rRounder);
+-      }else if( n==6 && strcmp(z,"minute")==0 ){
+-        p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0)) + rRounder);
+-      }else if( n==6 && strcmp(z,"second")==0 ){
+-        p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0*60.0)) + rRounder);
+-      }else if( n==5 && strcmp(z,"month")==0 ){
+-        int x, y;
+-        computeYMD_HMS(p);
+-        p->M += (int)r;
+-        x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
+-        p->Y += x;
+-        p->M -= x*12;
+-        p->validJD = 0;
+-        computeJD(p);
+-        y = (int)r;
+-        if( y!=r ){
+-          p->iJD += (sqlite3_int64)((r - y)*30.0*86400000.0 + rRounder);
+-        }
+-      }else if( n==4 && strcmp(z,"year")==0 ){
+-        int y = (int)r;
+-        computeYMD_HMS(p);
+-        p->Y += y;
+-        p->validJD = 0;
+-        computeJD(p);
+-        if( y!=r ){
+-          p->iJD += (sqlite3_int64)((r - y)*365.0*86400000.0 + rRounder);
+-        }
+-      }else{
+-        rc = 1;
+-      }
+-      clearYMD_HMS_TZ(p);
+-      break;
+-    }
+-    default: {
+-      break;
+-    }
+-  }
+-  return rc;
+-}
+ 
+-/*
+-** Process time function arguments.  argv[0] is a date-time stamp.
+-** argv[1] and following are modifiers.  Parse them all and write
+-** the resulting time into the DateTime structure p.  Return 0
+-** on success and 1 if there are any errors.
+-**
+-** If there are zero parameters (if even argv[0] is undefined)
+-** then assume a default value of "now" for argv[0].
++/* The minimum PMA size is set to this value multiplied by the database
++** page size in bytes.
+ */
+-static int isDate(
+-  sqlite3_context *context, 
+-  int argc, 
+-  sqlite3_value **argv, 
+-  DateTime *p
+-){
+-  int i;
+-  const unsigned char *z;
+-  int eType;
+-  memset(p, 0, sizeof(*p));
+-  if( argc==0 ){
+-    return setDateTimeToCurrent(context, p);
+-  }
+-  if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT
+-                   || eType==SQLITE_INTEGER ){
+-    p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*86400000.0 + 0.5);
+-    p->validJD = 1;
+-  }else{
+-    z = sqlite3_value_text(argv[0]);
+-    if( !z || parseDateOrTime(context, (char*)z, p) ){
+-      return 1;
+-    }
+-  }
+-  for(i=1; i<argc; i++){
+-    z = sqlite3_value_text(argv[i]);
+-    if( z==0 || parseModifier(context, (char*)z, p) ) return 1;
+-  }
+-  return 0;
+-}
++#ifndef SQLITE_SORTER_PMASZ
++# define SQLITE_SORTER_PMASZ 250
 +#endif
-+
+ 
 +/*
 +** The following singleton contains the global configuration for
 +** the SQLite library.
@@ -3945,6 +5895,7 @@
 +   0,                         /* nPage */
 +   0,                         /* mxParserStack */
 +   0,                         /* sharedCacheEnabled */
++   SQLITE_SORTER_PMASZ,       /* szPma */
 +   /* All the rest should always be initialized to zero */
 +   0,                         /* isInit */
 +   0,                         /* inProgress */
@@ -3968,57 +5919,969 @@
 +#endif
 +   0                          /* bLocaltimeFault */
 +};
-+
-+/*
+ 
+ /*
+-** The following routines implement the various date and time functions
+-** of SQLite.
 +** Hash table for global functions - functions common to all
 +** database connections.  After initialization, this table is
 +** read-only.
-+*/
+ */
 +SQLITE_PRIVATE SQLITE_WSD FuncDefHash sqlite3GlobalFunctions;
-+
-+/*
+ 
+ /*
+-**    julianday( TIMESTRING, MOD, MOD, ...)
+-**
+-** Return the julian day number of the date specified in the arguments
 +** Constant tokens for values 0 and 1.
-+*/
+ */
+-static void juliandayFunc(
+-  sqlite3_context *context,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  DateTime x;
+-  if( isDate(context, argc, argv, &x)==0 ){
+-    computeJD(&x);
+-    sqlite3_result_double(context, x.iJD/86400000.0);
+-  }
+-}
+-
+-/*
+-**    datetime( TIMESTRING, MOD, MOD, ...)
+-**
+-** Return YYYY-MM-DD HH:MM:SS
+-*/
+-static void datetimeFunc(
+-  sqlite3_context *context,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  DateTime x;
+-  if( isDate(context, argc, argv, &x)==0 ){
+-    char zBuf[100];
+-    computeYMD_HMS(&x);
+-    sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d %02d:%02d:%02d",
+-                     x.Y, x.M, x.D, x.h, x.m, (int)(x.s));
+-    sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
+-  }
+-}
+-
+-/*
+-**    time( TIMESTRING, MOD, MOD, ...)
+-**
+-** Return HH:MM:SS
+-*/
+-static void timeFunc(
+-  sqlite3_context *context,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  DateTime x;
+-  if( isDate(context, argc, argv, &x)==0 ){
+-    char zBuf[100];
+-    computeHMS(&x);
+-    sqlite3_snprintf(sizeof(zBuf), zBuf, "%02d:%02d:%02d", x.h, x.m, (int)x.s);
+-    sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
+-  }
+-}
+-
+-/*
+-**    date( TIMESTRING, MOD, MOD, ...)
+-**
+-** Return YYYY-MM-DD
+-*/
+-static void dateFunc(
+-  sqlite3_context *context,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  DateTime x;
+-  if( isDate(context, argc, argv, &x)==0 ){
+-    char zBuf[100];
+-    computeYMD(&x);
+-    sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D);
+-    sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
+-  }
+-}
+-
+-/*
+-**    strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
+-**
+-** Return a string described by FORMAT.  Conversions as follows:
+-**
+-**   %d  day of month
+-**   %f  ** fractional seconds  SS.SSS
+-**   %H  hour 00-24
+-**   %j  day of year 000-366
+-**   %J  ** julian day number
+-**   %m  month 01-12
+-**   %M  minute 00-59
+-**   %s  seconds since 1970-01-01
+-**   %S  seconds 00-59
+-**   %w  day of week 0-6  sunday==0
+-**   %W  week of year 00-53
+-**   %Y  year 0000-9999
+-**   %%  %
+-*/
+-static void strftimeFunc(
+-  sqlite3_context *context,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  DateTime x;
+-  u64 n;
+-  size_t i,j;
+-  char *z;
+-  sqlite3 *db;
+-  const char *zFmt;
+-  char zBuf[100];
+-  if( argc==0 ) return;
+-  zFmt = (const char*)sqlite3_value_text(argv[0]);
+-  if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return;
+-  db = sqlite3_context_db_handle(context);
+-  for(i=0, n=1; zFmt[i]; i++, n++){
+-    if( zFmt[i]=='%' ){
+-      switch( zFmt[i+1] ){
+-        case 'd':
+-        case 'H':
+-        case 'm':
+-        case 'M':
+-        case 'S':
+-        case 'W':
+-          n++;
+-          /* fall thru */
+-        case 'w':
+-        case '%':
+-          break;
+-        case 'f':
+-          n += 8;
+-          break;
+-        case 'j':
+-          n += 3;
+-          break;
+-        case 'Y':
+-          n += 8;
+-          break;
+-        case 's':
+-        case 'J':
+-          n += 50;
+-          break;
+-        default:
+-          return;  /* ERROR.  return a NULL */
+-      }
+-      i++;
+-    }
+-  }
+-  testcase( n==sizeof(zBuf)-1 );
+-  testcase( n==sizeof(zBuf) );
+-  testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
+-  testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH] );
+-  if( n<sizeof(zBuf) ){
+-    z = zBuf;
+-  }else if( n>(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ){
+-    sqlite3_result_error_toobig(context);
+-    return;
+-  }else{
+-    z = sqlite3DbMallocRaw(db, (int)n);
+-    if( z==0 ){
+-      sqlite3_result_error_nomem(context);
+-      return;
+-    }
+-  }
+-  computeJD(&x);
+-  computeYMD_HMS(&x);
+-  for(i=j=0; zFmt[i]; i++){
+-    if( zFmt[i]!='%' ){
+-      z[j++] = zFmt[i];
+-    }else{
+-      i++;
+-      switch( zFmt[i] ){
+-        case 'd':  sqlite3_snprintf(3, &z[j],"%02d",x.D); j+=2; break;
+-        case 'f': {
+-          double s = x.s;
+-          if( s>59.999 ) s = 59.999;
+-          sqlite3_snprintf(7, &z[j],"%06.3f", s);
+-          j += sqlite3Strlen30(&z[j]);
+-          break;
+-        }
+-        case 'H':  sqlite3_snprintf(3, &z[j],"%02d",x.h); j+=2; break;
+-        case 'W': /* Fall thru */
+-        case 'j': {
+-          int nDay;             /* Number of days since 1st day of year */
+-          DateTime y = x;
+-          y.validJD = 0;
+-          y.M = 1;
+-          y.D = 1;
+-          computeJD(&y);
+-          nDay = (int)((x.iJD-y.iJD+43200000)/86400000);
+-          if( zFmt[i]=='W' ){
+-            int wd;   /* 0=Monday, 1=Tuesday, ... 6=Sunday */
+-            wd = (int)(((x.iJD+43200000)/86400000)%7);
+-            sqlite3_snprintf(3, &z[j],"%02d",(nDay+7-wd)/7);
+-            j += 2;
+-          }else{
+-            sqlite3_snprintf(4, &z[j],"%03d",nDay+1);
+-            j += 3;
+-          }
+-          break;
+-        }
+-        case 'J': {
+-          sqlite3_snprintf(20, &z[j],"%.16g",x.iJD/86400000.0);
+-          j+=sqlite3Strlen30(&z[j]);
+-          break;
+-        }
+-        case 'm':  sqlite3_snprintf(3, &z[j],"%02d",x.M); j+=2; break;
+-        case 'M':  sqlite3_snprintf(3, &z[j],"%02d",x.m); j+=2; break;
+-        case 's': {
+-          sqlite3_snprintf(30,&z[j],"%lld",
+-                           (i64)(x.iJD/1000 - 21086676*(i64)10000));
+-          j += sqlite3Strlen30(&z[j]);
+-          break;
+-        }
+-        case 'S':  sqlite3_snprintf(3,&z[j],"%02d",(int)x.s); j+=2; break;
+-        case 'w': {
+-          z[j++] = (char)(((x.iJD+129600000)/86400000) % 7) + '0';
+-          break;
+-        }
+-        case 'Y': {
+-          sqlite3_snprintf(5,&z[j],"%04d",x.Y); j+=sqlite3Strlen30(&z[j]);
+-          break;
+-        }
+-        default:   z[j++] = '%'; break;
+-      }
+-    }
+-  }
+-  z[j] = 0;
+-  sqlite3_result_text(context, z, -1,
+-                      z==zBuf ? SQLITE_TRANSIENT : SQLITE_DYNAMIC);
+-}
+-
+-/*
+-** current_time()
+-**
+-** This function returns the same value as time('now').
+-*/
+-static void ctimeFunc(
+-  sqlite3_context *context,
+-  int NotUsed,
+-  sqlite3_value **NotUsed2
+-){
+-  UNUSED_PARAMETER2(NotUsed, NotUsed2);
+-  timeFunc(context, 0, 0);
+-}
 +SQLITE_PRIVATE const Token sqlite3IntTokens[] = {
 +   { "0", 1 },
 +   { "1", 1 }
 +};
-+
-+
-+/*
+ 
+-/*
+-** current_date()
+-**
+-** This function returns the same value as date('now').
+-*/
+-static void cdateFunc(
+-  sqlite3_context *context,
+-  int NotUsed,
+-  sqlite3_value **NotUsed2
+-){
+-  UNUSED_PARAMETER2(NotUsed, NotUsed2);
+-  dateFunc(context, 0, 0);
+-}
+ 
+ /*
+-** current_timestamp()
 +** The value of the "pending" byte must be 0x40000000 (1 byte past the
 +** 1-gibabyte boundary) in a compatible database.  SQLite never uses
 +** the database page that contains the pending byte.  It never attempts
 +** to read or write that page.  The pending byte page is set assign
 +** for use by the VFS layers as space for managing file locks.
-+**
+ **
+-** This function returns the same value as datetime('now').
+-*/
+-static void ctimestampFunc(
+-  sqlite3_context *context,
+-  int NotUsed,
+-  sqlite3_value **NotUsed2
+-){
+-  UNUSED_PARAMETER2(NotUsed, NotUsed2);
+-  datetimeFunc(context, 0, 0);
+-}
+-#endif /* !defined(SQLITE_OMIT_DATETIME_FUNCS) */
+-
+-#ifdef SQLITE_OMIT_DATETIME_FUNCS
+-/*
+-** If the library is compiled to omit the full-scale date and time
+-** handling (to get a smaller binary), the following minimal version
+-** of the functions current_time(), current_date() and current_timestamp()
+-** are included instead. This is to support column declarations that
+-** include "DEFAULT CURRENT_TIME" etc.
 +** During testing, it is often desirable to move the pending byte to
 +** a different position in the file.  This allows code that has to
 +** deal with the pending byte to run on files that are much smaller
 +** than 1 GiB.  The sqlite3_test_control() interface can be used to
 +** move the pending byte.
-+**
+ **
+-** This function uses the C-library functions time(), gmtime()
+-** and strftime(). The format string to pass to strftime() is supplied
+-** as the user-data for the function.
 +** IMPORTANT:  Changing the pending byte to any value other than
 +** 0x40000000 results in an incompatible database file format!
-+** Changing the pending byte during operating results in undefined
-+** and dileterious behavior.
-+*/
++** Changing the pending byte during operation will result in undefined
++** and incorrect behavior.
+ */
+-static void currentTimeFunc(
+-  sqlite3_context *context,
+-  int argc,
+-  sqlite3_value **argv
+-){
+-  time_t t;
+-  char *zFormat = (char *)sqlite3_user_data(context);
+-  sqlite3 *db;
+-  sqlite3_int64 iT;
+-  struct tm *pTm;
+-  struct tm sNow;
+-  char zBuf[20];
+-
+-  UNUSED_PARAMETER(argc);
+-  UNUSED_PARAMETER(argv);
+-
+-  iT = sqlite3StmtCurrentTime(context);
+-  if( iT<=0 ) return;
+-  t = iT/1000 - 10000*(sqlite3_int64)21086676;
+-#if HAVE_GMTIME_R
+-  pTm = gmtime_r(&t, &sNow);
+-#else
+-  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
+-  pTm = gmtime(&t);
+-  if( pTm ) memcpy(&sNow, pTm, sizeof(sNow));
+-  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
+-#endif
+-  if( pTm ){
+-    strftime(zBuf, 20, zFormat, &sNow);
+-    sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
+-  }
+-}
 +#ifndef SQLITE_OMIT_WSD
 +SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000;
-+#endif
-+
-+/*
+ #endif
+ 
+ /*
+-** This function registered all of the above C functions as SQL
+-** functions.  This should be the only routine in this file with
+-** external linkage.
 +** Properties of opcodes.  The OPFLG_INITIALIZER macro is
 +** created by mkopcodeh.awk during compilation.  Data is obtained
 +** from the comments following the "case OP_xxxx:" statements in
 +** the vdbe.c file.  
-+*/
+ */
+-SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){
+-  static SQLITE_WSD FuncDef aDateTimeFuncs[] = {
+-#ifndef SQLITE_OMIT_DATETIME_FUNCS
+-    FUNCTION(julianday,        -1, 0, 0, juliandayFunc ),
+-    FUNCTION(date,             -1, 0, 0, dateFunc      ),
+-    FUNCTION(time,             -1, 0, 0, timeFunc      ),
+-    FUNCTION(datetime,         -1, 0, 0, datetimeFunc  ),
+-    FUNCTION(strftime,         -1, 0, 0, strftimeFunc  ),
+-    FUNCTION(current_time,      0, 0, 0, ctimeFunc     ),
+-    FUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
+-    FUNCTION(current_date,      0, 0, 0, cdateFunc     ),
+-#else
+-    STR_FUNCTION(current_time,      0, "%H:%M:%S",          0, currentTimeFunc),
+-    STR_FUNCTION(current_date,      0, "%Y-%m-%d",          0, currentTimeFunc),
+-    STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc),
+-#endif
+-  };
+-  int i;
+-  FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
+-  FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aDateTimeFuncs);
+-
+-  for(i=0; i<ArraySize(aDateTimeFuncs); i++){
+-    sqlite3FuncDefInsert(pHash, &aFunc[i]);
+-  }
+-}
 +SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER;
-+
+ 
+-/************** End of date.c ************************************************/
+-/************** Begin file os.c **********************************************/
 +/************** End of global.c **********************************************/
 +/************** Begin file ctime.c *******************************************/
-+/*
+ /*
+-** 2005 November 29
 +** 2010 February 23
+ **
+ ** The author disclaims copyright to this source code.  In place of
+ ** a legal notice, here is a blessing:
+@@ -16474,157 +17692,2571 @@
+ **    May you find forgiveness for yourself and forgive others.
+ **    May you share freely, never taking more than you give.
+ **
+-******************************************************************************
++*************************************************************************
+ **
+-** This file contains OS interface code that is common to all
+-** architectures.
++** This file implements routines used to report what compile-time options
++** SQLite was built with.
+ */
+-#define _SQLITE_OS_C_ 1
+-#undef _SQLITE_OS_C_
+ 
+-/*
+-** The default SQLite sqlite3_vfs implementations do not allocate
+-** memory (actually, os_unix.c allocates a small amount of memory
+-** from within OsOpen()), but some third-party implementations may.
+-** So we test the effects of a malloc() failing and the sqlite3OsXXX()
+-** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro.
+-**
+-** The following functions are instrumented for malloc() failure 
+-** testing:
+-**
+-**     sqlite3OsRead()
+-**     sqlite3OsWrite()
+-**     sqlite3OsSync()
+-**     sqlite3OsFileSize()
+-**     sqlite3OsLock()
+-**     sqlite3OsCheckReservedLock()
+-**     sqlite3OsFileControl()
+-**     sqlite3OsShmMap()
+-**     sqlite3OsOpen()
+-**     sqlite3OsDelete()
+-**     sqlite3OsAccess()
+-**     sqlite3OsFullPathname()
+-**
+-*/
+-#if defined(SQLITE_TEST)
+-SQLITE_API int sqlite3_memdebug_vfs_oom_test = 1;
+-  #define DO_OS_MALLOC_TEST(x)                                       \
+-  if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) {  \
+-    void *pTstAlloc = sqlite3Malloc(10);                             \
+-    if (!pTstAlloc) return SQLITE_IOERR_NOMEM;                       \
+-    sqlite3_free(pTstAlloc);                                         \
+-  }
+-#else
+-  #define DO_OS_MALLOC_TEST(x)
+-#endif
++#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
+ 
+-/*
+-** The following routines are convenience wrappers around methods
+-** of the sqlite3_file object.  This is mostly just syntactic sugar. All
+-** of this would be completely automatic if SQLite were coded using
+-** C++ instead of plain old C.
+-*/
+-SQLITE_PRIVATE int sqlite3OsClose(sqlite3_file *pId){
+-  int rc = SQLITE_OK;
+-  if( pId->pMethods ){
+-    rc = pId->pMethods->xClose(pId);
+-    pId->pMethods = 0;
+-  }
+-  return rc;
+-}
+-SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
+-  DO_OS_MALLOC_TEST(id);
+-  return id->pMethods->xRead(id, pBuf, amt, offset);
+-}
+-SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
+-  DO_OS_MALLOC_TEST(id);
+-  return id->pMethods->xWrite(id, pBuf, amt, offset);
+-}
+-SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file *id, i64 size){
+-  return id->pMethods->xTruncate(id, size);
+-}
+-SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file *id, int flags){
+-  DO_OS_MALLOC_TEST(id);
+-  return id->pMethods->xSync(id, flags);
+-}
+-SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
+-  DO_OS_MALLOC_TEST(id);
+-  return id->pMethods->xFileSize(id, pSize);
+-}
+-SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file *id, int lockType){
+-  DO_OS_MALLOC_TEST(id);
+-  return id->pMethods->xLock(id, lockType);
+-}
+-SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file *id, int lockType){
+-  return id->pMethods->xUnlock(id, lockType);
+-}
+-SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
+-  DO_OS_MALLOC_TEST(id);
+-  return id->pMethods->xCheckReservedLock(id, pResOut);
+-}
+ 
+ /*
+-** Use sqlite3OsFileControl() when we are doing something that might fail
+-** and we need to know about the failures.  Use sqlite3OsFileControlHint()
+-** when simply tossing information over the wall to the VFS and we do not
+-** really care if the VFS receives and understands the information since it
+-** is only a hint and can be safely ignored.  The sqlite3OsFileControlHint()
+-** routine has no return value since the return value would be meaningless.
++** An array of names of all compile-time options.  This array should 
++** be sorted A-Z.
++**
++** This array looks large, but in a typical installation actually uses
++** only a handful of compile-time options, so most times this array is usually
++** rather short and uses little memory space.
+ */
+-SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
+-#ifdef SQLITE_TEST
+-  if( op!=SQLITE_FCNTL_COMMIT_PHASETWO ){
+-    /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite
+-    ** is using a regular VFS, it is called after the corresponding 
+-    ** transaction has been committed. Injecting a fault at this point 
+-    ** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM
+-    ** but the transaction is committed anyway.
+-    **
+-    ** The core must call OsFileControl() though, not OsFileControlHint(),
+-    ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably
+-    ** means the commit really has failed and an error should be returned
+-    ** to the user.  */
+-    DO_OS_MALLOC_TEST(id);
+-  }
+-#endif
+-  return id->pMethods->xFileControl(id, op, pArg);
+-}
+-SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){
+-  (void)id->pMethods->xFileControl(id, op, pArg);
+-}
++static const char * const azCompileOpt[] = {
+ 
+-SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id){
+-  int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
+-  return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
+-}
+-SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
+-  return id->pMethods->xDeviceCharacteristics(id);
+-}
+-SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){
+-  return id->pMethods->xShmLock(id, offset, n, flags);
+-}
+-SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id){
+-  id->pMethods->xShmBarrier(id);
+-}
+-SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){
+-  return id->pMethods->xShmUnmap(id, deleteFlag);
+-}
+-SQLITE_PRIVATE int sqlite3OsShmMap(
+-  sqlite3_file *id,               /* Database file handle */
+-  int iPage,
+-  int pgsz,
+-  int bExtend,                    /* True to extend file if necessary */
+-  void volatile **pp              /* OUT: Pointer to mapping */
+-){
+-  DO_OS_MALLOC_TEST(id);
+-  return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
+-}
++/* These macros are provided to "stringify" the value of the define
++** for those options in which the value is meaningful. */
++#define CTIMEOPT_VAL_(opt) #opt
++#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
+ 
+-#if SQLITE_MAX_MMAP_SIZE>0
+-/* The real implementation of xFetch and xUnfetch */
+-SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){
+-  DO_OS_MALLOC_TEST(id);
+-  return id->pMethods->xFetch(id, iOff, iAmt, pp);
++#if SQLITE_32BIT_ROWID
++  "32BIT_ROWID",
++#endif
++#if SQLITE_4_BYTE_ALIGNED_MALLOC
++  "4_BYTE_ALIGNED_MALLOC",
++#endif
++#if SQLITE_CASE_SENSITIVE_LIKE
++  "CASE_SENSITIVE_LIKE",
++#endif
++#if SQLITE_CHECK_PAGES
++  "CHECK_PAGES",
++#endif
++#if SQLITE_COVERAGE_TEST
++  "COVERAGE_TEST",
++#endif
++#if SQLITE_DEBUG
++  "DEBUG",
++#endif
++#if SQLITE_DEFAULT_LOCKING_MODE
++  "DEFAULT_LOCKING_MODE=" CTIMEOPT_VAL(SQLITE_DEFAULT_LOCKING_MODE),
++#endif
++#if defined(SQLITE_DEFAULT_MMAP_SIZE) && !defined(SQLITE_DEFAULT_MMAP_SIZE_xc)
++  "DEFAULT_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_DEFAULT_MMAP_SIZE),
++#endif
++#if SQLITE_DISABLE_DIRSYNC
++  "DISABLE_DIRSYNC",
++#endif
++#if SQLITE_DISABLE_LFS
++  "DISABLE_LFS",
++#endif
++#if SQLITE_ENABLE_API_ARMOR
++  "ENABLE_API_ARMOR",
++#endif
++#if SQLITE_ENABLE_ATOMIC_WRITE
++  "ENABLE_ATOMIC_WRITE",
++#endif
++#if SQLITE_ENABLE_CEROD
++  "ENABLE_CEROD",
++#endif
++#if SQLITE_ENABLE_COLUMN_METADATA
++  "ENABLE_COLUMN_METADATA",
++#endif
++#if SQLITE_ENABLE_DBSTAT_VTAB
++  "ENABLE_DBSTAT_VTAB",
++#endif
++#if SQLITE_ENABLE_EXPENSIVE_ASSERT
++  "ENABLE_EXPENSIVE_ASSERT",
++#endif
++#if SQLITE_ENABLE_FTS1
++  "ENABLE_FTS1",
++#endif
++#if SQLITE_ENABLE_FTS2
++  "ENABLE_FTS2",
++#endif
++#if SQLITE_ENABLE_FTS3
++  "ENABLE_FTS3",
++#endif
++#if SQLITE_ENABLE_FTS3_PARENTHESIS
++  "ENABLE_FTS3_PARENTHESIS",
++#endif
++#if SQLITE_ENABLE_FTS4
++  "ENABLE_FTS4",
++#endif
++#if SQLITE_ENABLE_ICU
++  "ENABLE_ICU",
++#endif
++#if SQLITE_ENABLE_IOTRACE
++  "ENABLE_IOTRACE",
++#endif
++#if SQLITE_ENABLE_LOAD_EXTENSION
++  "ENABLE_LOAD_EXTENSION",
++#endif
++#if SQLITE_ENABLE_LOCKING_STYLE
++  "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE),
++#endif
++#if SQLITE_ENABLE_MEMORY_MANAGEMENT
++  "ENABLE_MEMORY_MANAGEMENT",
++#endif
++#if SQLITE_ENABLE_MEMSYS3
++  "ENABLE_MEMSYS3",
++#endif
++#if SQLITE_ENABLE_MEMSYS5
++  "ENABLE_MEMSYS5",
++#endif
++#if SQLITE_ENABLE_OVERSIZE_CELL_CHECK
++  "ENABLE_OVERSIZE_CELL_CHECK",
++#endif
++#if SQLITE_ENABLE_RTREE
++  "ENABLE_RTREE",
++#endif
++#if defined(SQLITE_ENABLE_STAT4)
++  "ENABLE_STAT4",
++#elif defined(SQLITE_ENABLE_STAT3)
++  "ENABLE_STAT3",
++#endif
++#if SQLITE_ENABLE_UNLOCK_NOTIFY
++  "ENABLE_UNLOCK_NOTIFY",
++#endif
++#if SQLITE_ENABLE_UPDATE_DELETE_LIMIT
++  "ENABLE_UPDATE_DELETE_LIMIT",
++#endif
++#if SQLITE_HAS_CODEC
++  "HAS_CODEC",
++#endif
++#if HAVE_ISNAN || SQLITE_HAVE_ISNAN
++  "HAVE_ISNAN",
++#endif
++#if SQLITE_HOMEGROWN_RECURSIVE_MUTEX
++  "HOMEGROWN_RECURSIVE_MUTEX",
++#endif
++#if SQLITE_IGNORE_AFP_LOCK_ERRORS
++  "IGNORE_AFP_LOCK_ERRORS",
++#endif
++#if SQLITE_IGNORE_FLOCK_LOCK_ERRORS
++  "IGNORE_FLOCK_LOCK_ERRORS",
++#endif
++#ifdef SQLITE_INT64_TYPE
++  "INT64_TYPE",
++#endif
++#if SQLITE_LOCK_TRACE
++  "LOCK_TRACE",
++#endif
++#if defined(SQLITE_MAX_MMAP_SIZE) && !defined(SQLITE_MAX_MMAP_SIZE_xc)
++  "MAX_MMAP_SIZE=" CTIMEOPT_VAL(SQLITE_MAX_MMAP_SIZE),
++#endif
++#ifdef SQLITE_MAX_SCHEMA_RETRY
++  "MAX_SCHEMA_RETRY=" CTIMEOPT_VAL(SQLITE_MAX_SCHEMA_RETRY),
++#endif
++#if SQLITE_MEMDEBUG
++  "MEMDEBUG",
++#endif
++#if SQLITE_MIXED_ENDIAN_64BIT_FLOAT
++  "MIXED_ENDIAN_64BIT_FLOAT",
++#endif
++#if SQLITE_NO_SYNC
++  "NO_SYNC",
++#endif
++#if SQLITE_OMIT_ALTERTABLE
++  "OMIT_ALTERTABLE",
++#endif
++#if SQLITE_OMIT_ANALYZE
++  "OMIT_ANALYZE",
++#endif
++#if SQLITE_OMIT_ATTACH
++  "OMIT_ATTACH",
++#endif
++#if SQLITE_OMIT_AUTHORIZATION
++  "OMIT_AUTHORIZATION",
++#endif
++#if SQLITE_OMIT_AUTOINCREMENT
++  "OMIT_AUTOINCREMENT",
++#endif
++#if SQLITE_OMIT_AUTOINIT
++  "OMIT_AUTOINIT",
++#endif
++#if SQLITE_OMIT_AUTOMATIC_INDEX
++  "OMIT_AUTOMATIC_INDEX",
++#endif
++#if SQLITE_OMIT_AUTORESET
++  "OMIT_AUTORESET",
++#endif
++#if SQLITE_OMIT_AUTOVACUUM
++  "OMIT_AUTOVACUUM",
++#endif
++#if SQLITE_OMIT_BETWEEN_OPTIMIZATION
++  "OMIT_BETWEEN_OPTIMIZATION",
++#endif
++#if SQLITE_OMIT_BLOB_LITERAL
++  "OMIT_BLOB_LITERAL",
++#endif
++#if SQLITE_OMIT_BTREECOUNT
++  "OMIT_BTREECOUNT",
++#endif
++#if SQLITE_OMIT_BUILTIN_TEST
++  "OMIT_BUILTIN_TEST",
++#endif
++#if SQLITE_OMIT_CAST
++  "OMIT_CAST",
++#endif
++#if SQLITE_OMIT_CHECK
++  "OMIT_CHECK",
++#endif
++#if SQLITE_OMIT_COMPLETE
++  "OMIT_COMPLETE",
++#endif
++#if SQLITE_OMIT_COMPOUND_SELECT
++  "OMIT_COMPOUND_SELECT",
++#endif
++#if SQLITE_OMIT_CTE
++  "OMIT_CTE",
++#endif
++#if SQLITE_OMIT_DATETIME_FUNCS
++  "OMIT_DATETIME_FUNCS",
++#endif
++#if SQLITE_OMIT_DECLTYPE
++  "OMIT_DECLTYPE",
++#endif
++#if SQLITE_OMIT_DEPRECATED
++  "OMIT_DEPRECATED",
++#endif
++#if SQLITE_OMIT_DISKIO
++  "OMIT_DISKIO",
++#endif
++#if SQLITE_OMIT_EXPLAIN
++  "OMIT_EXPLAIN",
++#endif
++#if SQLITE_OMIT_FLAG_PRAGMAS
++  "OMIT_FLAG_PRAGMAS",
++#endif
++#if SQLITE_OMIT_FLOATING_POINT
++  "OMIT_FLOATING_POINT",
++#endif
++#if SQLITE_OMIT_FOREIGN_KEY
++  "OMIT_FOREIGN_KEY",
++#endif
++#if SQLITE_OMIT_GET_TABLE
++  "OMIT_GET_TABLE",
++#endif
++#if SQLITE_OMIT_INCRBLOB
++  "OMIT_INCRBLOB",
++#endif
++#if SQLITE_OMIT_INTEGRITY_CHECK
++  "OMIT_INTEGRITY_CHECK",
++#endif
++#if SQLITE_OMIT_LIKE_OPTIMIZATION
++  "OMIT_LIKE_OPTIMIZATION",
++#endif
++#if SQLITE_OMIT_LOAD_EXTENSION
++  "OMIT_LOAD_EXTENSION",
++#endif
++#if SQLITE_OMIT_LOCALTIME
++  "OMIT_LOCALTIME",
++#endif
++#if SQLITE_OMIT_LOOKASIDE
++  "OMIT_LOOKASIDE",
++#endif
++#if SQLITE_OMIT_MEMORYDB
++  "OMIT_MEMORYDB",
++#endif
++#if SQLITE_OMIT_OR_OPTIMIZATION
++  "OMIT_OR_OPTIMIZATION",
++#endif
++#if SQLITE_OMIT_PAGER_PRAGMAS
++  "OMIT_PAGER_PRAGMAS",
++#endif
++#if SQLITE_OMIT_PRAGMA
++  "OMIT_PRAGMA",
++#endif
++#if SQLITE_OMIT_PROGRESS_CALLBACK
++  "OMIT_PROGRESS_CALLBACK",
++#endif
++#if SQLITE_OMIT_QUICKBALANCE
++  "OMIT_QUICKBALANCE",
++#endif
++#if SQLITE_OMIT_REINDEX
++  "OMIT_REINDEX",
++#endif
++#if SQLITE_OMIT_SCHEMA_PRAGMAS
++  "OMIT_SCHEMA_PRAGMAS",
++#endif
++#if SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS
++  "OMIT_SCHEMA_VERSION_PRAGMAS",
++#endif
++#if SQLITE_OMIT_SHARED_CACHE
++  "OMIT_SHARED_CACHE",
++#endif
++#if SQLITE_OMIT_SUBQUERY
++  "OMIT_SUBQUERY",
++#endif
++#if SQLITE_OMIT_TCL_VARIABLE
++  "OMIT_TCL_VARIABLE",
++#endif
++#if SQLITE_OMIT_TEMPDB
++  "OMIT_TEMPDB",
++#endif
++#if SQLITE_OMIT_TRACE
++  "OMIT_TRACE",
++#endif
++#if SQLITE_OMIT_TRIGGER
++  "OMIT_TRIGGER",
++#endif
++#if SQLITE_OMIT_TRUNCATE_OPTIMIZATION
++  "OMIT_TRUNCATE_OPTIMIZATION",
++#endif
++#if SQLITE_OMIT_UTF16
++  "OMIT_UTF16",
++#endif
++#if SQLITE_OMIT_VACUUM
++  "OMIT_VACUUM",
++#endif
++#if SQLITE_OMIT_VIEW
++  "OMIT_VIEW",
++#endif
++#if SQLITE_OMIT_VIRTUALTABLE
++  "OMIT_VIRTUALTABLE",
++#endif
++#if SQLITE_OMIT_WAL
++  "OMIT_WAL",
++#endif
++#if SQLITE_OMIT_WSD
++  "OMIT_WSD",
++#endif
++#if SQLITE_OMIT_XFER_OPT
++  "OMIT_XFER_OPT",
++#endif
++#if SQLITE_PERFORMANCE_TRACE
++  "PERFORMANCE_TRACE",
++#endif
++#if SQLITE_PROXY_DEBUG
++  "PROXY_DEBUG",
++#endif
++#if SQLITE_RTREE_INT_ONLY
++  "RTREE_INT_ONLY",
++#endif
++#if SQLITE_SECURE_DELETE
++  "SECURE_DELETE",
++#endif
++#if SQLITE_SMALL_STACK
++  "SMALL_STACK",
++#endif
++#if SQLITE_SOUNDEX
++  "SOUNDEX",
++#endif
++#if SQLITE_SYSTEM_MALLOC
++  "SYSTEM_MALLOC",
++#endif
++#if SQLITE_TCL
++  "TCL",
++#endif
++#if defined(SQLITE_TEMP_STORE) && !defined(SQLITE_TEMP_STORE_xc)
++  "TEMP_STORE=" CTIMEOPT_VAL(SQLITE_TEMP_STORE),
++#endif
++#if SQLITE_TEST
++  "TEST",
++#endif
++#if defined(SQLITE_THREADSAFE)
++  "THREADSAFE=" CTIMEOPT_VAL(SQLITE_THREADSAFE),
++#endif
++#if SQLITE_USE_ALLOCA
++  "USE_ALLOCA",
++#endif
++#if SQLITE_USER_AUTHENTICATION
++  "USER_AUTHENTICATION",
++#endif
++#if SQLITE_WIN32_MALLOC
++  "WIN32_MALLOC",
++#endif
++#if SQLITE_ZERO_MALLOC
++  "ZERO_MALLOC"
++#endif
++};
++
++/*
++** Given the name of a compile-time option, return true if that option
++** was used and false if not.
++**
++** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix
++** is not required for a match.
++*/
++SQLITE_API int SQLITE_STDCALL sqlite3_compileoption_used(const char *zOptName){
++  int i, n;
++
++#if SQLITE_ENABLE_API_ARMOR
++  if( zOptName==0 ){
++    (void)SQLITE_MISUSE_BKPT;
++    return 0;
++  }
++#endif
++  if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7;
++  n = sqlite3Strlen30(zOptName);
++
++  /* Since ArraySize(azCompileOpt) is normally in single digits, a
++  ** linear search is adequate.  No need for a binary search. */
++  for(i=0; i<ArraySize(azCompileOpt); i++){
++    if( sqlite3StrNICmp(zOptName, azCompileOpt[i], n)==0
++     && sqlite3IsIdChar((unsigned char)azCompileOpt[i][n])==0
++    ){
++      return 1;
++    }
++  }
++  return 0;
++}
++
++/*
++** Return the N-th compile-time option string.  If N is out of range,
++** return a NULL pointer.
++*/
++SQLITE_API const char *SQLITE_STDCALL sqlite3_compileoption_get(int N){
++  if( N>=0 && N<ArraySize(azCompileOpt) ){
++    return azCompileOpt[N];
++  }
++  return 0;
++}
++
++#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
++
++/************** End of ctime.c ***********************************************/
++/************** Begin file status.c ******************************************/
++/*
++** 2008 June 18
 +**
 +** The author disclaims copyright to this source code.  In place of
 +** a legal notice, here is a blessing:
@@ -4029,24 +6892,2141 @@
 +**
 +*************************************************************************
 +**
-+** This file implements routines used to report what compile-time options
-+** SQLite was built with.
++** This module implements the sqlite3_status() interface and related
++** functionality.
++*/
++/************** Include vdbeInt.h in the middle of status.c ******************/
++/************** Begin file vdbeInt.h *****************************************/
++/*
++** 2003 September 6
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++*************************************************************************
++** This is the header file for information that is private to the
++** VDBE.  This information used to all be at the top of the single
++** source code file "vdbe.c".  When that file became too big (over
++** 6000 lines long) it was split up into several smaller files and
++** this header information was factored out.
 +*/
++#ifndef _VDBEINT_H_
++#define _VDBEINT_H_
 +
-+#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
++/*
++** The maximum number of times that a statement will try to reparse
++** itself before giving up and returning SQLITE_SCHEMA.
++*/
++#ifndef SQLITE_MAX_SCHEMA_RETRY
++# define SQLITE_MAX_SCHEMA_RETRY 50
++#endif
 +
++/*
++** SQL is translated into a sequence of instructions to be
++** executed by a virtual machine.  Each instruction is an instance
++** of the following structure.
++*/
++typedef struct VdbeOp Op;
 +
 +/*
-+** An array of names of all compile-time options.  This array should 
-+** be sorted A-Z.
++** Boolean values
++*/
++typedef unsigned Bool;
++
++/* Opaque type used by code in vdbesort.c */
++typedef struct VdbeSorter VdbeSorter;
++
++/* Opaque type used by the explainer */
++typedef struct Explain Explain;
++
++/* Elements of the linked list at Vdbe.pAuxData */
++typedef struct AuxData AuxData;
++
++/*
++** A cursor is a pointer into a single BTree within a database file.
++** The cursor can seek to a BTree entry with a particular key, or
++** loop over all entries of the Btree.  You can also insert new BTree
++** entries or retrieve the key or data from the entry that the cursor
++** is currently pointing to.
 +**
-+** This array looks large, but in a typical installation actually uses
-+** only a handful of compile-time options, so most times this array is usually
-+** rather short and uses little memory space.
- */
- static const char * const azCompileOpt[] = {
- 
-@@ -19343,7 +22894,7 @@
++** Cursors can also point to virtual tables, sorters, or "pseudo-tables".
++** A pseudo-table is a single-row table implemented by registers.
++** 
++** Every cursor that the virtual machine has open is represented by an
++** instance of the following structure.
++*/
++struct VdbeCursor {
++  BtCursor *pCursor;    /* The cursor structure of the backend */
++  Btree *pBt;           /* Separate file holding temporary table */
++  KeyInfo *pKeyInfo;    /* Info about index keys needed by index cursors */
++  int seekResult;       /* Result of previous sqlite3BtreeMoveto() */
++  int pseudoTableReg;   /* Register holding pseudotable content. */
++  i16 nField;           /* Number of fields in the header */
++  u16 nHdrParsed;       /* Number of header fields parsed so far */
++#ifdef SQLITE_DEBUG
++  u8 seekOp;            /* Most recent seek operation on this cursor */
++#endif
++  i8 iDb;               /* Index of cursor database in db->aDb[] (or -1) */
++  u8 nullRow;           /* True if pointing to a row with no data */
++  u8 deferredMoveto;    /* A call to sqlite3BtreeMoveto() is needed */
++  Bool isEphemeral:1;   /* True for an ephemeral table */
++  Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
++  Bool isTable:1;       /* True if a table requiring integer keys */
++  Bool isOrdered:1;     /* True if the underlying table is BTREE_UNORDERED */
++  Pgno pgnoRoot;        /* Root page of the open btree cursor */
++  sqlite3_vtab_cursor *pVtabCursor;  /* The cursor for a virtual table */
++  i64 seqCount;         /* Sequence counter */
++  i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
++  VdbeSorter *pSorter;  /* Sorter object for OP_SorterOpen cursors */
++
++  /* Cached information about the header for the data record that the
++  ** cursor is currently pointing to.  Only valid if cacheStatus matches
++  ** Vdbe.cacheCtr.  Vdbe.cacheCtr will never take on the value of
++  ** CACHE_STALE and so setting cacheStatus=CACHE_STALE guarantees that
++  ** the cache is out of date.
++  **
++  ** aRow might point to (ephemeral) data for the current row, or it might
++  ** be NULL.
++  */
++  u32 cacheStatus;      /* Cache is valid if this matches Vdbe.cacheCtr */
++  u32 payloadSize;      /* Total number of bytes in the record */
++  u32 szRow;            /* Byte available in aRow */
++  u32 iHdrOffset;       /* Offset to next unparsed byte of the header */
++  const u8 *aRow;       /* Data for the current row, if all on one page */
++  u32 *aOffset;         /* Pointer to aType[nField] */
++  u32 aType[1];         /* Type values for all entries in the record */
++  /* 2*nField extra array elements allocated for aType[], beyond the one
++  ** static element declared in the structure.  nField total array slots for
++  ** aType[] and nField+1 array slots for aOffset[] */
++};
++typedef struct VdbeCursor VdbeCursor;
++
++/*
++** When a sub-program is executed (OP_Program), a structure of this type
++** is allocated to store the current value of the program counter, as
++** well as the current memory cell array and various other frame specific
++** values stored in the Vdbe struct. When the sub-program is finished, 
++** these values are copied back to the Vdbe from the VdbeFrame structure,
++** restoring the state of the VM to as it was before the sub-program
++** began executing.
++**
++** The memory for a VdbeFrame object is allocated and managed by a memory
++** cell in the parent (calling) frame. When the memory cell is deleted or
++** overwritten, the VdbeFrame object is not freed immediately. Instead, it
++** is linked into the Vdbe.pDelFrame list. The contents of the Vdbe.pDelFrame
++** list is deleted when the VM is reset in VdbeHalt(). The reason for doing
++** this instead of deleting the VdbeFrame immediately is to avoid recursive
++** calls to sqlite3VdbeMemRelease() when the memory cells belonging to the
++** child frame are released.
++**
++** The currently executing frame is stored in Vdbe.pFrame. Vdbe.pFrame is
++** set to NULL if the currently executing frame is the main program.
++*/
++typedef struct VdbeFrame VdbeFrame;
++struct VdbeFrame {
++  Vdbe *v;                /* VM this frame belongs to */
++  VdbeFrame *pParent;     /* Parent of this frame, or NULL if parent is main */
++  Op *aOp;                /* Program instructions for parent frame */
++  i64 *anExec;            /* Event counters from parent frame */
++  Mem *aMem;              /* Array of memory cells for parent frame */
++  u8 *aOnceFlag;          /* Array of OP_Once flags for parent frame */
++  VdbeCursor **apCsr;     /* Array of Vdbe cursors for parent frame */
++  void *token;            /* Copy of SubProgram.token */
++  i64 lastRowid;          /* Last insert rowid (sqlite3.lastRowid) */
++  int nCursor;            /* Number of entries in apCsr */
++  int pc;                 /* Program Counter in parent (calling) frame */
++  int nOp;                /* Size of aOp array */
++  int nMem;               /* Number of entries in aMem */
++  int nOnceFlag;          /* Number of entries in aOnceFlag */
++  int nChildMem;          /* Number of memory cells for child frame */
++  int nChildCsr;          /* Number of cursors for child frame */
++  int nChange;            /* Statement changes (Vdbe.nChange)     */
++  int nDbChange;          /* Value of db->nChange */
++};
++
++#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))])
++
++/*
++** A value for VdbeCursor.cacheValid that means the cache is always invalid.
++*/
++#define CACHE_STALE 0
++
++/*
++** Internally, the vdbe manipulates nearly all SQL values as Mem
++** structures. Each Mem struct may cache multiple representations (string,
++** integer etc.) of the same value.
++*/
++struct Mem {
++  union MemValue {
++    double r;           /* Real value used when MEM_Real is set in flags */
++    i64 i;              /* Integer value used when MEM_Int is set in flags */
++    int nZero;          /* Used when bit MEM_Zero is set in flags */
++    FuncDef *pDef;      /* Used only when flags==MEM_Agg */
++    RowSet *pRowSet;    /* Used only when flags==MEM_RowSet */
++    VdbeFrame *pFrame;  /* Used when flags==MEM_Frame */
++  } u;
++  u16 flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
++  u8  enc;            /* SQLITE_UTF8, SQLITE_UTF16BE, SQLITE_UTF16LE */
++  int n;              /* Number of characters in string value, excluding '\0' */
++  char *z;            /* String or BLOB value */
++  /* ShallowCopy only needs to copy the information above */
++  char *zMalloc;      /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */
++  int szMalloc;       /* Size of the zMalloc allocation */
++  u32 uTemp;          /* Transient storage for serial_type in OP_MakeRecord */
++  sqlite3 *db;        /* The associated database connection */
++  void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */
++#ifdef SQLITE_DEBUG
++  Mem *pScopyFrom;    /* This Mem is a shallow copy of pScopyFrom */
++  void *pFiller;      /* So that sizeof(Mem) is a multiple of 8 */
++#endif
++};
++
++/* One or more of the following flags are set to indicate the validOK
++** representations of the value stored in the Mem struct.
++**
++** If the MEM_Null flag is set, then the value is an SQL NULL value.
++** No other flags may be set in this case.
++**
++** If the MEM_Str flag is set then Mem.z points at a string representation.
++** Usually this is encoded in the same unicode encoding as the main
++** database (see below for exceptions). If the MEM_Term flag is also
++** set, then the string is nul terminated. The MEM_Int and MEM_Real 
++** flags may coexist with the MEM_Str flag.
++*/
++#define MEM_Null      0x0001   /* Value is NULL */
++#define MEM_Str       0x0002   /* Value is a string */
++#define MEM_Int       0x0004   /* Value is an integer */
++#define MEM_Real      0x0008   /* Value is a real number */
++#define MEM_Blob      0x0010   /* Value is a BLOB */
++#define MEM_AffMask   0x001f   /* Mask of affinity bits */
++#define MEM_RowSet    0x0020   /* Value is a RowSet object */
++#define MEM_Frame     0x0040   /* Value is a VdbeFrame object */
++#define MEM_Undefined 0x0080   /* Value is undefined */
++#define MEM_Cleared   0x0100   /* NULL set by OP_Null, not from data */
++#define MEM_TypeMask  0x01ff   /* Mask of type bits */
++
++
++/* Whenever Mem contains a valid string or blob representation, one of
++** the following flags must be set to determine the memory management
++** policy for Mem.z.  The MEM_Term flag tells us whether or not the
++** string is \000 or \u0000 terminated
++*/
++#define MEM_Term      0x0200   /* String rep is nul terminated */
++#define MEM_Dyn       0x0400   /* Need to call Mem.xDel() on Mem.z */
++#define MEM_Static    0x0800   /* Mem.z points to a static string */
++#define MEM_Ephem     0x1000   /* Mem.z points to an ephemeral string */
++#define MEM_Agg       0x2000   /* Mem.z points to an agg function context */
++#define MEM_Zero      0x4000   /* Mem.i contains count of 0s appended to blob */
++#ifdef SQLITE_OMIT_INCRBLOB
++  #undef MEM_Zero
++  #define MEM_Zero 0x0000
++#endif
++
++/*
++** Clear any existing type flags from a Mem and replace them with f
++*/
++#define MemSetTypeFlag(p, f) \
++   ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f)
++
++/*
++** Return true if a memory cell is not marked as invalid.  This macro
++** is for use inside assert() statements only.
++*/
++#ifdef SQLITE_DEBUG
++#define memIsValid(M)  ((M)->flags & MEM_Undefined)==0
++#endif
++
++/*
++** Each auxiliary data pointer stored by a user defined function 
++** implementation calling sqlite3_set_auxdata() is stored in an instance
++** of this structure. All such structures associated with a single VM
++** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed
++** when the VM is halted (if not before).
++*/
++struct AuxData {
++  int iOp;                        /* Instruction number of OP_Function opcode */
++  int iArg;                       /* Index of function argument. */
++  void *pAux;                     /* Aux data pointer */
++  void (*xDelete)(void *);        /* Destructor for the aux data */
++  AuxData *pNext;                 /* Next element in list */
++};
++
++/*
++** The "context" argument for an installable function.  A pointer to an
++** instance of this structure is the first argument to the routines used
++** implement the SQL functions.
++**
++** There is a typedef for this structure in sqlite.h.  So all routines,
++** even the public interface to SQLite, can use a pointer to this structure.
++** But this file is the only place where the internal details of this
++** structure are known.
++**
++** This structure is defined inside of vdbeInt.h because it uses substructures
++** (Mem) which are only defined there.
++*/
++struct sqlite3_context {
++  Mem *pOut;            /* The return value is stored here */
++  FuncDef *pFunc;       /* Pointer to function information */
++  Mem *pMem;            /* Memory cell used to store aggregate context */
++  Vdbe *pVdbe;          /* The VM that owns this context */
++  int iOp;              /* Instruction number of OP_Function */
++  int isError;          /* Error code returned by the function. */
++  u8 skipFlag;          /* Skip accumulator loading if true */
++  u8 fErrorOrAux;       /* isError!=0 or pVdbe->pAuxData modified */
++};
++
++/*
++** An Explain object accumulates indented output which is helpful
++** in describing recursive data structures.
++*/
++struct Explain {
++  Vdbe *pVdbe;       /* Attach the explanation to this Vdbe */
++  StrAccum str;      /* The string being accumulated */
++  int nIndent;       /* Number of elements in aIndent */
++  u16 aIndent[100];  /* Levels of indentation */
++  char zBase[100];   /* Initial space */
++};
++
++/* A bitfield type for use inside of structures.  Always follow with :N where
++** N is the number of bits.
++*/
++typedef unsigned bft;  /* Bit Field Type */
++
++typedef struct ScanStatus ScanStatus;
++struct ScanStatus {
++  int addrExplain;                /* OP_Explain for loop */
++  int addrLoop;                   /* Address of "loops" counter */
++  int addrVisit;                  /* Address of "rows visited" counter */
++  int iSelectID;                  /* The "Select-ID" for this loop */
++  LogEst nEst;                    /* Estimated output rows per loop */
++  char *zName;                    /* Name of table or index */
++};
++
++/*
++** An instance of the virtual machine.  This structure contains the complete
++** state of the virtual machine.
++**
++** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare()
++** is really a pointer to an instance of this structure.
++*/
++struct Vdbe {
++  sqlite3 *db;            /* The database connection that owns this statement */
++  Op *aOp;                /* Space to hold the virtual machine's program */
++  Mem *aMem;              /* The memory locations */
++  Mem **apArg;            /* Arguments to currently executing user function */
++  Mem *aColName;          /* Column names to return */
++  Mem *pResultSet;        /* Pointer to an array of results */
++  Parse *pParse;          /* Parsing context used to create this Vdbe */
++  int nMem;               /* Number of memory locations currently allocated */
++  int nOp;                /* Number of instructions in the program */
++  int nCursor;            /* Number of slots in apCsr[] */
++  u32 magic;              /* Magic number for sanity checking */
++  char *zErrMsg;          /* Error message written here */
++  Vdbe *pPrev,*pNext;     /* Linked list of VDBEs with the same Vdbe.db */
++  VdbeCursor **apCsr;     /* One element of this array for each open cursor */
++  Mem *aVar;              /* Values for the OP_Variable opcode. */
++  char **azVar;           /* Name of variables */
++  ynVar nVar;             /* Number of entries in aVar[] */
++  ynVar nzVar;            /* Number of entries in azVar[] */
++  u32 cacheCtr;           /* VdbeCursor row cache generation counter */
++  int pc;                 /* The program counter */
++  int rc;                 /* Value to return */
++#ifdef SQLITE_DEBUG
++  int rcApp;              /* errcode set by sqlite3_result_error_code() */
++#endif
++  u16 nResColumn;         /* Number of columns in one row of the result set */
++  u8 errorAction;         /* Recovery action to do in case of an error */
++  u8 minWriteFileFormat;  /* Minimum file format for writable database files */
++  bft explain:2;          /* True if EXPLAIN present on SQL command */
++  bft changeCntOn:1;      /* True to update the change-counter */
++  bft expired:1;          /* True if the VM needs to be recompiled */
++  bft runOnlyOnce:1;      /* Automatically expire on reset */
++  bft usesStmtJournal:1;  /* True if uses a statement journal */
++  bft readOnly:1;         /* True for statements that do not write */
++  bft bIsReader:1;        /* True for statements that read */
++  bft isPrepareV2:1;      /* True if prepared with prepare_v2() */
++  bft doingRerun:1;       /* True if rerunning after an auto-reprepare */
++  int nChange;            /* Number of db changes made since last reset */
++  yDbMask btreeMask;      /* Bitmask of db->aDb[] entries referenced */
++  yDbMask lockMask;       /* Subset of btreeMask that requires a lock */
++  int iStatement;         /* Statement number (or 0 if has not opened stmt) */
++  u32 aCounter[5];        /* Counters used by sqlite3_stmt_status() */
++#ifndef SQLITE_OMIT_TRACE
++  i64 startTime;          /* Time when query started - used for profiling */
++#endif
++  i64 iCurrentTime;       /* Value of julianday('now') for this statement */
++  i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
++  i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
++  i64 nStmtDefImmCons;    /* Number of def. imm constraints when stmt started */
++  char *zSql;             /* Text of the SQL statement that generated this */
++  void *pFree;            /* Free this when deleting the vdbe */
++  VdbeFrame *pFrame;      /* Parent frame */
++  VdbeFrame *pDelFrame;   /* List of frame objects to free on VM reset */
++  int nFrame;             /* Number of frames in pFrame list */
++  u32 expmask;            /* Binding to these vars invalidates VM */
++  SubProgram *pProgram;   /* Linked list of all sub-programs used by VM */
++  int nOnceFlag;          /* Size of array aOnceFlag[] */
++  u8 *aOnceFlag;          /* Flags for OP_Once */
++  AuxData *pAuxData;      /* Linked list of auxdata allocations */
++#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
++  i64 *anExec;            /* Number of times each op has been executed */
++  int nScan;              /* Entries in aScan[] */
++  ScanStatus *aScan;      /* Scan definitions for sqlite3_stmt_scanstatus() */
++#endif
++};
++
++/*
++** The following are allowed values for Vdbe.magic
++*/
++#define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */
++#define VDBE_MAGIC_RUN      0xbdf20da3    /* VDBE is ready to execute */
++#define VDBE_MAGIC_HALT     0x519c2973    /* VDBE has completed execution */
++#define VDBE_MAGIC_DEAD     0xb606c3c8    /* The VDBE has been deallocated */
++
++/*
++** Function prototypes
++*/
++SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
++void sqliteVdbePopStack(Vdbe*,int);
++SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*);
++SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
++#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
++SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, Op*);
++#endif
++SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
++SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
++SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32);
++SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
++SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
++
++int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
++SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*);
++SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*);
++SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
++SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
++SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
++SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int);
++SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*);
++SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem*, const Mem*);
++SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int);
++SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem*, Mem*);
++SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem*);
++SQLITE_PRIVATE int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*));
++SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem*, i64);
++#ifdef SQLITE_OMIT_FLOATING_POINT
++# define sqlite3VdbeMemSetDouble sqlite3VdbeMemSetInt64
++#else
++SQLITE_PRIVATE   void sqlite3VdbeMemSetDouble(Mem*, double);
++#endif
++SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
++SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*);
++SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int);
++SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem*);
++SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
++SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8);
++SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*);
++SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*);
++SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*);
++SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*);
++SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*);
++SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*);
++SQLITE_PRIVATE void sqlite3VdbeMemCast(Mem*,u8,u8);
++SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*);
++SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p);
++#define VdbeMemDynamic(X)  \
++  (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
++SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
++SQLITE_PRIVATE const char *sqlite3OpcodeName(int);
++SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
++SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
++SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int);
++SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*);
++SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *);
++SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p);
++
++SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, int, VdbeCursor *);
++SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *, VdbeSorter *);
++SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *);
++SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *);
++SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *);
++SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *, int *);
++SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *);
++SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *);
++
++#if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0
++SQLITE_PRIVATE   void sqlite3VdbeEnter(Vdbe*);
++SQLITE_PRIVATE   void sqlite3VdbeLeave(Vdbe*);
++#else
++# define sqlite3VdbeEnter(X)
++# define sqlite3VdbeLeave(X)
++#endif
++
++#ifdef SQLITE_DEBUG
++SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe*,Mem*);
++SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem*);
++#endif
++
++#ifndef SQLITE_OMIT_FOREIGN_KEY
++SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *, int);
++#else
++# define sqlite3VdbeCheckFk(p,i) 0
++#endif
++
++SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem*, u8);
++#ifdef SQLITE_DEBUG
++SQLITE_PRIVATE   void sqlite3VdbePrintSql(Vdbe*);
++SQLITE_PRIVATE   void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf);
++#endif
++SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem);
++
++#ifndef SQLITE_OMIT_INCRBLOB
++SQLITE_PRIVATE   int sqlite3VdbeMemExpandBlob(Mem *);
++  #define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0)
++#else
++  #define sqlite3VdbeMemExpandBlob(x) SQLITE_OK
++  #define ExpandBlob(P) SQLITE_OK
++#endif
++
++#endif /* !defined(_VDBEINT_H_) */
++
++/************** End of vdbeInt.h *********************************************/
++/************** Continuing where we left off in status.c *********************/
++
++/*
++** Variables in which to record status information.
++*/
++typedef struct sqlite3StatType sqlite3StatType;
++static SQLITE_WSD struct sqlite3StatType {
++#if SQLITE_PTRSIZE>4
++  sqlite3_int64 nowValue[10];         /* Current value */
++  sqlite3_int64 mxValue[10];          /* Maximum value */
++#else
++  u32 nowValue[10];                   /* Current value */
++  u32 mxValue[10];                    /* Maximum value */
++#endif
++} sqlite3Stat = { {0,}, {0,} };
++
++/*
++** Elements of sqlite3Stat[] are protected by either the memory allocator
++** mutex, or by the pcache1 mutex.  The following array determines which.
++*/
++static const char statMutex[] = {
++  0,  /* SQLITE_STATUS_MEMORY_USED */
++  1,  /* SQLITE_STATUS_PAGECACHE_USED */
++  1,  /* SQLITE_STATUS_PAGECACHE_OVERFLOW */
++  0,  /* SQLITE_STATUS_SCRATCH_USED */
++  0,  /* SQLITE_STATUS_SCRATCH_OVERFLOW */
++  0,  /* SQLITE_STATUS_MALLOC_SIZE */
++  0,  /* SQLITE_STATUS_PARSER_STACK */
++  1,  /* SQLITE_STATUS_PAGECACHE_SIZE */
++  0,  /* SQLITE_STATUS_SCRATCH_SIZE */
++  0,  /* SQLITE_STATUS_MALLOC_COUNT */
++};
++
++
++/* The "wsdStat" macro will resolve to the status information
++** state vector.  If writable static data is unsupported on the target,
++** we have to locate the state vector at run-time.  In the more common
++** case where writable static data is supported, wsdStat can refer directly
++** to the "sqlite3Stat" state vector declared above.
++*/
++#ifdef SQLITE_OMIT_WSD
++# define wsdStatInit  sqlite3StatType *x = &GLOBAL(sqlite3StatType,sqlite3Stat)
++# define wsdStat x[0]
++#else
++# define wsdStatInit
++# define wsdStat sqlite3Stat
++#endif
++
++/*
++** Return the current value of a status parameter.  The caller must
++** be holding the appropriate mutex.
++*/
++SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int op){
++  wsdStatInit;
++  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
++  assert( op>=0 && op<ArraySize(statMutex) );
++  assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
++                                           : sqlite3MallocMutex()) );
++  return wsdStat.nowValue[op];
++}
++
++/*
++** Add N to the value of a status record.  The caller must hold the
++** appropriate mutex.  (Locking is checked by assert()).
++**
++** The StatusUp() routine can accept positive or negative values for N.
++** The value of N is added to the current status value and the high-water
++** mark is adjusted if necessary.
++**
++** The StatusDown() routine lowers the current value by N.  The highwater
++** mark is unchanged.  N must be non-negative for StatusDown().
++*/
++SQLITE_PRIVATE void sqlite3StatusUp(int op, int N){
++  wsdStatInit;
++  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
++  assert( op>=0 && op<ArraySize(statMutex) );
++  assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
++                                           : sqlite3MallocMutex()) );
++  wsdStat.nowValue[op] += N;
++  if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
++    wsdStat.mxValue[op] = wsdStat.nowValue[op];
++  }
++}
++SQLITE_PRIVATE void sqlite3StatusDown(int op, int N){
++  wsdStatInit;
++  assert( N>=0 );
++  assert( op>=0 && op<ArraySize(statMutex) );
++  assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
++                                           : sqlite3MallocMutex()) );
++  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
++  wsdStat.nowValue[op] -= N;
++}
++
++/*
++** Set the value of a status to X.  The highwater mark is adjusted if
++** necessary.  The caller must hold the appropriate mutex.
++*/
++SQLITE_PRIVATE void sqlite3StatusSet(int op, int X){
++  wsdStatInit;
++  assert( op>=0 && op<ArraySize(wsdStat.nowValue) );
++  assert( op>=0 && op<ArraySize(statMutex) );
++  assert( sqlite3_mutex_held(statMutex[op] ? sqlite3Pcache1Mutex()
++                                           : sqlite3MallocMutex()) );
++  wsdStat.nowValue[op] = X;
++  if( wsdStat.nowValue[op]>wsdStat.mxValue[op] ){
++    wsdStat.mxValue[op] = wsdStat.nowValue[op];
++  }
++}
++
++/*
++** Query status information.
++*/
++SQLITE_API int SQLITE_STDCALL sqlite3_status64(
++  int op,
++  sqlite3_int64 *pCurrent,
++  sqlite3_int64 *pHighwater,
++  int resetFlag
++){
++  sqlite3_mutex *pMutex;
++  wsdStatInit;
++  if( op<0 || op>=ArraySize(wsdStat.nowValue) ){
++    return SQLITE_MISUSE_BKPT;
++  }
++#ifdef SQLITE_ENABLE_API_ARMOR
++  if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT;
++#endif
++  pMutex = statMutex[op] ? sqlite3Pcache1Mutex() : sqlite3MallocMutex();
++  sqlite3_mutex_enter(pMutex);
++  *pCurrent = wsdStat.nowValue[op];
++  *pHighwater = wsdStat.mxValue[op];
++  if( resetFlag ){
++    wsdStat.mxValue[op] = wsdStat.nowValue[op];
++  }
++  sqlite3_mutex_leave(pMutex);
++  (void)pMutex;  /* Prevent warning when SQLITE_THREADSAFE=0 */
++  return SQLITE_OK;
++}
++SQLITE_API int SQLITE_STDCALL sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
++  sqlite3_int64 iCur, iHwtr;
++  int rc;
++#ifdef SQLITE_ENABLE_API_ARMOR
++  if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT;
++#endif
++  rc = sqlite3_status64(op, &iCur, &iHwtr, resetFlag);
++  if( rc==0 ){
++    *pCurrent = (int)iCur;
++    *pHighwater = (int)iHwtr;
++  }
++  return rc;
++}
++
++/*
++** Query status information for a single database connection
++*/
++SQLITE_API int SQLITE_STDCALL sqlite3_db_status(
++  sqlite3 *db,          /* The database connection whose status is desired */
++  int op,               /* Status verb */
++  int *pCurrent,        /* Write current value here */
++  int *pHighwater,      /* Write high-water mark here */
++  int resetFlag         /* Reset high-water mark if true */
++){
++  int rc = SQLITE_OK;   /* Return code */
++#ifdef SQLITE_ENABLE_API_ARMOR
++  if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwater==0 ){
++    return SQLITE_MISUSE_BKPT;
++  }
++#endif
++  sqlite3_mutex_enter(db->mutex);
++  switch( op ){
++    case SQLITE_DBSTATUS_LOOKASIDE_USED: {
++      *pCurrent = db->lookaside.nOut;
++      *pHighwater = db->lookaside.mxOut;
++      if( resetFlag ){
++        db->lookaside.mxOut = db->lookaside.nOut;
++      }
++      break;
++    }
++
++    case SQLITE_DBSTATUS_LOOKASIDE_HIT:
++    case SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE:
++    case SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL: {
++      testcase( op==SQLITE_DBSTATUS_LOOKASIDE_HIT );
++      testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE );
++      testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL );
++      assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)>=0 );
++      assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)<3 );
++      *pCurrent = 0;
++      *pHighwater = db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT];
++      if( resetFlag ){
++        db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT] = 0;
++      }
++      break;
++    }
++
++    /* 
++    ** Return an approximation for the amount of memory currently used
++    ** by all pagers associated with the given database connection.  The
++    ** highwater mark is meaningless and is returned as zero.
++    */
++    case SQLITE_DBSTATUS_CACHE_USED: {
++      int totalUsed = 0;
++      int i;
++      sqlite3BtreeEnterAll(db);
++      for(i=0; i<db->nDb; i++){
++        Btree *pBt = db->aDb[i].pBt;
++        if( pBt ){
++          Pager *pPager = sqlite3BtreePager(pBt);
++          totalUsed += sqlite3PagerMemUsed(pPager);
++        }
++      }
++      sqlite3BtreeLeaveAll(db);
++      *pCurrent = totalUsed;
++      *pHighwater = 0;
++      break;
++    }
++
++    /*
++    ** *pCurrent gets an accurate estimate of the amount of memory used
++    ** to store the schema for all databases (main, temp, and any ATTACHed
++    ** databases.  *pHighwater is set to zero.
++    */
++    case SQLITE_DBSTATUS_SCHEMA_USED: {
++      int i;                      /* Used to iterate through schemas */
++      int nByte = 0;              /* Used to accumulate return value */
++
++      sqlite3BtreeEnterAll(db);
++      db->pnBytesFreed = &nByte;
++      for(i=0; i<db->nDb; i++){
++        Schema *pSchema = db->aDb[i].pSchema;
++        if( ALWAYS(pSchema!=0) ){
++          HashElem *p;
++
++          nByte += sqlite3GlobalConfig.m.xRoundup(sizeof(HashElem)) * (
++              pSchema->tblHash.count 
++            + pSchema->trigHash.count
++            + pSchema->idxHash.count
++            + pSchema->fkeyHash.count
++          );
++          nByte += sqlite3MallocSize(pSchema->tblHash.ht);
++          nByte += sqlite3MallocSize(pSchema->trigHash.ht);
++          nByte += sqlite3MallocSize(pSchema->idxHash.ht);
++          nByte += sqlite3MallocSize(pSchema->fkeyHash.ht);
++
++          for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){
++            sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p));
++          }
++          for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){
++            sqlite3DeleteTable(db, (Table *)sqliteHashData(p));
++          }
++        }
++      }
++      db->pnBytesFreed = 0;
++      sqlite3BtreeLeaveAll(db);
++
++      *pHighwater = 0;
++      *pCurrent = nByte;
++      break;
++    }
++
++    /*
++    ** *pCurrent gets an accurate estimate of the amount of memory used
++    ** to store all prepared statements.
++    ** *pHighwater is set to zero.
++    */
++    case SQLITE_DBSTATUS_STMT_USED: {
++      struct Vdbe *pVdbe;         /* Used to iterate through VMs */
++      int nByte = 0;              /* Used to accumulate return value */
++
++      db->pnBytesFreed = &nByte;
++      for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){
++        sqlite3VdbeClearObject(db, pVdbe);
++        sqlite3DbFree(db, pVdbe);
++      }
++      db->pnBytesFreed = 0;
++
++      *pHighwater = 0;  /* IMP: R-64479-57858 */
++      *pCurrent = nByte;
++
++      break;
++    }
++
++    /*
++    ** Set *pCurrent to the total cache hits or misses encountered by all
++    ** pagers the database handle is connected to. *pHighwater is always set 
++    ** to zero.
++    */
++    case SQLITE_DBSTATUS_CACHE_HIT:
++    case SQLITE_DBSTATUS_CACHE_MISS:
++    case SQLITE_DBSTATUS_CACHE_WRITE:{
++      int i;
++      int nRet = 0;
++      assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 );
++      assert( SQLITE_DBSTATUS_CACHE_WRITE==SQLITE_DBSTATUS_CACHE_HIT+2 );
++
++      for(i=0; i<db->nDb; i++){
++        if( db->aDb[i].pBt ){
++          Pager *pPager = sqlite3BtreePager(db->aDb[i].pBt);
++          sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet);
++        }
++      }
++      *pHighwater = 0; /* IMP: R-42420-56072 */
++                       /* IMP: R-54100-20147 */
++                       /* IMP: R-29431-39229 */
++      *pCurrent = nRet;
++      break;
++    }
++
++    /* Set *pCurrent to non-zero if there are unresolved deferred foreign
++    ** key constraints.  Set *pCurrent to zero if all foreign key constraints
++    ** have been satisfied.  The *pHighwater is always set to zero.
++    */
++    case SQLITE_DBSTATUS_DEFERRED_FKS: {
++      *pHighwater = 0;  /* IMP: R-11967-56545 */
++      *pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0;
++      break;
++    }
++
++    default: {
++      rc = SQLITE_ERROR;
++    }
++  }
++  sqlite3_mutex_leave(db->mutex);
++  return rc;
++}
++
++/************** End of status.c **********************************************/
++/************** Begin file date.c ********************************************/
++/*
++** 2003 October 31
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++*************************************************************************
++** This file contains the C functions that implement date and time
++** functions for SQLite.  
++**
++** There is only one exported symbol in this file - the function
++** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
++** All other code has file scope.
++**
++** SQLite processes all times and dates as julian day numbers.  The
++** dates and times are stored as the number of days since noon
++** in Greenwich on November 24, 4714 B.C. according to the Gregorian
++** calendar system. 
++**
++** 1970-01-01 00:00:00 is JD 2440587.5
++** 2000-01-01 00:00:00 is JD 2451544.5
++**
++** This implementation requires years to be expressed as a 4-digit number
++** which means that only dates between 0000-01-01 and 9999-12-31 can
++** be represented, even though julian day numbers allow a much wider
++** range of dates.
++**
++** The Gregorian calendar system is used for all dates and times,
++** even those that predate the Gregorian calendar.  Historians usually
++** use the julian calendar for dates prior to 1582-10-15 and for some
++** dates afterwards, depending on locale.  Beware of this difference.
++**
++** The conversion algorithms are implemented based on descriptions
++** in the following text:
++**
++**      Jean Meeus
++**      Astronomical Algorithms, 2nd Edition, 1998
++**      ISBM 0-943396-61-1
++**      Willmann-Bell, Inc
++**      Richmond, Virginia (USA)
++*/
++/* #include <stdlib.h> */
++/* #include <assert.h> */
++#include <time.h>
++
++#ifndef SQLITE_OMIT_DATETIME_FUNCS
++
++
++/*
++** A structure for holding a single date and time.
++*/
++typedef struct DateTime DateTime;
++struct DateTime {
++  sqlite3_int64 iJD; /* The julian day number times 86400000 */
++  int Y, M, D;       /* Year, month, and day */
++  int h, m;          /* Hour and minutes */
++  int tz;            /* Timezone offset in minutes */
++  double s;          /* Seconds */
++  char validYMD;     /* True (1) if Y,M,D are valid */
++  char validHMS;     /* True (1) if h,m,s are valid */
++  char validJD;      /* True (1) if iJD is valid */
++  char validTZ;      /* True (1) if tz is valid */
++};
++
++
++/*
++** Convert zDate into one or more integers.  Additional arguments
++** come in groups of 5 as follows:
++**
++**       N       number of digits in the integer
++**       min     minimum allowed value of the integer
++**       max     maximum allowed value of the integer
++**       nextC   first character after the integer
++**       pVal    where to write the integers value.
++**
++** Conversions continue until one with nextC==0 is encountered.
++** The function returns the number of successful conversions.
++*/
++static int getDigits(const char *zDate, ...){
++  va_list ap;
++  int val;
++  int N;
++  int min;
++  int max;
++  int nextC;
++  int *pVal;
++  int cnt = 0;
++  va_start(ap, zDate);
++  do{
++    N = va_arg(ap, int);
++    min = va_arg(ap, int);
++    max = va_arg(ap, int);
++    nextC = va_arg(ap, int);
++    pVal = va_arg(ap, int*);
++    val = 0;
++    while( N-- ){
++      if( !sqlite3Isdigit(*zDate) ){
++        goto end_getDigits;
++      }
++      val = val*10 + *zDate - '0';
++      zDate++;
++    }
++    if( val<min || val>max || (nextC!=0 && nextC!=*zDate) ){
++      goto end_getDigits;
++    }
++    *pVal = val;
++    zDate++;
++    cnt++;
++  }while( nextC );
++end_getDigits:
++  va_end(ap);
++  return cnt;
++}
++
++/*
++** Parse a timezone extension on the end of a date-time.
++** The extension is of the form:
++**
++**        (+/-)HH:MM
++**
++** Or the "zulu" notation:
++**
++**        Z
++**
++** If the parse is successful, write the number of minutes
++** of change in p->tz and return 0.  If a parser error occurs,
++** return non-zero.
++**
++** A missing specifier is not considered an error.
++*/
++static int parseTimezone(const char *zDate, DateTime *p){
++  int sgn = 0;
++  int nHr, nMn;
++  int c;
++  while( sqlite3Isspace(*zDate) ){ zDate++; }
++  p->tz = 0;
++  c = *zDate;
++  if( c=='-' ){
++    sgn = -1;
++  }else if( c=='+' ){
++    sgn = +1;
++  }else if( c=='Z' || c=='z' ){
++    zDate++;
++    goto zulu_time;
++  }else{
++    return c!=0;
++  }
++  zDate++;
++  if( getDigits(zDate, 2, 0, 14, ':', &nHr, 2, 0, 59, 0, &nMn)!=2 ){
++    return 1;
++  }
++  zDate += 5;
++  p->tz = sgn*(nMn + nHr*60);
++zulu_time:
++  while( sqlite3Isspace(*zDate) ){ zDate++; }
++  return *zDate!=0;
++}
++
++/*
++** Parse times of the form HH:MM or HH:MM:SS or HH:MM:SS.FFFF.
++** The HH, MM, and SS must each be exactly 2 digits.  The
++** fractional seconds FFFF can be one or more digits.
++**
++** Return 1 if there is a parsing error and 0 on success.
++*/
++static int parseHhMmSs(const char *zDate, DateTime *p){
++  int h, m, s;
++  double ms = 0.0;
++  if( getDigits(zDate, 2, 0, 24, ':', &h, 2, 0, 59, 0, &m)!=2 ){
++    return 1;
++  }
++  zDate += 5;
++  if( *zDate==':' ){
++    zDate++;
++    if( getDigits(zDate, 2, 0, 59, 0, &s)!=1 ){
++      return 1;
++    }
++    zDate += 2;
++    if( *zDate=='.' && sqlite3Isdigit(zDate[1]) ){
++      double rScale = 1.0;
++      zDate++;
++      while( sqlite3Isdigit(*zDate) ){
++        ms = ms*10.0 + *zDate - '0';
++        rScale *= 10.0;
++        zDate++;
++      }
++      ms /= rScale;
++    }
++  }else{
++    s = 0;
++  }
++  p->validJD = 0;
++  p->validHMS = 1;
++  p->h = h;
++  p->m = m;
++  p->s = s + ms;
++  if( parseTimezone(zDate, p) ) return 1;
++  p->validTZ = (p->tz!=0)?1:0;
++  return 0;
++}
++
++/*
++** Convert from YYYY-MM-DD HH:MM:SS to julian day.  We always assume
++** that the YYYY-MM-DD is according to the Gregorian calendar.
++**
++** Reference:  Meeus page 61
++*/
++static void computeJD(DateTime *p){
++  int Y, M, D, A, B, X1, X2;
++
++  if( p->validJD ) return;
++  if( p->validYMD ){
++    Y = p->Y;
++    M = p->M;
++    D = p->D;
++  }else{
++    Y = 2000;  /* If no YMD specified, assume 2000-Jan-01 */
++    M = 1;
++    D = 1;
++  }
++  if( M<=2 ){
++    Y--;
++    M += 12;
++  }
++  A = Y/100;
++  B = 2 - A + (A/4);
++  X1 = 36525*(Y+4716)/100;
++  X2 = 306001*(M+1)/10000;
++  p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000);
++  p->validJD = 1;
++  if( p->validHMS ){
++    p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000);
++    if( p->validTZ ){
++      p->iJD -= p->tz*60000;
++      p->validYMD = 0;
++      p->validHMS = 0;
++      p->validTZ = 0;
++    }
++  }
++}
++
++/*
++** Parse dates of the form
++**
++**     YYYY-MM-DD HH:MM:SS.FFF
++**     YYYY-MM-DD HH:MM:SS
++**     YYYY-MM-DD HH:MM
++**     YYYY-MM-DD
++**
++** Write the result into the DateTime structure and return 0
++** on success and 1 if the input string is not a well-formed
++** date.
++*/
++static int parseYyyyMmDd(const char *zDate, DateTime *p){
++  int Y, M, D, neg;
++
++  if( zDate[0]=='-' ){
++    zDate++;
++    neg = 1;
++  }else{
++    neg = 0;
++  }
++  if( getDigits(zDate,4,0,9999,'-',&Y,2,1,12,'-',&M,2,1,31,0,&D)!=3 ){
++    return 1;
++  }
++  zDate += 10;
++  while( sqlite3Isspace(*zDate) || 'T'==*(u8*)zDate ){ zDate++; }
++  if( parseHhMmSs(zDate, p)==0 ){
++    /* We got the time */
++  }else if( *zDate==0 ){
++    p->validHMS = 0;
++  }else{
++    return 1;
++  }
++  p->validJD = 0;
++  p->validYMD = 1;
++  p->Y = neg ? -Y : Y;
++  p->M = M;
++  p->D = D;
++  if( p->validTZ ){
++    computeJD(p);
++  }
++  return 0;
++}
++
++/*
++** Set the time to the current time reported by the VFS.
++**
++** Return the number of errors.
++*/
++static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
++  p->iJD = sqlite3StmtCurrentTime(context);
++  if( p->iJD>0 ){
++    p->validJD = 1;
++    return 0;
++  }else{
++    return 1;
++  }
++}
++
++/*
++** Attempt to parse the given string into a julian day number.  Return
++** the number of errors.
++**
++** The following are acceptable forms for the input string:
++**
++**      YYYY-MM-DD HH:MM:SS.FFF  +/-HH:MM
++**      DDDD.DD 
++**      now
++**
++** In the first form, the +/-HH:MM is always optional.  The fractional
++** seconds extension (the ".FFF") is optional.  The seconds portion
++** (":SS.FFF") is option.  The year and date can be omitted as long
++** as there is a time string.  The time string can be omitted as long
++** as there is a year and date.
++*/
++static int parseDateOrTime(
++  sqlite3_context *context, 
++  const char *zDate, 
++  DateTime *p
++){
++  double r;
++  if( parseYyyyMmDd(zDate,p)==0 ){
++    return 0;
++  }else if( parseHhMmSs(zDate, p)==0 ){
++    return 0;
++  }else if( sqlite3StrICmp(zDate,"now")==0){
++    return setDateTimeToCurrent(context, p);
++  }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
++    p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
++    p->validJD = 1;
++    return 0;
++  }
++  return 1;
++}
++
++/*
++** Compute the Year, Month, and Day from the julian day number.
++*/
++static void computeYMD(DateTime *p){
++  int Z, A, B, C, D, E, X1;
++  if( p->validYMD ) return;
++  if( !p->validJD ){
++    p->Y = 2000;
++    p->M = 1;
++    p->D = 1;
++  }else{
++    Z = (int)((p->iJD + 43200000)/86400000);
++    A = (int)((Z - 1867216.25)/36524.25);
++    A = Z + 1 + A - (A/4);
++    B = A + 1524;
++    C = (int)((B - 122.1)/365.25);
++    D = (36525*C)/100;
++    E = (int)((B-D)/30.6001);
++    X1 = (int)(30.6001*E);
++    p->D = B - D - X1;
++    p->M = E<14 ? E-1 : E-13;
++    p->Y = p->M>2 ? C - 4716 : C - 4715;
++  }
++  p->validYMD = 1;
++}
++
++/*
++** Compute the Hour, Minute, and Seconds from the julian day number.
++*/
++static void computeHMS(DateTime *p){
++  int s;
++  if( p->validHMS ) return;
++  computeJD(p);
++  s = (int)((p->iJD + 43200000) % 86400000);
++  p->s = s/1000.0;
++  s = (int)p->s;
++  p->s -= s;
++  p->h = s/3600;
++  s -= p->h*3600;
++  p->m = s/60;
++  p->s += s - p->m*60;
++  p->validHMS = 1;
++}
++
++/*
++** Compute both YMD and HMS
++*/
++static void computeYMD_HMS(DateTime *p){
++  computeYMD(p);
++  computeHMS(p);
++}
++
++/*
++** Clear the YMD and HMS and the TZ
++*/
++static void clearYMD_HMS_TZ(DateTime *p){
++  p->validYMD = 0;
++  p->validHMS = 0;
++  p->validTZ = 0;
++}
++
++/*
++** On recent Windows platforms, the localtime_s() function is available
++** as part of the "Secure CRT". It is essentially equivalent to 
++** localtime_r() available under most POSIX platforms, except that the 
++** order of the parameters is reversed.
++**
++** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx.
++**
++** If the user has not indicated to use localtime_r() or localtime_s()
++** already, check for an MSVC build environment that provides 
++** localtime_s().
++*/
++#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S \
++    && defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE)
++#undef  HAVE_LOCALTIME_S
++#define HAVE_LOCALTIME_S 1
++#endif
++
++#ifndef SQLITE_OMIT_LOCALTIME
++/*
++** The following routine implements the rough equivalent of localtime_r()
++** using whatever operating-system specific localtime facility that
++** is available.  This routine returns 0 on success and
++** non-zero on any kind of error.
++**
++** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this
++** routine will always fail.
++**
++** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C
++** library function localtime_r() is used to assist in the calculation of
++** local time.
++*/
++static int osLocaltime(time_t *t, struct tm *pTm){
++  int rc;
++#if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S
++  struct tm *pX;
++#if SQLITE_THREADSAFE>0
++  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
++#endif
++  sqlite3_mutex_enter(mutex);
++  pX = localtime(t);
++#ifndef SQLITE_OMIT_BUILTIN_TEST
++  if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0;
++#endif
++  if( pX ) *pTm = *pX;
++  sqlite3_mutex_leave(mutex);
++  rc = pX==0;
++#else
++#ifndef SQLITE_OMIT_BUILTIN_TEST
++  if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
++#endif
++#if HAVE_LOCALTIME_R
++  rc = localtime_r(t, pTm)==0;
++#else
++  rc = localtime_s(pTm, t);
++#endif /* HAVE_LOCALTIME_R */
++#endif /* HAVE_LOCALTIME_R || HAVE_LOCALTIME_S */
++  return rc;
++}
++#endif /* SQLITE_OMIT_LOCALTIME */
++
++
++#ifndef SQLITE_OMIT_LOCALTIME
++/*
++** Compute the difference (in milliseconds) between localtime and UTC
++** (a.k.a. GMT) for the time value p where p is in UTC. If no error occurs,
++** return this value and set *pRc to SQLITE_OK. 
++**
++** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value
++** is undefined in this case.
++*/
++static sqlite3_int64 localtimeOffset(
++  DateTime *p,                    /* Date at which to calculate offset */
++  sqlite3_context *pCtx,          /* Write error here if one occurs */
++  int *pRc                        /* OUT: Error code. SQLITE_OK or ERROR */
++){
++  DateTime x, y;
++  time_t t;
++  struct tm sLocal;
++
++  /* Initialize the contents of sLocal to avoid a compiler warning. */
++  memset(&sLocal, 0, sizeof(sLocal));
++
++  x = *p;
++  computeYMD_HMS(&x);
++  if( x.Y<1971 || x.Y>=2038 ){
++    /* EVIDENCE-OF: R-55269-29598 The localtime_r() C function normally only
++    ** works for years between 1970 and 2037. For dates outside this range,
++    ** SQLite attempts to map the year into an equivalent year within this
++    ** range, do the calculation, then map the year back.
++    */
++    x.Y = 2000;
++    x.M = 1;
++    x.D = 1;
++    x.h = 0;
++    x.m = 0;
++    x.s = 0.0;
++  } else {
++    int s = (int)(x.s + 0.5);
++    x.s = s;
++  }
++  x.tz = 0;
++  x.validJD = 0;
++  computeJD(&x);
++  t = (time_t)(x.iJD/1000 - 21086676*(i64)10000);
++  if( osLocaltime(&t, &sLocal) ){
++    sqlite3_result_error(pCtx, "local time unavailable", -1);
++    *pRc = SQLITE_ERROR;
++    return 0;
++  }
++  y.Y = sLocal.tm_year + 1900;
++  y.M = sLocal.tm_mon + 1;
++  y.D = sLocal.tm_mday;
++  y.h = sLocal.tm_hour;
++  y.m = sLocal.tm_min;
++  y.s = sLocal.tm_sec;
++  y.validYMD = 1;
++  y.validHMS = 1;
++  y.validJD = 0;
++  y.validTZ = 0;
++  computeJD(&y);
++  *pRc = SQLITE_OK;
++  return y.iJD - x.iJD;
++}
++#endif /* SQLITE_OMIT_LOCALTIME */
++
++/*
++** Process a modifier to a date-time stamp.  The modifiers are
++** as follows:
++**
++**     NNN days
++**     NNN hours
++**     NNN minutes
++**     NNN.NNNN seconds
++**     NNN months
++**     NNN years
++**     start of month
++**     start of year
++**     start of week
++**     start of day
++**     weekday N
++**     unixepoch
++**     localtime
++**     utc
++**
++** Return 0 on success and 1 if there is any kind of error. If the error
++** is in a system call (i.e. localtime()), then an error message is written
++** to context pCtx. If the error is an unrecognized modifier, no error is
++** written to pCtx.
++*/
++static int parseModifier(sqlite3_context *pCtx, const char *zMod, DateTime *p){
++  int rc = 1;
++  int n;
++  double r;
++  char *z, zBuf[30];
++  z = zBuf;
++  for(n=0; n<ArraySize(zBuf)-1 && zMod[n]; n++){
++    z[n] = (char)sqlite3UpperToLower[(u8)zMod[n]];
++  }
++  z[n] = 0;
++  switch( z[0] ){
++#ifndef SQLITE_OMIT_LOCALTIME
++    case 'l': {
++      /*    localtime
++      **
++      ** Assuming the current time value is UTC (a.k.a. GMT), shift it to
++      ** show local time.
++      */
++      if( strcmp(z, "localtime")==0 ){
++        computeJD(p);
++        p->iJD += localtimeOffset(p, pCtx, &rc);
++        clearYMD_HMS_TZ(p);
++      }
++      break;
++    }
++#endif
++    case 'u': {
++      /*
++      **    unixepoch
++      **
++      ** Treat the current value of p->iJD as the number of
++      ** seconds since 1970.  Convert to a real julian day number.
++      */
++      if( strcmp(z, "unixepoch")==0 && p->validJD ){
++        p->iJD = (p->iJD + 43200)/86400 + 21086676*(i64)10000000;
++        clearYMD_HMS_TZ(p);
++        rc = 0;
++      }
++#ifndef SQLITE_OMIT_LOCALTIME
++      else if( strcmp(z, "utc")==0 ){
++        sqlite3_int64 c1;
++        computeJD(p);
++        c1 = localtimeOffset(p, pCtx, &rc);
++        if( rc==SQLITE_OK ){
++          p->iJD -= c1;
++          clearYMD_HMS_TZ(p);
++          p->iJD += c1 - localtimeOffset(p, pCtx, &rc);
++        }
++      }
++#endif
++      break;
++    }
++    case 'w': {
++      /*
++      **    weekday N
++      **
++      ** Move the date to the same time on the next occurrence of
++      ** weekday N where 0==Sunday, 1==Monday, and so forth.  If the
++      ** date is already on the appropriate weekday, this is a no-op.
++      */
++      if( strncmp(z, "weekday ", 8)==0
++               && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)
++               && (n=(int)r)==r && n>=0 && r<7 ){
++        sqlite3_int64 Z;
++        computeYMD_HMS(p);
++        p->validTZ = 0;
++        p->validJD = 0;
++        computeJD(p);
++        Z = ((p->iJD + 129600000)/86400000) % 7;
++        if( Z>n ) Z -= 7;
++        p->iJD += (n - Z)*86400000;
++        clearYMD_HMS_TZ(p);
++        rc = 0;
++      }
++      break;
++    }
++    case 's': {
++      /*
++      **    start of TTTTT
++      **
++      ** Move the date backwards to the beginning of the current day,
++      ** or month or year.
++      */
++      if( strncmp(z, "start of ", 9)!=0 ) break;
++      z += 9;
++      computeYMD(p);
++      p->validHMS = 1;
++      p->h = p->m = 0;
++      p->s = 0.0;
++      p->validTZ = 0;
++      p->validJD = 0;
++      if( strcmp(z,"month")==0 ){
++        p->D = 1;
++        rc = 0;
++      }else if( strcmp(z,"year")==0 ){
++        computeYMD(p);
++        p->M = 1;
++        p->D = 1;
++        rc = 0;
++      }else if( strcmp(z,"day")==0 ){
++        rc = 0;
++      }
++      break;
++    }
++    case '+':
++    case '-':
++    case '0':
++    case '1':
++    case '2':
++    case '3':
++    case '4':
++    case '5':
++    case '6':
++    case '7':
++    case '8':
++    case '9': {
++      double rRounder;
++      for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){}
++      if( !sqlite3AtoF(z, &r, n, SQLITE_UTF8) ){
++        rc = 1;
++        break;
++      }
++      if( z[n]==':' ){
++        /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the
++        ** specified number of hours, minutes, seconds, and fractional seconds
++        ** to the time.  The ".FFF" may be omitted.  The ":SS.FFF" may be
++        ** omitted.
++        */
++        const char *z2 = z;
++        DateTime tx;
++        sqlite3_int64 day;
++        if( !sqlite3Isdigit(*z2) ) z2++;
++        memset(&tx, 0, sizeof(tx));
++        if( parseHhMmSs(z2, &tx) ) break;
++        computeJD(&tx);
++        tx.iJD -= 43200000;
++        day = tx.iJD/86400000;
++        tx.iJD -= day*86400000;
++        if( z[0]=='-' ) tx.iJD = -tx.iJD;
++        computeJD(p);
++        clearYMD_HMS_TZ(p);
++        p->iJD += tx.iJD;
++        rc = 0;
++        break;
++      }
++      z += n;
++      while( sqlite3Isspace(*z) ) z++;
++      n = sqlite3Strlen30(z);
++      if( n>10 || n<3 ) break;
++      if( z[n-1]=='s' ){ z[n-1] = 0; n--; }
++      computeJD(p);
++      rc = 0;
++      rRounder = r<0 ? -0.5 : +0.5;
++      if( n==3 && strcmp(z,"day")==0 ){
++        p->iJD += (sqlite3_int64)(r*86400000.0 + rRounder);
++      }else if( n==4 && strcmp(z,"hour")==0 ){
++        p->iJD += (sqlite3_int64)(r*(86400000.0/24.0) + rRounder);
++      }else if( n==6 && strcmp(z,"minute")==0 ){
++        p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0)) + rRounder);
++      }else if( n==6 && strcmp(z,"second")==0 ){
++        p->iJD += (sqlite3_int64)(r*(86400000.0/(24.0*60.0*60.0)) + rRounder);
++      }else if( n==5 && strcmp(z,"month")==0 ){
++        int x, y;
++        computeYMD_HMS(p);
++        p->M += (int)r;
++        x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12;
++        p->Y += x;
++        p->M -= x*12;
++        p->validJD = 0;
++        computeJD(p);
++        y = (int)r;
++        if( y!=r ){
++          p->iJD += (sqlite3_int64)((r - y)*30.0*86400000.0 + rRounder);
++        }
++      }else if( n==4 && strcmp(z,"year")==0 ){
++        int y = (int)r;
++        computeYMD_HMS(p);
++        p->Y += y;
++        p->validJD = 0;
++        computeJD(p);
++        if( y!=r ){
++          p->iJD += (sqlite3_int64)((r - y)*365.0*86400000.0 + rRounder);
++        }
++      }else{
++        rc = 1;
++      }
++      clearYMD_HMS_TZ(p);
++      break;
++    }
++    default: {
++      break;
++    }
++  }
++  return rc;
++}
++
++/*
++** Process time function arguments.  argv[0] is a date-time stamp.
++** argv[1] and following are modifiers.  Parse them all and write
++** the resulting time into the DateTime structure p.  Return 0
++** on success and 1 if there are any errors.
++**
++** If there are zero parameters (if even argv[0] is undefined)
++** then assume a default value of "now" for argv[0].
++*/
++static int isDate(
++  sqlite3_context *context, 
++  int argc, 
++  sqlite3_value **argv, 
++  DateTime *p
++){
++  int i;
++  const unsigned char *z;
++  int eType;
++  memset(p, 0, sizeof(*p));
++  if( argc==0 ){
++    return setDateTimeToCurrent(context, p);
++  }
++  if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT
++                   || eType==SQLITE_INTEGER ){
++    p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*86400000.0 + 0.5);
++    p->validJD = 1;
++  }else{
++    z = sqlite3_value_text(argv[0]);
++    if( !z || parseDateOrTime(context, (char*)z, p) ){
++      return 1;
++    }
++  }
++  for(i=1; i<argc; i++){
++    z = sqlite3_value_text(argv[i]);
++    if( z==0 || parseModifier(context, (char*)z, p) ) return 1;
++  }
++  return 0;
++}
++
++
++/*
++** The following routines implement the various date and time functions
++** of SQLite.
++*/
++
++/*
++**    julianday( TIMESTRING, MOD, MOD, ...)
++**
++** Return the julian day number of the date specified in the arguments
++*/
++static void juliandayFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  DateTime x;
++  if( isDate(context, argc, argv, &x)==0 ){
++    computeJD(&x);
++    sqlite3_result_double(context, x.iJD/86400000.0);
++  }
++}
++
++/*
++**    datetime( TIMESTRING, MOD, MOD, ...)
++**
++** Return YYYY-MM-DD HH:MM:SS
++*/
++static void datetimeFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  DateTime x;
++  if( isDate(context, argc, argv, &x)==0 ){
++    char zBuf[100];
++    computeYMD_HMS(&x);
++    sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d %02d:%02d:%02d",
++                     x.Y, x.M, x.D, x.h, x.m, (int)(x.s));
++    sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
++  }
++}
++
++/*
++**    time( TIMESTRING, MOD, MOD, ...)
++**
++** Return HH:MM:SS
++*/
++static void timeFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  DateTime x;
++  if( isDate(context, argc, argv, &x)==0 ){
++    char zBuf[100];
++    computeHMS(&x);
++    sqlite3_snprintf(sizeof(zBuf), zBuf, "%02d:%02d:%02d", x.h, x.m, (int)x.s);
++    sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
++  }
++}
++
++/*
++**    date( TIMESTRING, MOD, MOD, ...)
++**
++** Return YYYY-MM-DD
++*/
++static void dateFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  DateTime x;
++  if( isDate(context, argc, argv, &x)==0 ){
++    char zBuf[100];
++    computeYMD(&x);
++    sqlite3_snprintf(sizeof(zBuf), zBuf, "%04d-%02d-%02d", x.Y, x.M, x.D);
++    sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
++  }
++}
++
++/*
++**    strftime( FORMAT, TIMESTRING, MOD, MOD, ...)
++**
++** Return a string described by FORMAT.  Conversions as follows:
++**
++**   %d  day of month
++**   %f  ** fractional seconds  SS.SSS
++**   %H  hour 00-24
++**   %j  day of year 000-366
++**   %J  ** julian day number
++**   %m  month 01-12
++**   %M  minute 00-59
++**   %s  seconds since 1970-01-01
++**   %S  seconds 00-59
++**   %w  day of week 0-6  sunday==0
++**   %W  week of year 00-53
++**   %Y  year 0000-9999
++**   %%  %
++*/
++static void strftimeFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  DateTime x;
++  u64 n;
++  size_t i,j;
++  char *z;
++  sqlite3 *db;
++  const char *zFmt;
++  char zBuf[100];
++  if( argc==0 ) return;
++  zFmt = (const char*)sqlite3_value_text(argv[0]);
++  if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return;
++  db = sqlite3_context_db_handle(context);
++  for(i=0, n=1; zFmt[i]; i++, n++){
++    if( zFmt[i]=='%' ){
++      switch( zFmt[i+1] ){
++        case 'd':
++        case 'H':
++        case 'm':
++        case 'M':
++        case 'S':
++        case 'W':
++          n++;
++          /* fall thru */
++        case 'w':
++        case '%':
++          break;
++        case 'f':
++          n += 8;
++          break;
++        case 'j':
++          n += 3;
++          break;
++        case 'Y':
++          n += 8;
++          break;
++        case 's':
++        case 'J':
++          n += 50;
++          break;
++        default:
++          return;  /* ERROR.  return a NULL */
++      }
++      i++;
++    }
++  }
++  testcase( n==sizeof(zBuf)-1 );
++  testcase( n==sizeof(zBuf) );
++  testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
++  testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH] );
++  if( n<sizeof(zBuf) ){
++    z = zBuf;
++  }else if( n>(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ){
++    sqlite3_result_error_toobig(context);
++    return;
++  }else{
++    z = sqlite3DbMallocRaw(db, (int)n);
++    if( z==0 ){
++      sqlite3_result_error_nomem(context);
++      return;
++    }
++  }
++  computeJD(&x);
++  computeYMD_HMS(&x);
++  for(i=j=0; zFmt[i]; i++){
++    if( zFmt[i]!='%' ){
++      z[j++] = zFmt[i];
++    }else{
++      i++;
++      switch( zFmt[i] ){
++        case 'd':  sqlite3_snprintf(3, &z[j],"%02d",x.D); j+=2; break;
++        case 'f': {
++          double s = x.s;
++          if( s>59.999 ) s = 59.999;
++          sqlite3_snprintf(7, &z[j],"%06.3f", s);
++          j += sqlite3Strlen30(&z[j]);
++          break;
++        }
++        case 'H':  sqlite3_snprintf(3, &z[j],"%02d",x.h); j+=2; break;
++        case 'W': /* Fall thru */
++        case 'j': {
++          int nDay;             /* Number of days since 1st day of year */
++          DateTime y = x;
++          y.validJD = 0;
++          y.M = 1;
++          y.D = 1;
++          computeJD(&y);
++          nDay = (int)((x.iJD-y.iJD+43200000)/86400000);
++          if( zFmt[i]=='W' ){
++            int wd;   /* 0=Monday, 1=Tuesday, ... 6=Sunday */
++            wd = (int)(((x.iJD+43200000)/86400000)%7);
++            sqlite3_snprintf(3, &z[j],"%02d",(nDay+7-wd)/7);
++            j += 2;
++          }else{
++            sqlite3_snprintf(4, &z[j],"%03d",nDay+1);
++            j += 3;
++          }
++          break;
++        }
++        case 'J': {
++          sqlite3_snprintf(20, &z[j],"%.16g",x.iJD/86400000.0);
++          j+=sqlite3Strlen30(&z[j]);
++          break;
++        }
++        case 'm':  sqlite3_snprintf(3, &z[j],"%02d",x.M); j+=2; break;
++        case 'M':  sqlite3_snprintf(3, &z[j],"%02d",x.m); j+=2; break;
++        case 's': {
++          sqlite3_snprintf(30,&z[j],"%lld",
++                           (i64)(x.iJD/1000 - 21086676*(i64)10000));
++          j += sqlite3Strlen30(&z[j]);
++          break;
++        }
++        case 'S':  sqlite3_snprintf(3,&z[j],"%02d",(int)x.s); j+=2; break;
++        case 'w': {
++          z[j++] = (char)(((x.iJD+129600000)/86400000) % 7) + '0';
++          break;
++        }
++        case 'Y': {
++          sqlite3_snprintf(5,&z[j],"%04d",x.Y); j+=sqlite3Strlen30(&z[j]);
++          break;
++        }
++        default:   z[j++] = '%'; break;
++      }
++    }
++  }
++  z[j] = 0;
++  sqlite3_result_text(context, z, -1,
++                      z==zBuf ? SQLITE_TRANSIENT : SQLITE_DYNAMIC);
++}
++
++/*
++** current_time()
++**
++** This function returns the same value as time('now').
++*/
++static void ctimeFunc(
++  sqlite3_context *context,
++  int NotUsed,
++  sqlite3_value **NotUsed2
++){
++  UNUSED_PARAMETER2(NotUsed, NotUsed2);
++  timeFunc(context, 0, 0);
++}
++
++/*
++** current_date()
++**
++** This function returns the same value as date('now').
++*/
++static void cdateFunc(
++  sqlite3_context *context,
++  int NotUsed,
++  sqlite3_value **NotUsed2
++){
++  UNUSED_PARAMETER2(NotUsed, NotUsed2);
++  dateFunc(context, 0, 0);
++}
++
++/*
++** current_timestamp()
++**
++** This function returns the same value as datetime('now').
++*/
++static void ctimestampFunc(
++  sqlite3_context *context,
++  int NotUsed,
++  sqlite3_value **NotUsed2
++){
++  UNUSED_PARAMETER2(NotUsed, NotUsed2);
++  datetimeFunc(context, 0, 0);
++}
++#endif /* !defined(SQLITE_OMIT_DATETIME_FUNCS) */
++
++#ifdef SQLITE_OMIT_DATETIME_FUNCS
++/*
++** If the library is compiled to omit the full-scale date and time
++** handling (to get a smaller binary), the following minimal version
++** of the functions current_time(), current_date() and current_timestamp()
++** are included instead. This is to support column declarations that
++** include "DEFAULT CURRENT_TIME" etc.
++**
++** This function uses the C-library functions time(), gmtime()
++** and strftime(). The format string to pass to strftime() is supplied
++** as the user-data for the function.
++*/
++static void currentTimeFunc(
++  sqlite3_context *context,
++  int argc,
++  sqlite3_value **argv
++){
++  time_t t;
++  char *zFormat = (char *)sqlite3_user_data(context);
++  sqlite3 *db;
++  sqlite3_int64 iT;
++  struct tm *pTm;
++  struct tm sNow;
++  char zBuf[20];
++
++  UNUSED_PARAMETER(argc);
++  UNUSED_PARAMETER(argv);
++
++  iT = sqlite3StmtCurrentTime(context);
++  if( iT<=0 ) return;
++  t = iT/1000 - 10000*(sqlite3_int64)21086676;
++#if HAVE_GMTIME_R
++  pTm = gmtime_r(&t, &sNow);
++#else
++  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
++  pTm = gmtime(&t);
++  if( pTm ) memcpy(&sNow, pTm, sizeof(sNow));
++  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
++#endif
++  if( pTm ){
++    strftime(zBuf, 20, zFormat, &sNow);
++    sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
++  }
++}
++#endif
++
++/*
++** This function registered all of the above C functions as SQL
++** functions.  This should be the only routine in this file with
++** external linkage.
++*/
++SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){
++  static SQLITE_WSD FuncDef aDateTimeFuncs[] = {
++#ifndef SQLITE_OMIT_DATETIME_FUNCS
++    FUNCTION(julianday,        -1, 0, 0, juliandayFunc ),
++    FUNCTION(date,             -1, 0, 0, dateFunc      ),
++    FUNCTION(time,             -1, 0, 0, timeFunc      ),
++    FUNCTION(datetime,         -1, 0, 0, datetimeFunc  ),
++    FUNCTION(strftime,         -1, 0, 0, strftimeFunc  ),
++    FUNCTION(current_time,      0, 0, 0, ctimeFunc     ),
++    FUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc),
++    FUNCTION(current_date,      0, 0, 0, cdateFunc     ),
++#else
++    STR_FUNCTION(current_time,      0, "%H:%M:%S",          0, currentTimeFunc),
++    STR_FUNCTION(current_date,      0, "%Y-%m-%d",          0, currentTimeFunc),
++    STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc),
++#endif
++  };
++  int i;
++  FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions);
++  FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aDateTimeFuncs);
++
++  for(i=0; i<ArraySize(aDateTimeFuncs); i++){
++    sqlite3FuncDefInsert(pHash, &aFunc[i]);
++  }
++}
++
++/************** End of date.c ************************************************/
++/************** Begin file os.c **********************************************/
++/*
++** 2005 November 29
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++******************************************************************************
++**
++** This file contains OS interface code that is common to all
++** architectures.
++*/
++#define _SQLITE_OS_C_ 1
++#undef _SQLITE_OS_C_
++
++/*
++** The default SQLite sqlite3_vfs implementations do not allocate
++** memory (actually, os_unix.c allocates a small amount of memory
++** from within OsOpen()), but some third-party implementations may.
++** So we test the effects of a malloc() failing and the sqlite3OsXXX()
++** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro.
++**
++** The following functions are instrumented for malloc() failure 
++** testing:
++**
++**     sqlite3OsRead()
++**     sqlite3OsWrite()
++**     sqlite3OsSync()
++**     sqlite3OsFileSize()
++**     sqlite3OsLock()
++**     sqlite3OsCheckReservedLock()
++**     sqlite3OsFileControl()
++**     sqlite3OsShmMap()
++**     sqlite3OsOpen()
++**     sqlite3OsDelete()
++**     sqlite3OsAccess()
++**     sqlite3OsFullPathname()
++**
++*/
++#if defined(SQLITE_TEST)
++SQLITE_API int sqlite3_memdebug_vfs_oom_test = 1;
++  #define DO_OS_MALLOC_TEST(x)                                       \
++  if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) {  \
++    void *pTstAlloc = sqlite3Malloc(10);                             \
++    if (!pTstAlloc) return SQLITE_IOERR_NOMEM;                       \
++    sqlite3_free(pTstAlloc);                                         \
++  }
++#else
++  #define DO_OS_MALLOC_TEST(x)
++#endif
++
++/*
++** The following routines are convenience wrappers around methods
++** of the sqlite3_file object.  This is mostly just syntactic sugar. All
++** of this would be completely automatic if SQLite were coded using
++** C++ instead of plain old C.
++*/
++SQLITE_PRIVATE int sqlite3OsClose(sqlite3_file *pId){
++  int rc = SQLITE_OK;
++  if( pId->pMethods ){
++    rc = pId->pMethods->xClose(pId);
++    pId->pMethods = 0;
++  }
++  return rc;
++}
++SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){
++  DO_OS_MALLOC_TEST(id);
++  return id->pMethods->xRead(id, pBuf, amt, offset);
++}
++SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){
++  DO_OS_MALLOC_TEST(id);
++  return id->pMethods->xWrite(id, pBuf, amt, offset);
++}
++SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file *id, i64 size){
++  return id->pMethods->xTruncate(id, size);
++}
++SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file *id, int flags){
++  DO_OS_MALLOC_TEST(id);
++  return id->pMethods->xSync(id, flags);
++}
++SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
++  DO_OS_MALLOC_TEST(id);
++  return id->pMethods->xFileSize(id, pSize);
++}
++SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file *id, int lockType){
++  DO_OS_MALLOC_TEST(id);
++  return id->pMethods->xLock(id, lockType);
++}
++SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file *id, int lockType){
++  return id->pMethods->xUnlock(id, lockType);
++}
++SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
++  DO_OS_MALLOC_TEST(id);
++  return id->pMethods->xCheckReservedLock(id, pResOut);
++}
++
++/*
++** Use sqlite3OsFileControl() when we are doing something that might fail
++** and we need to know about the failures.  Use sqlite3OsFileControlHint()
++** when simply tossing information over the wall to the VFS and we do not
++** really care if the VFS receives and understands the information since it
++** is only a hint and can be safely ignored.  The sqlite3OsFileControlHint()
++** routine has no return value since the return value would be meaningless.
++*/
++SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
++#ifdef SQLITE_TEST
++  if( op!=SQLITE_FCNTL_COMMIT_PHASETWO ){
++    /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite
++    ** is using a regular VFS, it is called after the corresponding 
++    ** transaction has been committed. Injecting a fault at this point 
++    ** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM
++    ** but the transaction is committed anyway.
++    **
++    ** The core must call OsFileControl() though, not OsFileControlHint(),
++    ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably
++    ** means the commit really has failed and an error should be returned
++    ** to the user.  */
++    DO_OS_MALLOC_TEST(id);
++  }
++#endif
++  return id->pMethods->xFileControl(id, op, pArg);
++}
++SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){
++  (void)id->pMethods->xFileControl(id, op, pArg);
++}
++
++SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id){
++  int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
++  return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
++}
++SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
++  return id->pMethods->xDeviceCharacteristics(id);
++}
++SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){
++  return id->pMethods->xShmLock(id, offset, n, flags);
++}
++SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id){
++  id->pMethods->xShmBarrier(id);
++}
++SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){
++  return id->pMethods->xShmUnmap(id, deleteFlag);
++}
++SQLITE_PRIVATE int sqlite3OsShmMap(
++  sqlite3_file *id,               /* Database file handle */
++  int iPage,
++  int pgsz,
++  int bExtend,                    /* True to extend file if necessary */
++  void volatile **pp              /* OUT: Pointer to mapping */
++){
++  DO_OS_MALLOC_TEST(id);
++  return id->pMethods->xShmMap(id, iPage, pgsz, bExtend, pp);
++}
++
++#if SQLITE_MAX_MMAP_SIZE>0
++/* The real implementation of xFetch and xUnfetch */
++SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){
++  DO_OS_MALLOC_TEST(id);
++  return id->pMethods->xFetch(id, iOff, iAmt, pp);
+ }
+ SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){
+   return id->pMethods->xUnfetch(id, iOff, p);
+@@ -20088,7 +23720,7 @@
  /*
  ** Include the primary Windows SDK header file.
  */
@@ -4055,7 +9035,7 @@
  
  #ifdef __CYGWIN__
  # include <sys/cygwin.h>
-@@ -24157,7 +27708,7 @@
+@@ -25328,7 +28960,7 @@
  #include <sys/time.h>
  #include <errno.h>
  #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
@@ -4063,76 +9043,27895 @@
 +/* # include <sys/mman.h> */
  #endif
  
- #if SQLITE_ENABLE_LOCKING_STYLE || OS_VXWORKS
-@@ -47475,7 +51026,39 @@
+ #if SQLITE_ENABLE_LOCKING_STYLE
+@@ -33657,6275 +37289,5194 @@
+ #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
+   { "AreFileApisANSI",         (SYSCALL)AreFileApisANSI,         0 },
+ #else
+-  { "AreFileApisANSI",         (SYSCALL)0,                       0 },
+-#endif
+-
+-#ifndef osAreFileApisANSI
+-#define osAreFileApisANSI ((BOOL(WINAPI*)(VOID))aSyscall[0].pCurrent)
+-#endif
+-
+-#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
+-  { "CharLowerW",              (SYSCALL)CharLowerW,              0 },
+-#else
+-  { "CharLowerW",              (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osCharLowerW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[1].pCurrent)
+-
+-#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
+-  { "CharUpperW",              (SYSCALL)CharUpperW,              0 },
+-#else
+-  { "CharUpperW",              (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osCharUpperW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[2].pCurrent)
+-
+-  { "CloseHandle",             (SYSCALL)CloseHandle,             0 },
+-
+-#define osCloseHandle ((BOOL(WINAPI*)(HANDLE))aSyscall[3].pCurrent)
+-
+-#if defined(SQLITE_WIN32_HAS_ANSI)
+-  { "CreateFileA",             (SYSCALL)CreateFileA,             0 },
+-#else
+-  { "CreateFileA",             (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \
+-        LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent)
+-
+-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
+-  { "CreateFileW",             (SYSCALL)CreateFileW,             0 },
+-#else
+-  { "CreateFileW",             (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \
+-        LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
+-
+-#if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
+-        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
+-  { "CreateFileMappingA",      (SYSCALL)CreateFileMappingA,      0 },
+-#else
+-  { "CreateFileMappingA",      (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
+-        DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent)
+-
+-#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
+-        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
+-  { "CreateFileMappingW",      (SYSCALL)CreateFileMappingW,      0 },
+-#else
+-  { "CreateFileMappingW",      (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
+-        DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent)
+-
+-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
+-  { "CreateMutexW",            (SYSCALL)CreateMutexW,            0 },
+-#else
+-  { "CreateMutexW",            (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \
+-        LPCWSTR))aSyscall[8].pCurrent)
+-
+-#if defined(SQLITE_WIN32_HAS_ANSI)
+-  { "DeleteFileA",             (SYSCALL)DeleteFileA,             0 },
+-#else
+-  { "DeleteFileA",             (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].pCurrent)
+-
+-#if defined(SQLITE_WIN32_HAS_WIDE)
+-  { "DeleteFileW",             (SYSCALL)DeleteFileW,             0 },
+-#else
+-  { "DeleteFileW",             (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent)
+-
+-#if SQLITE_OS_WINCE
+-  { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 },
+-#else
+-  { "FileTimeToLocalFileTime", (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \
+-        LPFILETIME))aSyscall[11].pCurrent)
+-
+-#if SQLITE_OS_WINCE
+-  { "FileTimeToSystemTime",    (SYSCALL)FileTimeToSystemTime,    0 },
+-#else
+-  { "FileTimeToSystemTime",    (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \
+-        LPSYSTEMTIME))aSyscall[12].pCurrent)
+-
+-  { "FlushFileBuffers",        (SYSCALL)FlushFileBuffers,        0 },
+-
+-#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent)
+-
+-#if defined(SQLITE_WIN32_HAS_ANSI)
+-  { "FormatMessageA",          (SYSCALL)FormatMessageA,          0 },
+-#else
+-  { "FormatMessageA",          (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \
+-        DWORD,va_list*))aSyscall[14].pCurrent)
+-
+-#if defined(SQLITE_WIN32_HAS_WIDE)
+-  { "FormatMessageW",          (SYSCALL)FormatMessageW,          0 },
+-#else
+-  { "FormatMessageW",          (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \
+-        DWORD,va_list*))aSyscall[15].pCurrent)
+-
+-#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
+-  { "FreeLibrary",             (SYSCALL)FreeLibrary,             0 },
+-#else
+-  { "FreeLibrary",             (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent)
+-
+-  { "GetCurrentProcessId",     (SYSCALL)GetCurrentProcessId,     0 },
+-
+-#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].pCurrent)
+-
+-#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
+-  { "GetDiskFreeSpaceA",       (SYSCALL)GetDiskFreeSpaceA,       0 },
+-#else
+-  { "GetDiskFreeSpaceA",       (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \
+-        LPDWORD))aSyscall[18].pCurrent)
+-
+-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
+-  { "GetDiskFreeSpaceW",       (SYSCALL)GetDiskFreeSpaceW,       0 },
+-#else
+-  { "GetDiskFreeSpaceW",       (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \
+-        LPDWORD))aSyscall[19].pCurrent)
+-
+-#if defined(SQLITE_WIN32_HAS_ANSI)
+-  { "GetFileAttributesA",      (SYSCALL)GetFileAttributesA,      0 },
+-#else
+-  { "GetFileAttributesA",      (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent)
+-
+-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
+-  { "GetFileAttributesW",      (SYSCALL)GetFileAttributesW,      0 },
+-#else
+-  { "GetFileAttributesW",      (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent)
+-
+-#if defined(SQLITE_WIN32_HAS_WIDE)
+-  { "GetFileAttributesExW",    (SYSCALL)GetFileAttributesExW,    0 },
+-#else
+-  { "GetFileAttributesExW",    (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \
+-        LPVOID))aSyscall[22].pCurrent)
+-
+-#if !SQLITE_OS_WINRT
+-  { "GetFileSize",             (SYSCALL)GetFileSize,             0 },
+-#else
+-  { "GetFileSize",             (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[23].pCurrent)
+-
+-#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
+-  { "GetFullPathNameA",        (SYSCALL)GetFullPathNameA,        0 },
+-#else
+-  { "GetFullPathNameA",        (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \
+-        LPSTR*))aSyscall[24].pCurrent)
+-
+-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
+-  { "GetFullPathNameW",        (SYSCALL)GetFullPathNameW,        0 },
+-#else
+-  { "GetFullPathNameW",        (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \
+-        LPWSTR*))aSyscall[25].pCurrent)
+-
+-  { "GetLastError",            (SYSCALL)GetLastError,            0 },
+-
+-#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent)
+-
+-#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
+-#if SQLITE_OS_WINCE
+-  /* The GetProcAddressA() routine is only available on Windows CE. */
+-  { "GetProcAddressA",         (SYSCALL)GetProcAddressA,         0 },
+-#else
+-  /* All other Windows platforms expect GetProcAddress() to take
+-  ** an ANSI string regardless of the _UNICODE setting */
+-  { "GetProcAddressA",         (SYSCALL)GetProcAddress,          0 },
+-#endif
+-#else
+-  { "GetProcAddressA",         (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \
+-        LPCSTR))aSyscall[27].pCurrent)
+-
+-#if !SQLITE_OS_WINRT
+-  { "GetSystemInfo",           (SYSCALL)GetSystemInfo,           0 },
+-#else
+-  { "GetSystemInfo",           (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[28].pCurrent)
+-
+-  { "GetSystemTime",           (SYSCALL)GetSystemTime,           0 },
+-
+-#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[29].pCurrent)
+-
+-#if !SQLITE_OS_WINCE
+-  { "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 },
+-#else
+-  { "GetSystemTimeAsFileTime", (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \
+-        LPFILETIME))aSyscall[30].pCurrent)
+-
+-#if defined(SQLITE_WIN32_HAS_ANSI)
+-  { "GetTempPathA",            (SYSCALL)GetTempPathA,            0 },
+-#else
+-  { "GetTempPathA",            (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent)
+-
+-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
+-  { "GetTempPathW",            (SYSCALL)GetTempPathW,            0 },
+-#else
+-  { "GetTempPathW",            (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].pCurrent)
+-
+-#if !SQLITE_OS_WINRT
+-  { "GetTickCount",            (SYSCALL)GetTickCount,            0 },
+-#else
+-  { "GetTickCount",            (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent)
+-
+-#if defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_GETVERSIONEX) && \
+-        SQLITE_WIN32_GETVERSIONEX
+-  { "GetVersionExA",           (SYSCALL)GetVersionExA,           0 },
+-#else
+-  { "GetVersionExA",           (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osGetVersionExA ((BOOL(WINAPI*)( \
+-        LPOSVERSIONINFOA))aSyscall[34].pCurrent)
+-
+-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
+-        defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX
+-  { "GetVersionExW",           (SYSCALL)GetVersionExW,           0 },
+-#else
+-  { "GetVersionExW",           (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osGetVersionExW ((BOOL(WINAPI*)( \
+-        LPOSVERSIONINFOW))aSyscall[35].pCurrent)
+-
+-  { "HeapAlloc",               (SYSCALL)HeapAlloc,               0 },
+-
+-#define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \
+-        SIZE_T))aSyscall[36].pCurrent)
+-
+-#if !SQLITE_OS_WINRT
+-  { "HeapCreate",              (SYSCALL)HeapCreate,              0 },
+-#else
+-  { "HeapCreate",              (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \
+-        SIZE_T))aSyscall[37].pCurrent)
+-
+-#if !SQLITE_OS_WINRT
+-  { "HeapDestroy",             (SYSCALL)HeapDestroy,             0 },
+-#else
+-  { "HeapDestroy",             (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[38].pCurrent)
+-
+-  { "HeapFree",                (SYSCALL)HeapFree,                0 },
+-
+-#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[39].pCurrent)
+-
+-  { "HeapReAlloc",             (SYSCALL)HeapReAlloc,             0 },
+-
+-#define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \
+-        SIZE_T))aSyscall[40].pCurrent)
+-
+-  { "HeapSize",                (SYSCALL)HeapSize,                0 },
+-
+-#define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \
+-        LPCVOID))aSyscall[41].pCurrent)
+-
+-#if !SQLITE_OS_WINRT
+-  { "HeapValidate",            (SYSCALL)HeapValidate,            0 },
+-#else
+-  { "HeapValidate",            (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
+-        LPCVOID))aSyscall[42].pCurrent)
+-
+-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
+-  { "HeapCompact",             (SYSCALL)HeapCompact,             0 },
+-#else
+-  { "HeapCompact",             (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osHeapCompact ((UINT(WINAPI*)(HANDLE,DWORD))aSyscall[43].pCurrent)
+-
+-#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+-  { "LoadLibraryA",            (SYSCALL)LoadLibraryA,            0 },
+-#else
+-  { "LoadLibraryA",            (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[44].pCurrent)
+-
+-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
+-        !defined(SQLITE_OMIT_LOAD_EXTENSION)
+-  { "LoadLibraryW",            (SYSCALL)LoadLibraryW,            0 },
+-#else
+-  { "LoadLibraryW",            (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[45].pCurrent)
+-
+-#if !SQLITE_OS_WINRT
+-  { "LocalFree",               (SYSCALL)LocalFree,               0 },
+-#else
+-  { "LocalFree",               (SYSCALL)0,                       0 },
+-#endif
+-
+-#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[46].pCurrent)
+-
+-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
+-  { "LockFile",                (SYSCALL)LockFile,                0 },
+-#else
+-  { "LockFile",                (SYSCALL)0,                       0 },
++  { "AreFileApisANSI",         (SYSCALL)0,                       0 },
+ #endif
+ 
+-#ifndef osLockFile
+-#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
+-        DWORD))aSyscall[47].pCurrent)
++#ifndef osAreFileApisANSI
++#define osAreFileApisANSI ((BOOL(WINAPI*)(VOID))aSyscall[0].pCurrent)
+ #endif
+ 
+-#if !SQLITE_OS_WINCE
+-  { "LockFileEx",              (SYSCALL)LockFileEx,              0 },
++#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
++  { "CharLowerW",              (SYSCALL)CharLowerW,              0 },
+ #else
+-  { "LockFileEx",              (SYSCALL)0,                       0 },
++  { "CharLowerW",              (SYSCALL)0,                       0 },
+ #endif
+ 
+-#ifndef osLockFileEx
+-#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
+-        LPOVERLAPPED))aSyscall[48].pCurrent)
+-#endif
++#define osCharLowerW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[1].pCurrent)
+ 
+-#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && \
+-        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
+-  { "MapViewOfFile",           (SYSCALL)MapViewOfFile,           0 },
++#if SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_WIDE)
++  { "CharUpperW",              (SYSCALL)CharUpperW,              0 },
+ #else
+-  { "MapViewOfFile",           (SYSCALL)0,                       0 },
++  { "CharUpperW",              (SYSCALL)0,                       0 },
+ #endif
+ 
+-#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
+-        SIZE_T))aSyscall[49].pCurrent)
+-
+-  { "MultiByteToWideChar",     (SYSCALL)MultiByteToWideChar,     0 },
+-
+-#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \
+-        int))aSyscall[50].pCurrent)
+-
+-  { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 },
+-
+-#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \
+-        LARGE_INTEGER*))aSyscall[51].pCurrent)
+-
+-  { "ReadFile",                (SYSCALL)ReadFile,                0 },
+-
+-#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \
+-        LPOVERLAPPED))aSyscall[52].pCurrent)
++#define osCharUpperW ((LPWSTR(WINAPI*)(LPWSTR))aSyscall[2].pCurrent)
+ 
+-  { "SetEndOfFile",            (SYSCALL)SetEndOfFile,            0 },
++  { "CloseHandle",             (SYSCALL)CloseHandle,             0 },
+ 
+-#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[53].pCurrent)
++#define osCloseHandle ((BOOL(WINAPI*)(HANDLE))aSyscall[3].pCurrent)
+ 
+-#if !SQLITE_OS_WINRT
+-  { "SetFilePointer",          (SYSCALL)SetFilePointer,          0 },
++#if defined(SQLITE_WIN32_HAS_ANSI)
++  { "CreateFileA",             (SYSCALL)CreateFileA,             0 },
+ #else
+-  { "SetFilePointer",          (SYSCALL)0,                       0 },
++  { "CreateFileA",             (SYSCALL)0,                       0 },
+ #endif
+ 
+-#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \
+-        DWORD))aSyscall[54].pCurrent)
++#define osCreateFileA ((HANDLE(WINAPI*)(LPCSTR,DWORD,DWORD, \
++        LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[4].pCurrent)
+ 
+-#if !SQLITE_OS_WINRT
+-  { "Sleep",                   (SYSCALL)Sleep,                   0 },
++#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
++  { "CreateFileW",             (SYSCALL)CreateFileW,             0 },
+ #else
+-  { "Sleep",                   (SYSCALL)0,                       0 },
++  { "CreateFileW",             (SYSCALL)0,                       0 },
+ #endif
+ 
+-#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[55].pCurrent)
+-
+-  { "SystemTimeToFileTime",    (SYSCALL)SystemTimeToFileTime,    0 },
+-
+-#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \
+-        LPFILETIME))aSyscall[56].pCurrent)
++#define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \
++        LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
+ 
+-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
+-  { "UnlockFile",              (SYSCALL)UnlockFile,              0 },
++#if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
++        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
++  { "CreateFileMappingA",      (SYSCALL)CreateFileMappingA,      0 },
+ #else
+-  { "UnlockFile",              (SYSCALL)0,                       0 },
++  { "CreateFileMappingA",      (SYSCALL)0,                       0 },
+ #endif
+ 
+-#ifndef osUnlockFile
+-#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
+-        DWORD))aSyscall[57].pCurrent)
+-#endif
++#define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
++        DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent)
+ 
+-#if !SQLITE_OS_WINCE
+-  { "UnlockFileEx",            (SYSCALL)UnlockFileEx,            0 },
++#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
++        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
++  { "CreateFileMappingW",      (SYSCALL)CreateFileMappingW,      0 },
+ #else
+-  { "UnlockFileEx",            (SYSCALL)0,                       0 },
++  { "CreateFileMappingW",      (SYSCALL)0,                       0 },
+ #endif
+ 
+-#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
+-        LPOVERLAPPED))aSyscall[58].pCurrent)
++#define osCreateFileMappingW ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
++        DWORD,DWORD,DWORD,LPCWSTR))aSyscall[7].pCurrent)
+ 
+-#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
+-  { "UnmapViewOfFile",         (SYSCALL)UnmapViewOfFile,         0 },
++#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
++  { "CreateMutexW",            (SYSCALL)CreateMutexW,            0 },
+ #else
+-  { "UnmapViewOfFile",         (SYSCALL)0,                       0 },
++  { "CreateMutexW",            (SYSCALL)0,                       0 },
+ #endif
+ 
+-#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[59].pCurrent)
+-
+-  { "WideCharToMultiByte",     (SYSCALL)WideCharToMultiByte,     0 },
+-
+-#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \
+-        LPCSTR,LPBOOL))aSyscall[60].pCurrent)
+-
+-  { "WriteFile",               (SYSCALL)WriteFile,               0 },
+-
+-#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \
+-        LPOVERLAPPED))aSyscall[61].pCurrent)
++#define osCreateMutexW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,BOOL, \
++        LPCWSTR))aSyscall[8].pCurrent)
+ 
+-#if SQLITE_OS_WINRT
+-  { "CreateEventExW",          (SYSCALL)CreateEventExW,          0 },
++#if defined(SQLITE_WIN32_HAS_ANSI)
++  { "DeleteFileA",             (SYSCALL)DeleteFileA,             0 },
+ #else
+-  { "CreateEventExW",          (SYSCALL)0,                       0 },
++  { "DeleteFileA",             (SYSCALL)0,                       0 },
+ #endif
+ 
+-#define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \
+-        DWORD,DWORD))aSyscall[62].pCurrent)
++#define osDeleteFileA ((BOOL(WINAPI*)(LPCSTR))aSyscall[9].pCurrent)
+ 
+-#if !SQLITE_OS_WINRT
+-  { "WaitForSingleObject",     (SYSCALL)WaitForSingleObject,     0 },
++#if defined(SQLITE_WIN32_HAS_WIDE)
++  { "DeleteFileW",             (SYSCALL)DeleteFileW,             0 },
+ #else
+-  { "WaitForSingleObject",     (SYSCALL)0,                       0 },
++  { "DeleteFileW",             (SYSCALL)0,                       0 },
+ #endif
+ 
+-#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
+-        DWORD))aSyscall[63].pCurrent)
++#define osDeleteFileW ((BOOL(WINAPI*)(LPCWSTR))aSyscall[10].pCurrent)
+ 
+-#if !SQLITE_OS_WINCE
+-  { "WaitForSingleObjectEx",   (SYSCALL)WaitForSingleObjectEx,   0 },
++#if SQLITE_OS_WINCE
++  { "FileTimeToLocalFileTime", (SYSCALL)FileTimeToLocalFileTime, 0 },
+ #else
+-  { "WaitForSingleObjectEx",   (SYSCALL)0,                       0 },
++  { "FileTimeToLocalFileTime", (SYSCALL)0,                       0 },
+ #endif
+ 
+-#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
+-        BOOL))aSyscall[64].pCurrent)
++#define osFileTimeToLocalFileTime ((BOOL(WINAPI*)(CONST FILETIME*, \
++        LPFILETIME))aSyscall[11].pCurrent)
+ 
+-#if SQLITE_OS_WINRT
+-  { "SetFilePointerEx",        (SYSCALL)SetFilePointerEx,        0 },
++#if SQLITE_OS_WINCE
++  { "FileTimeToSystemTime",    (SYSCALL)FileTimeToSystemTime,    0 },
+ #else
+-  { "SetFilePointerEx",        (SYSCALL)0,                       0 },
++  { "FileTimeToSystemTime",    (SYSCALL)0,                       0 },
+ #endif
+ 
+-#define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \
+-        PLARGE_INTEGER,DWORD))aSyscall[65].pCurrent)
++#define osFileTimeToSystemTime ((BOOL(WINAPI*)(CONST FILETIME*, \
++        LPSYSTEMTIME))aSyscall[12].pCurrent)
+ 
+-#if SQLITE_OS_WINRT
+-  { "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 },
+-#else
+-  { "GetFileInformationByHandleEx", (SYSCALL)0,                  0 },
+-#endif
++  { "FlushFileBuffers",        (SYSCALL)FlushFileBuffers,        0 },
+ 
+-#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
+-        FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent)
++#define osFlushFileBuffers ((BOOL(WINAPI*)(HANDLE))aSyscall[13].pCurrent)
+ 
+-#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
+-  { "MapViewOfFileFromApp",    (SYSCALL)MapViewOfFileFromApp,    0 },
++#if defined(SQLITE_WIN32_HAS_ANSI)
++  { "FormatMessageA",          (SYSCALL)FormatMessageA,          0 },
+ #else
+-  { "MapViewOfFileFromApp",    (SYSCALL)0,                       0 },
++  { "FormatMessageA",          (SYSCALL)0,                       0 },
+ #endif
+ 
+-#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \
+-        SIZE_T))aSyscall[67].pCurrent)
++#define osFormatMessageA ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPSTR, \
++        DWORD,va_list*))aSyscall[14].pCurrent)
+ 
+-#if SQLITE_OS_WINRT
+-  { "CreateFile2",             (SYSCALL)CreateFile2,             0 },
++#if defined(SQLITE_WIN32_HAS_WIDE)
++  { "FormatMessageW",          (SYSCALL)FormatMessageW,          0 },
+ #else
+-  { "CreateFile2",             (SYSCALL)0,                       0 },
++  { "FormatMessageW",          (SYSCALL)0,                       0 },
+ #endif
+ 
+-#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \
+-        LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[68].pCurrent)
++#define osFormatMessageW ((DWORD(WINAPI*)(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, \
++        DWORD,va_list*))aSyscall[15].pCurrent)
+ 
+-#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION)
+-  { "LoadPackagedLibrary",     (SYSCALL)LoadPackagedLibrary,     0 },
++#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
++  { "FreeLibrary",             (SYSCALL)FreeLibrary,             0 },
+ #else
+-  { "LoadPackagedLibrary",     (SYSCALL)0,                       0 },
++  { "FreeLibrary",             (SYSCALL)0,                       0 },
+ #endif
+ 
+-#define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \
+-        DWORD))aSyscall[69].pCurrent)
++#define osFreeLibrary ((BOOL(WINAPI*)(HMODULE))aSyscall[16].pCurrent)
+ 
+-#if SQLITE_OS_WINRT
+-  { "GetTickCount64",          (SYSCALL)GetTickCount64,          0 },
+-#else
+-  { "GetTickCount64",          (SYSCALL)0,                       0 },
+-#endif
++  { "GetCurrentProcessId",     (SYSCALL)GetCurrentProcessId,     0 },
+ 
+-#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[70].pCurrent)
++#define osGetCurrentProcessId ((DWORD(WINAPI*)(VOID))aSyscall[17].pCurrent)
+ 
+-#if SQLITE_OS_WINRT
+-  { "GetNativeSystemInfo",     (SYSCALL)GetNativeSystemInfo,     0 },
++#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
++  { "GetDiskFreeSpaceA",       (SYSCALL)GetDiskFreeSpaceA,       0 },
+ #else
+-  { "GetNativeSystemInfo",     (SYSCALL)0,                       0 },
++  { "GetDiskFreeSpaceA",       (SYSCALL)0,                       0 },
+ #endif
+ 
+-#define osGetNativeSystemInfo ((VOID(WINAPI*)( \
+-        LPSYSTEM_INFO))aSyscall[71].pCurrent)
++#define osGetDiskFreeSpaceA ((BOOL(WINAPI*)(LPCSTR,LPDWORD,LPDWORD,LPDWORD, \
++        LPDWORD))aSyscall[18].pCurrent)
+ 
+-#if defined(SQLITE_WIN32_HAS_ANSI)
+-  { "OutputDebugStringA",      (SYSCALL)OutputDebugStringA,      0 },
++#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
++  { "GetDiskFreeSpaceW",       (SYSCALL)GetDiskFreeSpaceW,       0 },
+ #else
+-  { "OutputDebugStringA",      (SYSCALL)0,                       0 },
++  { "GetDiskFreeSpaceW",       (SYSCALL)0,                       0 },
+ #endif
+ 
+-#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[72].pCurrent)
++#define osGetDiskFreeSpaceW ((BOOL(WINAPI*)(LPCWSTR,LPDWORD,LPDWORD,LPDWORD, \
++        LPDWORD))aSyscall[19].pCurrent)
+ 
+-#if defined(SQLITE_WIN32_HAS_WIDE)
+-  { "OutputDebugStringW",      (SYSCALL)OutputDebugStringW,      0 },
++#if defined(SQLITE_WIN32_HAS_ANSI)
++  { "GetFileAttributesA",      (SYSCALL)GetFileAttributesA,      0 },
+ #else
+-  { "OutputDebugStringW",      (SYSCALL)0,                       0 },
++  { "GetFileAttributesA",      (SYSCALL)0,                       0 },
+ #endif
+ 
+-#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[73].pCurrent)
+-
+-  { "GetProcessHeap",          (SYSCALL)GetProcessHeap,          0 },
+-
+-#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[74].pCurrent)
++#define osGetFileAttributesA ((DWORD(WINAPI*)(LPCSTR))aSyscall[20].pCurrent)
+ 
+-#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
+-  { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
++#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
++  { "GetFileAttributesW",      (SYSCALL)GetFileAttributesW,      0 },
+ #else
+-  { "CreateFileMappingFromApp", (SYSCALL)0,                      0 },
++  { "GetFileAttributesW",      (SYSCALL)0,                       0 },
+ #endif
+ 
+-#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
+-        LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent)
+-
+-/*
+-** NOTE: On some sub-platforms, the InterlockedCompareExchange "function"
+-**       is really just a macro that uses a compiler intrinsic (e.g. x64).
+-**       So do not try to make this is into a redefinable interface.
+-*/
+-#if defined(InterlockedCompareExchange)
+-  { "InterlockedCompareExchange", (SYSCALL)0,                    0 },
++#define osGetFileAttributesW ((DWORD(WINAPI*)(LPCWSTR))aSyscall[21].pCurrent)
+ 
+-#define osInterlockedCompareExchange InterlockedCompareExchange
++#if defined(SQLITE_WIN32_HAS_WIDE)
++  { "GetFileAttributesExW",    (SYSCALL)GetFileAttributesExW,    0 },
+ #else
+-  { "InterlockedCompareExchange", (SYSCALL)InterlockedCompareExchange, 0 },
++  { "GetFileAttributesExW",    (SYSCALL)0,                       0 },
++#endif
+ 
+-#define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG \
+-        SQLITE_WIN32_VOLATILE*, LONG,LONG))aSyscall[76].pCurrent)
+-#endif /* defined(InterlockedCompareExchange) */
++#define osGetFileAttributesExW ((BOOL(WINAPI*)(LPCWSTR,GET_FILEEX_INFO_LEVELS, \
++        LPVOID))aSyscall[22].pCurrent)
+ 
+-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
+-  { "UuidCreate",               (SYSCALL)UuidCreate,             0 },
++#if !SQLITE_OS_WINRT
++  { "GetFileSize",             (SYSCALL)GetFileSize,             0 },
+ #else
+-  { "UuidCreate",               (SYSCALL)0,                      0 },
++  { "GetFileSize",             (SYSCALL)0,                       0 },
+ #endif
+ 
+-#define osUuidCreate ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[77].pCurrent)
++#define osGetFileSize ((DWORD(WINAPI*)(HANDLE,LPDWORD))aSyscall[23].pCurrent)
+ 
+-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
+-  { "UuidCreateSequential",     (SYSCALL)UuidCreateSequential,   0 },
++#if !SQLITE_OS_WINCE && defined(SQLITE_WIN32_HAS_ANSI)
++  { "GetFullPathNameA",        (SYSCALL)GetFullPathNameA,        0 },
+ #else
+-  { "UuidCreateSequential",     (SYSCALL)0,                      0 },
++  { "GetFullPathNameA",        (SYSCALL)0,                       0 },
+ #endif
+ 
+-#define osUuidCreateSequential \
+-        ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[78].pCurrent)
++#define osGetFullPathNameA ((DWORD(WINAPI*)(LPCSTR,DWORD,LPSTR, \
++        LPSTR*))aSyscall[24].pCurrent)
+ 
+-#if !defined(SQLITE_NO_SYNC) && SQLITE_MAX_MMAP_SIZE>0
+-  { "FlushViewOfFile",          (SYSCALL)FlushViewOfFile,        0 },
++#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
++  { "GetFullPathNameW",        (SYSCALL)GetFullPathNameW,        0 },
+ #else
+-  { "FlushViewOfFile",          (SYSCALL)0,                      0 },
++  { "GetFullPathNameW",        (SYSCALL)0,                       0 },
+ #endif
+ 
+-#define osFlushViewOfFile \
+-        ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent)
++#define osGetFullPathNameW ((DWORD(WINAPI*)(LPCWSTR,DWORD,LPWSTR, \
++        LPWSTR*))aSyscall[25].pCurrent)
+ 
+-}; /* End of the overrideable system calls */
++  { "GetLastError",            (SYSCALL)GetLastError,            0 },
+ 
+-/*
+-** This is the xSetSystemCall() method of sqlite3_vfs for all of the
+-** "win32" VFSes.  Return SQLITE_OK opon successfully updating the
+-** system call pointer, or SQLITE_NOTFOUND if there is no configurable
+-** system call named zName.
+-*/
+-static int winSetSystemCall(
+-  sqlite3_vfs *pNotUsed,        /* The VFS pointer.  Not used */
+-  const char *zName,            /* Name of system call to override */
+-  sqlite3_syscall_ptr pNewFunc  /* Pointer to new system call value */
+-){
+-  unsigned int i;
+-  int rc = SQLITE_NOTFOUND;
++#define osGetLastError ((DWORD(WINAPI*)(VOID))aSyscall[26].pCurrent)
+ 
+-  UNUSED_PARAMETER(pNotUsed);
+-  if( zName==0 ){
+-    /* If no zName is given, restore all system calls to their default
+-    ** settings and return NULL
+-    */
+-    rc = SQLITE_OK;
+-    for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
+-      if( aSyscall[i].pDefault ){
+-        aSyscall[i].pCurrent = aSyscall[i].pDefault;
+-      }
+-    }
+-  }else{
+-    /* If zName is specified, operate on only the one system call
+-    ** specified.
+-    */
+-    for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
+-      if( strcmp(zName, aSyscall[i].zName)==0 ){
+-        if( aSyscall[i].pDefault==0 ){
+-          aSyscall[i].pDefault = aSyscall[i].pCurrent;
+-        }
+-        rc = SQLITE_OK;
+-        if( pNewFunc==0 ) pNewFunc = aSyscall[i].pDefault;
+-        aSyscall[i].pCurrent = pNewFunc;
+-        break;
+-      }
+-    }
+-  }
+-  return rc;
+-}
++#if !defined(SQLITE_OMIT_LOAD_EXTENSION)
++#if SQLITE_OS_WINCE
++  /* The GetProcAddressA() routine is only available on Windows CE. */
++  { "GetProcAddressA",         (SYSCALL)GetProcAddressA,         0 },
++#else
++  /* All other Windows platforms expect GetProcAddress() to take
++  ** an ANSI string regardless of the _UNICODE setting */
++  { "GetProcAddressA",         (SYSCALL)GetProcAddress,          0 },
++#endif
++#else
++  { "GetProcAddressA",         (SYSCALL)0,                       0 },
++#endif
+ 
+-/*
+-** Return the value of a system call.  Return NULL if zName is not a
+-** recognized system call name.  NULL is also returned if the system call
+-** is currently undefined.
+-*/
+-static sqlite3_syscall_ptr winGetSystemCall(
+-  sqlite3_vfs *pNotUsed,
+-  const char *zName
+-){
+-  unsigned int i;
++#define osGetProcAddressA ((FARPROC(WINAPI*)(HMODULE, \
++        LPCSTR))aSyscall[27].pCurrent)
+ 
+-  UNUSED_PARAMETER(pNotUsed);
+-  for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
+-    if( strcmp(zName, aSyscall[i].zName)==0 ) return aSyscall[i].pCurrent;
+-  }
+-  return 0;
+-}
++#if !SQLITE_OS_WINRT
++  { "GetSystemInfo",           (SYSCALL)GetSystemInfo,           0 },
++#else
++  { "GetSystemInfo",           (SYSCALL)0,                       0 },
++#endif
+ 
+-/*
+-** Return the name of the first system call after zName.  If zName==NULL
+-** then return the name of the first system call.  Return NULL if zName
+-** is the last system call or if zName is not the name of a valid
+-** system call.
+-*/
+-static const char *winNextSystemCall(sqlite3_vfs *p, const char *zName){
+-  int i = -1;
++#define osGetSystemInfo ((VOID(WINAPI*)(LPSYSTEM_INFO))aSyscall[28].pCurrent)
+ 
+-  UNUSED_PARAMETER(p);
+-  if( zName ){
+-    for(i=0; i<ArraySize(aSyscall)-1; i++){
+-      if( strcmp(zName, aSyscall[i].zName)==0 ) break;
+-    }
+-  }
+-  for(i++; i<ArraySize(aSyscall); i++){
+-    if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
+-  }
+-  return 0;
+-}
++  { "GetSystemTime",           (SYSCALL)GetSystemTime,           0 },
+ 
+-#ifdef SQLITE_WIN32_MALLOC
+-/*
+-** If a Win32 native heap has been configured, this function will attempt to
+-** compact it.  Upon success, SQLITE_OK will be returned.  Upon failure, one
+-** of SQLITE_NOMEM, SQLITE_ERROR, or SQLITE_NOTFOUND will be returned.  The
+-** "pnLargest" argument, if non-zero, will be used to return the size of the
+-** largest committed free block in the heap, in bytes.
+-*/
+-SQLITE_API int SQLITE_STDCALL sqlite3_win32_compact_heap(LPUINT pnLargest){
+-  int rc = SQLITE_OK;
+-  UINT nLargest = 0;
+-  HANDLE hHeap;
++#define osGetSystemTime ((VOID(WINAPI*)(LPSYSTEMTIME))aSyscall[29].pCurrent)
+ 
+-  winMemAssertMagic();
+-  hHeap = winMemGetHeap();
+-  assert( hHeap!=0 );
+-  assert( hHeap!=INVALID_HANDLE_VALUE );
+-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
+-  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
+-#endif
+-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
+-  if( (nLargest=osHeapCompact(hHeap, SQLITE_WIN32_HEAP_FLAGS))==0 ){
+-    DWORD lastErrno = osGetLastError();
+-    if( lastErrno==NO_ERROR ){
+-      sqlite3_log(SQLITE_NOMEM, "failed to HeapCompact (no space), heap=%p",
+-                  (void*)hHeap);
+-      rc = SQLITE_NOMEM;
+-    }else{
+-      sqlite3_log(SQLITE_ERROR, "failed to HeapCompact (%lu), heap=%p",
+-                  osGetLastError(), (void*)hHeap);
+-      rc = SQLITE_ERROR;
+-    }
+-  }
++#if !SQLITE_OS_WINCE
++  { "GetSystemTimeAsFileTime", (SYSCALL)GetSystemTimeAsFileTime, 0 },
+ #else
+-  sqlite3_log(SQLITE_NOTFOUND, "failed to HeapCompact, heap=%p",
+-              (void*)hHeap);
+-  rc = SQLITE_NOTFOUND;
++  { "GetSystemTimeAsFileTime", (SYSCALL)0,                       0 },
+ #endif
+-  if( pnLargest ) *pnLargest = nLargest;
+-  return rc;
+-}
+-
+-/*
+-** If a Win32 native heap has been configured, this function will attempt to
+-** destroy and recreate it.  If the Win32 native heap is not isolated and/or
+-** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will
+-** be returned and no changes will be made to the Win32 native heap.
+-*/
+-SQLITE_API int SQLITE_STDCALL sqlite3_win32_reset_heap(){
+-  int rc;
+-  MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
+-  MUTEX_LOGIC( sqlite3_mutex *pMem; )    /* The memsys static mutex */
+-  MUTEX_LOGIC( pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); )
+-  MUTEX_LOGIC( pMem = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); )
+-  sqlite3_mutex_enter(pMaster);
+-  sqlite3_mutex_enter(pMem);
+-  winMemAssertMagic();
+-  if( winMemGetHeap()!=NULL && winMemGetOwned() && sqlite3_memory_used()==0 ){
+-    /*
+-    ** At this point, there should be no outstanding memory allocations on
+-    ** the heap.  Also, since both the master and memsys locks are currently
+-    ** being held by us, no other function (i.e. from another thread) should
+-    ** be able to even access the heap.  Attempt to destroy and recreate our
+-    ** isolated Win32 native heap now.
+-    */
+-    assert( winMemGetHeap()!=NULL );
+-    assert( winMemGetOwned() );
+-    assert( sqlite3_memory_used()==0 );
+-    winMemShutdown(winMemGetDataPtr());
+-    assert( winMemGetHeap()==NULL );
+-    assert( !winMemGetOwned() );
+-    assert( sqlite3_memory_used()==0 );
+-    rc = winMemInit(winMemGetDataPtr());
+-    assert( rc!=SQLITE_OK || winMemGetHeap()!=NULL );
+-    assert( rc!=SQLITE_OK || winMemGetOwned() );
+-    assert( rc!=SQLITE_OK || sqlite3_memory_used()==0 );
+-  }else{
+-    /*
+-    ** The Win32 native heap cannot be modified because it may be in use.
+-    */
+-    rc = SQLITE_BUSY;
+-  }
+-  sqlite3_mutex_leave(pMem);
+-  sqlite3_mutex_leave(pMaster);
+-  return rc;
+-}
+-#endif /* SQLITE_WIN32_MALLOC */
+ 
+-/*
+-** This function outputs the specified (ANSI) string to the Win32 debugger
+-** (if available).
+-*/
++#define osGetSystemTimeAsFileTime ((VOID(WINAPI*)( \
++        LPFILETIME))aSyscall[30].pCurrent)
+ 
+-SQLITE_API void SQLITE_STDCALL sqlite3_win32_write_debug(const char *zBuf, int nBuf){
+-  char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE];
+-  int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */
+-  if( nMin<-1 ) nMin = -1; /* all negative values become -1. */
+-  assert( nMin==-1 || nMin==0 || nMin<SQLITE_WIN32_DBG_BUF_SIZE );
+ #if defined(SQLITE_WIN32_HAS_ANSI)
+-  if( nMin>0 ){
+-    memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
+-    memcpy(zDbgBuf, zBuf, nMin);
+-    osOutputDebugStringA(zDbgBuf);
+-  }else{
+-    osOutputDebugStringA(zBuf);
+-  }
+-#elif defined(SQLITE_WIN32_HAS_WIDE)
+-  memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
+-  if ( osMultiByteToWideChar(
+-          osAreFileApisANSI() ? CP_ACP : CP_OEMCP, 0, zBuf,
+-          nMin, (LPWSTR)zDbgBuf, SQLITE_WIN32_DBG_BUF_SIZE/sizeof(WCHAR))<=0 ){
+-    return;
+-  }
+-  osOutputDebugStringW((LPCWSTR)zDbgBuf);
++  { "GetTempPathA",            (SYSCALL)GetTempPathA,            0 },
+ #else
+-  if( nMin>0 ){
+-    memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
+-    memcpy(zDbgBuf, zBuf, nMin);
+-    fprintf(stderr, "%s", zDbgBuf);
+-  }else{
+-    fprintf(stderr, "%s", zBuf);
+-  }
++  { "GetTempPathA",            (SYSCALL)0,                       0 },
++#endif
++
++#define osGetTempPathA ((DWORD(WINAPI*)(DWORD,LPSTR))aSyscall[31].pCurrent)
++
++#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
++  { "GetTempPathW",            (SYSCALL)GetTempPathW,            0 },
++#else
++  { "GetTempPathW",            (SYSCALL)0,                       0 },
+ #endif
+-}
+ 
+-/*
+-** The following routine suspends the current thread for at least ms
+-** milliseconds.  This is equivalent to the Win32 Sleep() interface.
+-*/
+-#if SQLITE_OS_WINRT
+-static HANDLE sleepObj = NULL;
++#define osGetTempPathW ((DWORD(WINAPI*)(DWORD,LPWSTR))aSyscall[32].pCurrent)
++
++#if !SQLITE_OS_WINRT
++  { "GetTickCount",            (SYSCALL)GetTickCount,            0 },
++#else
++  { "GetTickCount",            (SYSCALL)0,                       0 },
+ #endif
+ 
+-SQLITE_API void SQLITE_STDCALL sqlite3_win32_sleep(DWORD milliseconds){
+-#if SQLITE_OS_WINRT
+-  if ( sleepObj==NULL ){
+-    sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET,
+-                                SYNCHRONIZE);
+-  }
+-  assert( sleepObj!=NULL );
+-  osWaitForSingleObjectEx(sleepObj, milliseconds, FALSE);
++#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent)
++
++#if defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_GETVERSIONEX) && \
++        SQLITE_WIN32_GETVERSIONEX
++  { "GetVersionExA",           (SYSCALL)GetVersionExA,           0 },
+ #else
+-  osSleep(milliseconds);
++  { "GetVersionExA",           (SYSCALL)0,                       0 },
+ #endif
+-}
+ 
+-#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \
+-        SQLITE_THREADSAFE>0
+-SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){
+-  DWORD rc;
+-  while( (rc = osWaitForSingleObjectEx(hObject, INFINITE,
+-                                       TRUE))==WAIT_IO_COMPLETION ){}
+-  return rc;
+-}
++#define osGetVersionExA ((BOOL(WINAPI*)( \
++        LPOSVERSIONINFOA))aSyscall[34].pCurrent)
++
++#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
++        defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX
++  { "GetVersionExW",           (SYSCALL)GetVersionExW,           0 },
++#else
++  { "GetVersionExW",           (SYSCALL)0,                       0 },
+ #endif
+ 
+-/*
+-** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
+-** or WinCE.  Return false (zero) for Win95, Win98, or WinME.
+-**
+-** Here is an interesting observation:  Win95, Win98, and WinME lack
+-** the LockFileEx() API.  But we can still statically link against that
+-** API as long as we don't call it when running Win95/98/ME.  A call to
+-** this routine is used to determine if the host is Win95/98/ME or
+-** WinNT/2K/XP so that we will know whether or not we can safely call
+-** the LockFileEx() API.
+-*/
++#define osGetVersionExW ((BOOL(WINAPI*)( \
++        LPOSVERSIONINFOW))aSyscall[35].pCurrent)
+ 
+-#if !defined(SQLITE_WIN32_GETVERSIONEX) || !SQLITE_WIN32_GETVERSIONEX
+-# define osIsNT()  (1)
+-#elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI)
+-# define osIsNT()  (1)
+-#elif !defined(SQLITE_WIN32_HAS_WIDE)
+-# define osIsNT()  (0)
++  { "HeapAlloc",               (SYSCALL)HeapAlloc,               0 },
++
++#define osHeapAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD, \
++        SIZE_T))aSyscall[36].pCurrent)
++
++#if !SQLITE_OS_WINRT
++  { "HeapCreate",              (SYSCALL)HeapCreate,              0 },
+ #else
+-# define osIsNT()  ((sqlite3_os_type==2) || sqlite3_win32_is_nt())
++  { "HeapCreate",              (SYSCALL)0,                       0 },
+ #endif
+ 
+-/*
+-** This function determines if the machine is running a version of Windows
+-** based on the NT kernel.
+-*/
+-SQLITE_API int SQLITE_STDCALL sqlite3_win32_is_nt(void){
+-#if SQLITE_OS_WINRT
+-  /*
+-  ** NOTE: The WinRT sub-platform is always assumed to be based on the NT
+-  **       kernel.
+-  */
+-  return 1;
+-#elif defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX
+-  if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){
+-#if defined(SQLITE_WIN32_HAS_ANSI)
+-    OSVERSIONINFOA sInfo;
+-    sInfo.dwOSVersionInfoSize = sizeof(sInfo);
+-    osGetVersionExA(&sInfo);
+-    osInterlockedCompareExchange(&sqlite3_os_type,
+-        (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0);
+-#elif defined(SQLITE_WIN32_HAS_WIDE)
+-    OSVERSIONINFOW sInfo;
+-    sInfo.dwOSVersionInfoSize = sizeof(sInfo);
+-    osGetVersionExW(&sInfo);
+-    osInterlockedCompareExchange(&sqlite3_os_type,
+-        (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0);
++#define osHeapCreate ((HANDLE(WINAPI*)(DWORD,SIZE_T, \
++        SIZE_T))aSyscall[37].pCurrent)
++
++#if !SQLITE_OS_WINRT
++  { "HeapDestroy",             (SYSCALL)HeapDestroy,             0 },
++#else
++  { "HeapDestroy",             (SYSCALL)0,                       0 },
+ #endif
+-  }
+-  return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2;
+-#elif SQLITE_TEST
+-  return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2;
++
++#define osHeapDestroy ((BOOL(WINAPI*)(HANDLE))aSyscall[38].pCurrent)
++
++  { "HeapFree",                (SYSCALL)HeapFree,                0 },
++
++#define osHeapFree ((BOOL(WINAPI*)(HANDLE,DWORD,LPVOID))aSyscall[39].pCurrent)
++
++  { "HeapReAlloc",             (SYSCALL)HeapReAlloc,             0 },
++
++#define osHeapReAlloc ((LPVOID(WINAPI*)(HANDLE,DWORD,LPVOID, \
++        SIZE_T))aSyscall[40].pCurrent)
++
++  { "HeapSize",                (SYSCALL)HeapSize,                0 },
++
++#define osHeapSize ((SIZE_T(WINAPI*)(HANDLE,DWORD, \
++        LPCVOID))aSyscall[41].pCurrent)
++
++#if !SQLITE_OS_WINRT
++  { "HeapValidate",            (SYSCALL)HeapValidate,            0 },
+ #else
+-  /*
+-  ** NOTE: All sub-platforms where the GetVersionEx[AW] functions are
+-  **       deprecated are always assumed to be based on the NT kernel.
+-  */
+-  return 1;
++  { "HeapValidate",            (SYSCALL)0,                       0 },
+ #endif
+-}
+ 
+-#ifdef SQLITE_WIN32_MALLOC
+-/*
+-** Allocate nBytes of memory.
+-*/
+-static void *winMemMalloc(int nBytes){
+-  HANDLE hHeap;
+-  void *p;
++#define osHeapValidate ((BOOL(WINAPI*)(HANDLE,DWORD, \
++        LPCVOID))aSyscall[42].pCurrent)
+ 
+-  winMemAssertMagic();
+-  hHeap = winMemGetHeap();
+-  assert( hHeap!=0 );
+-  assert( hHeap!=INVALID_HANDLE_VALUE );
+-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
+-  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
++#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
++  { "HeapCompact",             (SYSCALL)HeapCompact,             0 },
++#else
++  { "HeapCompact",             (SYSCALL)0,                       0 },
+ #endif
+-  assert( nBytes>=0 );
+-  p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
+-  if( !p ){
+-    sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%lu), heap=%p",
+-                nBytes, osGetLastError(), (void*)hHeap);
+-  }
+-  return p;
+-}
+ 
+-/*
+-** Free memory.
+-*/
+-static void winMemFree(void *pPrior){
+-  HANDLE hHeap;
++#define osHeapCompact ((UINT(WINAPI*)(HANDLE,DWORD))aSyscall[43].pCurrent)
+ 
+-  winMemAssertMagic();
+-  hHeap = winMemGetHeap();
+-  assert( hHeap!=0 );
+-  assert( hHeap!=INVALID_HANDLE_VALUE );
+-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
+-  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
++#if defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
++  { "LoadLibraryA",            (SYSCALL)LoadLibraryA,            0 },
++#else
++  { "LoadLibraryA",            (SYSCALL)0,                       0 },
+ #endif
+-  if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */
+-  if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){
+-    sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%lu), heap=%p",
+-                pPrior, osGetLastError(), (void*)hHeap);
+-  }
+-}
+ 
+-/*
+-** Change the size of an existing memory allocation
+-*/
+-static void *winMemRealloc(void *pPrior, int nBytes){
+-  HANDLE hHeap;
+-  void *p;
++#define osLoadLibraryA ((HMODULE(WINAPI*)(LPCSTR))aSyscall[44].pCurrent)
+ 
+-  winMemAssertMagic();
+-  hHeap = winMemGetHeap();
+-  assert( hHeap!=0 );
+-  assert( hHeap!=INVALID_HANDLE_VALUE );
+-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
+-  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
++#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
++        !defined(SQLITE_OMIT_LOAD_EXTENSION)
++  { "LoadLibraryW",            (SYSCALL)LoadLibraryW,            0 },
++#else
++  { "LoadLibraryW",            (SYSCALL)0,                       0 },
+ #endif
+-  assert( nBytes>=0 );
+-  if( !pPrior ){
+-    p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
+-  }else{
+-    p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes);
+-  }
+-  if( !p ){
+-    sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%lu), heap=%p",
+-                pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, osGetLastError(),
+-                (void*)hHeap);
+-  }
+-  return p;
+-}
+ 
+-/*
+-** Return the size of an outstanding allocation, in bytes.
+-*/
+-static int winMemSize(void *p){
+-  HANDLE hHeap;
+-  SIZE_T n;
++#define osLoadLibraryW ((HMODULE(WINAPI*)(LPCWSTR))aSyscall[45].pCurrent)
+ 
+-  winMemAssertMagic();
+-  hHeap = winMemGetHeap();
+-  assert( hHeap!=0 );
+-  assert( hHeap!=INVALID_HANDLE_VALUE );
+-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
+-  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, p) );
++#if !SQLITE_OS_WINRT
++  { "LocalFree",               (SYSCALL)LocalFree,               0 },
++#else
++  { "LocalFree",               (SYSCALL)0,                       0 },
+ #endif
+-  if( !p ) return 0;
+-  n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p);
+-  if( n==(SIZE_T)-1 ){
+-    sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%lu), heap=%p",
+-                p, osGetLastError(), (void*)hHeap);
+-    return 0;
+-  }
+-  return (int)n;
+-}
+ 
+-/*
+-** Round up a request size to the next valid allocation size.
+-*/
+-static int winMemRoundup(int n){
+-  return n;
+-}
++#define osLocalFree ((HLOCAL(WINAPI*)(HLOCAL))aSyscall[46].pCurrent)
+ 
+-/*
+-** Initialize this module.
+-*/
+-static int winMemInit(void *pAppData){
+-  winMemData *pWinMemData = (winMemData *)pAppData;
++#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
++  { "LockFile",                (SYSCALL)LockFile,                0 },
++#else
++  { "LockFile",                (SYSCALL)0,                       0 },
++#endif
+ 
+-  if( !pWinMemData ) return SQLITE_ERROR;
+-  assert( pWinMemData->magic1==WINMEM_MAGIC1 );
+-  assert( pWinMemData->magic2==WINMEM_MAGIC2 );
++#ifndef osLockFile
++#define osLockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
++        DWORD))aSyscall[47].pCurrent)
++#endif
+ 
+-#if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE
+-  if( !pWinMemData->hHeap ){
+-    DWORD dwInitialSize = SQLITE_WIN32_HEAP_INIT_SIZE;
+-    DWORD dwMaximumSize = (DWORD)sqlite3GlobalConfig.nHeap;
+-    if( dwMaximumSize==0 ){
+-      dwMaximumSize = SQLITE_WIN32_HEAP_MAX_SIZE;
+-    }else if( dwInitialSize>dwMaximumSize ){
+-      dwInitialSize = dwMaximumSize;
+-    }
+-    pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS,
+-                                      dwInitialSize, dwMaximumSize);
+-    if( !pWinMemData->hHeap ){
+-      sqlite3_log(SQLITE_NOMEM,
+-          "failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu",
+-          osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize,
+-          dwMaximumSize);
+-      return SQLITE_NOMEM;
+-    }
+-    pWinMemData->bOwned = TRUE;
+-    assert( pWinMemData->bOwned );
+-  }
++#if !SQLITE_OS_WINCE
++  { "LockFileEx",              (SYSCALL)LockFileEx,              0 },
+ #else
+-  pWinMemData->hHeap = osGetProcessHeap();
+-  if( !pWinMemData->hHeap ){
+-    sqlite3_log(SQLITE_NOMEM,
+-        "failed to GetProcessHeap (%lu)", osGetLastError());
+-    return SQLITE_NOMEM;
+-  }
+-  pWinMemData->bOwned = FALSE;
+-  assert( !pWinMemData->bOwned );
++  { "LockFileEx",              (SYSCALL)0,                       0 },
+ #endif
+-  assert( pWinMemData->hHeap!=0 );
+-  assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
+-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
+-  assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
++
++#ifndef osLockFileEx
++#define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \
++        LPOVERLAPPED))aSyscall[48].pCurrent)
+ #endif
+-  return SQLITE_OK;
+-}
+ 
+-/*
+-** Deinitialize this module.
+-*/
+-static void winMemShutdown(void *pAppData){
+-  winMemData *pWinMemData = (winMemData *)pAppData;
++#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && \
++        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
++  { "MapViewOfFile",           (SYSCALL)MapViewOfFile,           0 },
++#else
++  { "MapViewOfFile",           (SYSCALL)0,                       0 },
++#endif
+ 
+-  if( !pWinMemData ) return;
+-  assert( pWinMemData->magic1==WINMEM_MAGIC1 );
+-  assert( pWinMemData->magic2==WINMEM_MAGIC2 );
++#define osMapViewOfFile ((LPVOID(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
++        SIZE_T))aSyscall[49].pCurrent)
+ 
+-  if( pWinMemData->hHeap ){
+-    assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
+-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
+-    assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
++  { "MultiByteToWideChar",     (SYSCALL)MultiByteToWideChar,     0 },
++
++#define osMultiByteToWideChar ((int(WINAPI*)(UINT,DWORD,LPCSTR,int,LPWSTR, \
++        int))aSyscall[50].pCurrent)
++
++  { "QueryPerformanceCounter", (SYSCALL)QueryPerformanceCounter, 0 },
++
++#define osQueryPerformanceCounter ((BOOL(WINAPI*)( \
++        LARGE_INTEGER*))aSyscall[51].pCurrent)
++
++  { "ReadFile",                (SYSCALL)ReadFile,                0 },
++
++#define osReadFile ((BOOL(WINAPI*)(HANDLE,LPVOID,DWORD,LPDWORD, \
++        LPOVERLAPPED))aSyscall[52].pCurrent)
++
++  { "SetEndOfFile",            (SYSCALL)SetEndOfFile,            0 },
++
++#define osSetEndOfFile ((BOOL(WINAPI*)(HANDLE))aSyscall[53].pCurrent)
++
++#if !SQLITE_OS_WINRT
++  { "SetFilePointer",          (SYSCALL)SetFilePointer,          0 },
++#else
++  { "SetFilePointer",          (SYSCALL)0,                       0 },
+ #endif
+-    if( pWinMemData->bOwned ){
+-      if( !osHeapDestroy(pWinMemData->hHeap) ){
+-        sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%lu), heap=%p",
+-                    osGetLastError(), (void*)pWinMemData->hHeap);
+-      }
+-      pWinMemData->bOwned = FALSE;
+-    }
+-    pWinMemData->hHeap = NULL;
+-  }
+-}
+ 
+-/*
+-** Populate the low-level memory allocation function pointers in
+-** sqlite3GlobalConfig.m with pointers to the routines in this file. The
+-** arguments specify the block of memory to manage.
+-**
+-** This routine is only called by sqlite3_config(), and therefore
+-** is not required to be threadsafe (it is not).
+-*/
+-SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void){
+-  static const sqlite3_mem_methods winMemMethods = {
+-    winMemMalloc,
+-    winMemFree,
+-    winMemRealloc,
+-    winMemSize,
+-    winMemRoundup,
+-    winMemInit,
+-    winMemShutdown,
+-    &win_mem_data
+-  };
+-  return &winMemMethods;
+-}
++#define osSetFilePointer ((DWORD(WINAPI*)(HANDLE,LONG,PLONG, \
++        DWORD))aSyscall[54].pCurrent)
+ 
+-SQLITE_PRIVATE void sqlite3MemSetDefault(void){
+-  sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetWin32());
+-}
+-#endif /* SQLITE_WIN32_MALLOC */
++#if !SQLITE_OS_WINRT
++  { "Sleep",                   (SYSCALL)Sleep,                   0 },
++#else
++  { "Sleep",                   (SYSCALL)0,                       0 },
++#endif
+ 
+-/*
+-** Convert a UTF-8 string to Microsoft Unicode (UTF-16?).
+-**
+-** Space to hold the returned string is obtained from malloc.
+-*/
+-static LPWSTR winUtf8ToUnicode(const char *zFilename){
+-  int nChar;
+-  LPWSTR zWideFilename;
++#define osSleep ((VOID(WINAPI*)(DWORD))aSyscall[55].pCurrent)
+ 
+-  nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
+-  if( nChar==0 ){
+-    return 0;
+-  }
+-  zWideFilename = sqlite3MallocZero( nChar*sizeof(zWideFilename[0]) );
+-  if( zWideFilename==0 ){
+-    return 0;
+-  }
+-  nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename,
+-                                nChar);
+-  if( nChar==0 ){
+-    sqlite3_free(zWideFilename);
+-    zWideFilename = 0;
+-  }
+-  return zWideFilename;
+-}
++  { "SystemTimeToFileTime",    (SYSCALL)SystemTimeToFileTime,    0 },
+ 
+-/*
+-** Convert Microsoft Unicode to UTF-8.  Space to hold the returned string is
+-** obtained from sqlite3_malloc().
+-*/
+-static char *winUnicodeToUtf8(LPCWSTR zWideFilename){
+-  int nByte;
+-  char *zFilename;
++#define osSystemTimeToFileTime ((BOOL(WINAPI*)(CONST SYSTEMTIME*, \
++        LPFILETIME))aSyscall[56].pCurrent)
+ 
+-  nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
+-  if( nByte == 0 ){
+-    return 0;
+-  }
+-  zFilename = sqlite3MallocZero( nByte );
+-  if( zFilename==0 ){
+-    return 0;
+-  }
+-  nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
+-                                0, 0);
+-  if( nByte == 0 ){
+-    sqlite3_free(zFilename);
+-    zFilename = 0;
+-  }
+-  return zFilename;
+-}
++#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
++  { "UnlockFile",              (SYSCALL)UnlockFile,              0 },
++#else
++  { "UnlockFile",              (SYSCALL)0,                       0 },
++#endif
+ 
+-/*
+-** Convert an ANSI string to Microsoft Unicode, based on the
+-** current codepage settings for file apis.
+-**
+-** Space to hold the returned string is obtained
+-** from sqlite3_malloc.
+-*/
+-static LPWSTR winMbcsToUnicode(const char *zFilename){
+-  int nByte;
+-  LPWSTR zMbcsFilename;
+-  int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
++#ifndef osUnlockFile
++#define osUnlockFile ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
++        DWORD))aSyscall[57].pCurrent)
++#endif
+ 
+-  nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL,
+-                                0)*sizeof(WCHAR);
+-  if( nByte==0 ){
+-    return 0;
+-  }
+-  zMbcsFilename = sqlite3MallocZero( nByte*sizeof(zMbcsFilename[0]) );
+-  if( zMbcsFilename==0 ){
+-    return 0;
+-  }
+-  nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename,
+-                                nByte);
+-  if( nByte==0 ){
+-    sqlite3_free(zMbcsFilename);
+-    zMbcsFilename = 0;
+-  }
+-  return zMbcsFilename;
+-}
++#if !SQLITE_OS_WINCE
++  { "UnlockFileEx",            (SYSCALL)UnlockFileEx,            0 },
++#else
++  { "UnlockFileEx",            (SYSCALL)0,                       0 },
++#endif
+ 
+-/*
+-** Convert Microsoft Unicode to multi-byte character string, based on the
+-** user's ANSI codepage.
+-**
+-** Space to hold the returned string is obtained from
+-** sqlite3_malloc().
+-*/
+-static char *winUnicodeToMbcs(LPCWSTR zWideFilename){
+-  int nByte;
+-  char *zFilename;
+-  int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
++#define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \
++        LPOVERLAPPED))aSyscall[58].pCurrent)
++
++#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
++  { "UnmapViewOfFile",         (SYSCALL)UnmapViewOfFile,         0 },
++#else
++  { "UnmapViewOfFile",         (SYSCALL)0,                       0 },
++#endif
++
++#define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[59].pCurrent)
++
++  { "WideCharToMultiByte",     (SYSCALL)WideCharToMultiByte,     0 },
+ 
+-  nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
+-  if( nByte == 0 ){
+-    return 0;
+-  }
+-  zFilename = sqlite3MallocZero( nByte );
+-  if( zFilename==0 ){
+-    return 0;
+-  }
+-  nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename,
+-                                nByte, 0, 0);
+-  if( nByte == 0 ){
+-    sqlite3_free(zFilename);
+-    zFilename = 0;
+-  }
+-  return zFilename;
+-}
++#define osWideCharToMultiByte ((int(WINAPI*)(UINT,DWORD,LPCWSTR,int,LPSTR,int, \
++        LPCSTR,LPBOOL))aSyscall[60].pCurrent)
+ 
+-/*
+-** Convert multibyte character string to UTF-8.  Space to hold the
+-** returned string is obtained from sqlite3_malloc().
+-*/
+-SQLITE_API char *SQLITE_STDCALL sqlite3_win32_mbcs_to_utf8(const char *zFilename){
+-  char *zFilenameUtf8;
+-  LPWSTR zTmpWide;
++  { "WriteFile",               (SYSCALL)WriteFile,               0 },
+ 
+-  zTmpWide = winMbcsToUnicode(zFilename);
+-  if( zTmpWide==0 ){
+-    return 0;
+-  }
+-  zFilenameUtf8 = winUnicodeToUtf8(zTmpWide);
+-  sqlite3_free(zTmpWide);
+-  return zFilenameUtf8;
+-}
++#define osWriteFile ((BOOL(WINAPI*)(HANDLE,LPCVOID,DWORD,LPDWORD, \
++        LPOVERLAPPED))aSyscall[61].pCurrent)
+ 
+-/*
+-** Convert UTF-8 to multibyte character string.  Space to hold the
+-** returned string is obtained from sqlite3_malloc().
+-*/
+-SQLITE_API char *SQLITE_STDCALL sqlite3_win32_utf8_to_mbcs(const char *zFilename){
+-  char *zFilenameMbcs;
+-  LPWSTR zTmpWide;
++#if SQLITE_OS_WINRT
++  { "CreateEventExW",          (SYSCALL)CreateEventExW,          0 },
++#else
++  { "CreateEventExW",          (SYSCALL)0,                       0 },
++#endif
+ 
+-  zTmpWide = winUtf8ToUnicode(zFilename);
+-  if( zTmpWide==0 ){
+-    return 0;
+-  }
+-  zFilenameMbcs = winUnicodeToMbcs(zTmpWide);
+-  sqlite3_free(zTmpWide);
+-  return zFilenameMbcs;
+-}
++#define osCreateEventExW ((HANDLE(WINAPI*)(LPSECURITY_ATTRIBUTES,LPCWSTR, \
++        DWORD,DWORD))aSyscall[62].pCurrent)
+ 
+-/*
+-** This function sets the data directory or the temporary directory based on
+-** the provided arguments.  The type argument must be 1 in order to set the
+-** data directory or 2 in order to set the temporary directory.  The zValue
+-** argument is the name of the directory to use.  The return value will be
+-** SQLITE_OK if successful.
+-*/
+-SQLITE_API int SQLITE_STDCALL sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
+-  char **ppDirectory = 0;
+-#ifndef SQLITE_OMIT_AUTOINIT
+-  int rc = sqlite3_initialize();
+-  if( rc ) return rc;
++#if !SQLITE_OS_WINRT
++  { "WaitForSingleObject",     (SYSCALL)WaitForSingleObject,     0 },
++#else
++  { "WaitForSingleObject",     (SYSCALL)0,                       0 },
+ #endif
+-  if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){
+-    ppDirectory = &sqlite3_data_directory;
+-  }else if( type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE ){
+-    ppDirectory = &sqlite3_temp_directory;
+-  }
+-  assert( !ppDirectory || type==SQLITE_WIN32_DATA_DIRECTORY_TYPE
+-          || type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE
+-  );
+-  assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) );
+-  if( ppDirectory ){
+-    char *zValueUtf8 = 0;
+-    if( zValue && zValue[0] ){
+-      zValueUtf8 = winUnicodeToUtf8(zValue);
+-      if ( zValueUtf8==0 ){
+-        return SQLITE_NOMEM;
+-      }
+-    }
+-    sqlite3_free(*ppDirectory);
+-    *ppDirectory = zValueUtf8;
+-    return SQLITE_OK;
+-  }
+-  return SQLITE_ERROR;
+-}
+ 
+-/*
+-** The return value of winGetLastErrorMsg
+-** is zero if the error message fits in the buffer, or non-zero
+-** otherwise (if the message was truncated).
+-*/
+-static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
+-  /* FormatMessage returns 0 on failure.  Otherwise it
+-  ** returns the number of TCHARs written to the output
+-  ** buffer, excluding the terminating null char.
+-  */
+-  DWORD dwLen = 0;
+-  char *zOut = 0;
++#define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \
++        DWORD))aSyscall[63].pCurrent)
++
++#if !SQLITE_OS_WINCE
++  { "WaitForSingleObjectEx",   (SYSCALL)WaitForSingleObjectEx,   0 },
++#else
++  { "WaitForSingleObjectEx",   (SYSCALL)0,                       0 },
++#endif
++
++#define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \
++        BOOL))aSyscall[64].pCurrent)
+ 
+-  if( osIsNT() ){
+ #if SQLITE_OS_WINRT
+-    WCHAR zTempWide[SQLITE_WIN32_MAX_ERRMSG_CHARS+1];
+-    dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
+-                             FORMAT_MESSAGE_IGNORE_INSERTS,
+-                             NULL,
+-                             lastErrno,
+-                             0,
+-                             zTempWide,
+-                             SQLITE_WIN32_MAX_ERRMSG_CHARS,
+-                             0);
++  { "SetFilePointerEx",        (SYSCALL)SetFilePointerEx,        0 },
+ #else
+-    LPWSTR zTempWide = NULL;
+-    dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+-                             FORMAT_MESSAGE_FROM_SYSTEM |
+-                             FORMAT_MESSAGE_IGNORE_INSERTS,
+-                             NULL,
+-                             lastErrno,
+-                             0,
+-                             (LPWSTR) &zTempWide,
+-                             0,
+-                             0);
++  { "SetFilePointerEx",        (SYSCALL)0,                       0 },
+ #endif
+-    if( dwLen > 0 ){
+-      /* allocate a buffer and convert to UTF8 */
+-      sqlite3BeginBenignMalloc();
+-      zOut = winUnicodeToUtf8(zTempWide);
+-      sqlite3EndBenignMalloc();
+-#if !SQLITE_OS_WINRT
+-      /* free the system buffer allocated by FormatMessage */
+-      osLocalFree(zTempWide);
++
++#define osSetFilePointerEx ((BOOL(WINAPI*)(HANDLE,LARGE_INTEGER, \
++        PLARGE_INTEGER,DWORD))aSyscall[65].pCurrent)
++
++#if SQLITE_OS_WINRT
++  { "GetFileInformationByHandleEx", (SYSCALL)GetFileInformationByHandleEx, 0 },
++#else
++  { "GetFileInformationByHandleEx", (SYSCALL)0,                  0 },
+ #endif
+-    }
+-  }
+-#ifdef SQLITE_WIN32_HAS_ANSI
+-  else{
+-    char *zTemp = NULL;
+-    dwLen = osFormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+-                             FORMAT_MESSAGE_FROM_SYSTEM |
+-                             FORMAT_MESSAGE_IGNORE_INSERTS,
+-                             NULL,
+-                             lastErrno,
+-                             0,
+-                             (LPSTR) &zTemp,
+-                             0,
+-                             0);
+-    if( dwLen > 0 ){
+-      /* allocate a buffer and convert to UTF8 */
+-      sqlite3BeginBenignMalloc();
+-      zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
+-      sqlite3EndBenignMalloc();
+-      /* free the system buffer allocated by FormatMessage */
+-      osLocalFree(zTemp);
+-    }
+-  }
++
++#define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \
++        FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[66].pCurrent)
++
++#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
++  { "MapViewOfFileFromApp",    (SYSCALL)MapViewOfFileFromApp,    0 },
++#else
++  { "MapViewOfFileFromApp",    (SYSCALL)0,                       0 },
+ #endif
+-  if( 0 == dwLen ){
+-    sqlite3_snprintf(nBuf, zBuf, "OsError 0x%lx (%lu)", lastErrno, lastErrno);
+-  }else{
+-    /* copy a maximum of nBuf chars to output buffer */
+-    sqlite3_snprintf(nBuf, zBuf, "%s", zOut);
+-    /* free the UTF8 buffer */
+-    sqlite3_free(zOut);
+-  }
+-  return 0;
+-}
+ 
+-/*
+-**
+-** This function - winLogErrorAtLine() - is only ever called via the macro
+-** winLogError().
+-**
+-** This routine is invoked after an error occurs in an OS function.
+-** It logs a message using sqlite3_log() containing the current value of
+-** error code and, if possible, the human-readable equivalent from
+-** FormatMessage.
+-**
+-** The first argument passed to the macro should be the error code that
+-** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN).
+-** The two subsequent arguments should be the name of the OS function that
+-** failed and the associated file-system path, if any.
+-*/
+-#define winLogError(a,b,c,d)   winLogErrorAtLine(a,b,c,d,__LINE__)
+-static int winLogErrorAtLine(
+-  int errcode,                    /* SQLite error code */
+-  DWORD lastErrno,                /* Win32 last error */
+-  const char *zFunc,              /* Name of OS function that failed */
+-  const char *zPath,              /* File path associated with error */
+-  int iLine                       /* Source line number where error occurred */
+-){
+-  char zMsg[500];                 /* Human readable error text */
+-  int i;                          /* Loop counter */
++#define osMapViewOfFileFromApp ((LPVOID(WINAPI*)(HANDLE,ULONG,ULONG64, \
++        SIZE_T))aSyscall[67].pCurrent)
+ 
+-  zMsg[0] = 0;
+-  winGetLastErrorMsg(lastErrno, sizeof(zMsg), zMsg);
+-  assert( errcode!=SQLITE_OK );
+-  if( zPath==0 ) zPath = "";
+-  for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){}
+-  zMsg[i] = 0;
+-  sqlite3_log(errcode,
+-      "os_win.c:%d: (%lu) %s(%s) - %s",
+-      iLine, lastErrno, zFunc, zPath, zMsg
+-  );
++#if SQLITE_OS_WINRT
++  { "CreateFile2",             (SYSCALL)CreateFile2,             0 },
++#else
++  { "CreateFile2",             (SYSCALL)0,                       0 },
++#endif
+ 
+-  return errcode;
+-}
++#define osCreateFile2 ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD,DWORD, \
++        LPCREATEFILE2_EXTENDED_PARAMETERS))aSyscall[68].pCurrent)
+ 
+-/*
+-** The number of times that a ReadFile(), WriteFile(), and DeleteFile()
+-** will be retried following a locking error - probably caused by
+-** antivirus software.  Also the initial delay before the first retry.
+-** The delay increases linearly with each retry.
+-*/
+-#ifndef SQLITE_WIN32_IOERR_RETRY
+-# define SQLITE_WIN32_IOERR_RETRY 10
++#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_LOAD_EXTENSION)
++  { "LoadPackagedLibrary",     (SYSCALL)LoadPackagedLibrary,     0 },
++#else
++  { "LoadPackagedLibrary",     (SYSCALL)0,                       0 },
+ #endif
+-#ifndef SQLITE_WIN32_IOERR_RETRY_DELAY
+-# define SQLITE_WIN32_IOERR_RETRY_DELAY 25
++
++#define osLoadPackagedLibrary ((HMODULE(WINAPI*)(LPCWSTR, \
++        DWORD))aSyscall[69].pCurrent)
++
++#if SQLITE_OS_WINRT
++  { "GetTickCount64",          (SYSCALL)GetTickCount64,          0 },
++#else
++  { "GetTickCount64",          (SYSCALL)0,                       0 },
+ #endif
+-static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY;
+-static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY;
+ 
+-/*
+-** The "winIoerrCanRetry1" macro is used to determine if a particular I/O
+-** error code obtained via GetLastError() is eligible to be retried.  It
+-** must accept the error code DWORD as its only argument and should return
+-** non-zero if the error code is transient in nature and the operation
+-** responsible for generating the original error might succeed upon being
+-** retried.  The argument to this macro should be a variable.
+-**
+-** Additionally, a macro named "winIoerrCanRetry2" may be defined.  If it
+-** is defined, it will be consulted only when the macro "winIoerrCanRetry1"
+-** returns zero.  The "winIoerrCanRetry2" macro is completely optional and
+-** may be used to include additional error codes in the set that should
+-** result in the failing I/O operation being retried by the caller.  If
+-** defined, the "winIoerrCanRetry2" macro must exhibit external semantics
+-** identical to those of the "winIoerrCanRetry1" macro.
+-*/
+-#if !defined(winIoerrCanRetry1)
+-#define winIoerrCanRetry1(a) (((a)==ERROR_ACCESS_DENIED)        || \
+-                              ((a)==ERROR_SHARING_VIOLATION)    || \
+-                              ((a)==ERROR_LOCK_VIOLATION)       || \
+-                              ((a)==ERROR_DEV_NOT_EXIST)        || \
+-                              ((a)==ERROR_NETNAME_DELETED)      || \
+-                              ((a)==ERROR_SEM_TIMEOUT)          || \
+-                              ((a)==ERROR_NETWORK_UNREACHABLE))
++#define osGetTickCount64 ((ULONGLONG(WINAPI*)(VOID))aSyscall[70].pCurrent)
++
++#if SQLITE_OS_WINRT
++  { "GetNativeSystemInfo",     (SYSCALL)GetNativeSystemInfo,     0 },
++#else
++  { "GetNativeSystemInfo",     (SYSCALL)0,                       0 },
+ #endif
+ 
+-/*
+-** If a ReadFile() or WriteFile() error occurs, invoke this routine
+-** to see if it should be retried.  Return TRUE to retry.  Return FALSE
+-** to give up with an error.
+-*/
+-static int winRetryIoerr(int *pnRetry, DWORD *pError){
+-  DWORD e = osGetLastError();
+-  if( *pnRetry>=winIoerrRetry ){
+-    if( pError ){
+-      *pError = e;
+-    }
+-    return 0;
+-  }
+-  if( winIoerrCanRetry1(e) ){
+-    sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry));
+-    ++*pnRetry;
+-    return 1;
+-  }
+-#if defined(winIoerrCanRetry2)
+-  else if( winIoerrCanRetry2(e) ){
+-    sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry));
+-    ++*pnRetry;
+-    return 1;
+-  }
++#define osGetNativeSystemInfo ((VOID(WINAPI*)( \
++        LPSYSTEM_INFO))aSyscall[71].pCurrent)
++
++#if defined(SQLITE_WIN32_HAS_ANSI)
++  { "OutputDebugStringA",      (SYSCALL)OutputDebugStringA,      0 },
++#else
++  { "OutputDebugStringA",      (SYSCALL)0,                       0 },
+ #endif
+-  if( pError ){
+-    *pError = e;
+-  }
+-  return 0;
+-}
+ 
+-/*
+-** Log a I/O error retry episode.
+-*/
+-static void winLogIoerr(int nRetry, int lineno){
+-  if( nRetry ){
+-    sqlite3_log(SQLITE_NOTICE,
+-      "delayed %dms for lock/sharing conflict at line %d",
+-      winIoerrRetryDelay*nRetry*(nRetry+1)/2, lineno
+-    );
+-  }
+-}
++#define osOutputDebugStringA ((VOID(WINAPI*)(LPCSTR))aSyscall[72].pCurrent)
+ 
+-#if SQLITE_OS_WINCE
+-/*************************************************************************
+-** This section contains code for WinCE only.
+-*/
+-#if !defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API
+-/*
+-** The MSVC CRT on Windows CE may not have a localtime() function.  So
+-** create a substitute.
+-*/
+-/* #include <time.h> */
+-struct tm *__cdecl localtime(const time_t *t)
+-{
+-  static struct tm y;
+-  FILETIME uTm, lTm;
+-  SYSTEMTIME pTm;
+-  sqlite3_int64 t64;
+-  t64 = *t;
+-  t64 = (t64 + 11644473600)*10000000;
+-  uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF);
+-  uTm.dwHighDateTime= (DWORD)(t64 >> 32);
+-  osFileTimeToLocalFileTime(&uTm,&lTm);
+-  osFileTimeToSystemTime(&lTm,&pTm);
+-  y.tm_year = pTm.wYear - 1900;
+-  y.tm_mon = pTm.wMonth - 1;
+-  y.tm_wday = pTm.wDayOfWeek;
+-  y.tm_mday = pTm.wDay;
+-  y.tm_hour = pTm.wHour;
+-  y.tm_min = pTm.wMinute;
+-  y.tm_sec = pTm.wSecond;
+-  return &y;
+-}
++#if defined(SQLITE_WIN32_HAS_WIDE)
++  { "OutputDebugStringW",      (SYSCALL)OutputDebugStringW,      0 },
++#else
++  { "OutputDebugStringW",      (SYSCALL)0,                       0 },
+ #endif
+ 
+-#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]
++#define osOutputDebugStringW ((VOID(WINAPI*)(LPCWSTR))aSyscall[73].pCurrent)
+ 
+-/*
+-** Acquire a lock on the handle h
+-*/
+-static void winceMutexAcquire(HANDLE h){
+-   DWORD dwErr;
+-   do {
+-     dwErr = osWaitForSingleObject(h, INFINITE);
+-   } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
+-}
+-/*
+-** Release a lock acquired by winceMutexAcquire()
+-*/
+-#define winceMutexRelease(h) ReleaseMutex(h)
++  { "GetProcessHeap",          (SYSCALL)GetProcessHeap,          0 },
+ 
+-/*
+-** Create the mutex and shared memory used for locking in the file
+-** descriptor pFile
+-*/
+-static int winceCreateLock(const char *zFilename, winFile *pFile){
+-  LPWSTR zTok;
+-  LPWSTR zName;
+-  DWORD lastErrno;
+-  BOOL bLogged = FALSE;
+-  BOOL bInit = TRUE;
++#define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[74].pCurrent)
+ 
+-  zName = winUtf8ToUnicode(zFilename);
+-  if( zName==0 ){
+-    /* out of memory */
+-    return SQLITE_IOERR_NOMEM;
+-  }
++#if SQLITE_OS_WINRT && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0)
++  { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 },
++#else
++  { "CreateFileMappingFromApp", (SYSCALL)0,                      0 },
++#endif
+ 
+-  /* Initialize the local lockdata */
+-  memset(&pFile->local, 0, sizeof(pFile->local));
++#define osCreateFileMappingFromApp ((HANDLE(WINAPI*)(HANDLE, \
++        LPSECURITY_ATTRIBUTES,ULONG,ULONG64,LPCWSTR))aSyscall[75].pCurrent)
+ 
+-  /* Replace the backslashes from the filename and lowercase it
+-  ** to derive a mutex name. */
+-  zTok = osCharLowerW(zName);
+-  for (;*zTok;zTok++){
+-    if (*zTok == '\\') *zTok = '_';
+-  }
++/*
++** NOTE: On some sub-platforms, the InterlockedCompareExchange "function"
++**       is really just a macro that uses a compiler intrinsic (e.g. x64).
++**       So do not try to make this is into a redefinable interface.
++*/
++#if defined(InterlockedCompareExchange)
++  { "InterlockedCompareExchange", (SYSCALL)0,                    0 },
+ 
+-  /* Create/open the named mutex */
+-  pFile->hMutex = osCreateMutexW(NULL, FALSE, zName);
+-  if (!pFile->hMutex){
+-    pFile->lastErrno = osGetLastError();
+-    sqlite3_free(zName);
+-    return winLogError(SQLITE_IOERR, pFile->lastErrno,
+-                       "winceCreateLock1", zFilename);
+-  }
++#define osInterlockedCompareExchange InterlockedCompareExchange
++#else
++  { "InterlockedCompareExchange", (SYSCALL)InterlockedCompareExchange, 0 },
+ 
+-  /* Acquire the mutex before continuing */
+-  winceMutexAcquire(pFile->hMutex);
++#define osInterlockedCompareExchange ((LONG(WINAPI*)(LONG \
++        SQLITE_WIN32_VOLATILE*, LONG,LONG))aSyscall[76].pCurrent)
++#endif /* defined(InterlockedCompareExchange) */
+ 
+-  /* Since the names of named mutexes, semaphores, file mappings etc are
+-  ** case-sensitive, take advantage of that by uppercasing the mutex name
+-  ** and using that as the shared filemapping name.
+-  */
+-  osCharUpperW(zName);
+-  pFile->hShared = osCreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
+-                                        PAGE_READWRITE, 0, sizeof(winceLock),
+-                                        zName);
++#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
++  { "UuidCreate",               (SYSCALL)UuidCreate,             0 },
++#else
++  { "UuidCreate",               (SYSCALL)0,                      0 },
++#endif
+ 
+-  /* Set a flag that indicates we're the first to create the memory so it
+-  ** must be zero-initialized */
+-  lastErrno = osGetLastError();
+-  if (lastErrno == ERROR_ALREADY_EXISTS){
+-    bInit = FALSE;
+-  }
++#define osUuidCreate ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[77].pCurrent)
+ 
+-  sqlite3_free(zName);
++#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
++  { "UuidCreateSequential",     (SYSCALL)UuidCreateSequential,   0 },
++#else
++  { "UuidCreateSequential",     (SYSCALL)0,                      0 },
++#endif
+ 
+-  /* If we succeeded in making the shared memory handle, map it. */
+-  if( pFile->hShared ){
+-    pFile->shared = (winceLock*)osMapViewOfFile(pFile->hShared,
+-             FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
+-    /* If mapping failed, close the shared memory handle and erase it */
+-    if( !pFile->shared ){
+-      pFile->lastErrno = osGetLastError();
+-      winLogError(SQLITE_IOERR, pFile->lastErrno,
+-                  "winceCreateLock2", zFilename);
+-      bLogged = TRUE;
+-      osCloseHandle(pFile->hShared);
+-      pFile->hShared = NULL;
+-    }
+-  }
++#define osUuidCreateSequential \
++        ((RPC_STATUS(RPC_ENTRY*)(UUID*))aSyscall[78].pCurrent)
+ 
+-  /* If shared memory could not be created, then close the mutex and fail */
+-  if( pFile->hShared==NULL ){
+-    if( !bLogged ){
+-      pFile->lastErrno = lastErrno;
+-      winLogError(SQLITE_IOERR, pFile->lastErrno,
+-                  "winceCreateLock3", zFilename);
+-      bLogged = TRUE;
+-    }
+-    winceMutexRelease(pFile->hMutex);
+-    osCloseHandle(pFile->hMutex);
+-    pFile->hMutex = NULL;
+-    return SQLITE_IOERR;
+-  }
++#if !defined(SQLITE_NO_SYNC) && SQLITE_MAX_MMAP_SIZE>0
++  { "FlushViewOfFile",          (SYSCALL)FlushViewOfFile,        0 },
++#else
++  { "FlushViewOfFile",          (SYSCALL)0,                      0 },
++#endif
+ 
+-  /* Initialize the shared memory if we're supposed to */
+-  if( bInit ){
+-    memset(pFile->shared, 0, sizeof(winceLock));
+-  }
++#define osFlushViewOfFile \
++        ((BOOL(WINAPI*)(LPCVOID,SIZE_T))aSyscall[79].pCurrent)
+ 
+-  winceMutexRelease(pFile->hMutex);
+-  return SQLITE_OK;
+-}
++}; /* End of the overrideable system calls */
+ 
+ /*
+-** Destroy the part of winFile that deals with wince locks
++** This is the xSetSystemCall() method of sqlite3_vfs for all of the
++** "win32" VFSes.  Return SQLITE_OK opon successfully updating the
++** system call pointer, or SQLITE_NOTFOUND if there is no configurable
++** system call named zName.
+ */
+-static void winceDestroyLock(winFile *pFile){
+-  if (pFile->hMutex){
+-    /* Acquire the mutex */
+-    winceMutexAcquire(pFile->hMutex);
++static int winSetSystemCall(
++  sqlite3_vfs *pNotUsed,        /* The VFS pointer.  Not used */
++  const char *zName,            /* Name of system call to override */
++  sqlite3_syscall_ptr pNewFunc  /* Pointer to new system call value */
++){
++  unsigned int i;
++  int rc = SQLITE_NOTFOUND;
+ 
+-    /* The following blocks should probably assert in debug mode, but they
+-       are to cleanup in case any locks remained open */
+-    if (pFile->local.nReaders){
+-      pFile->shared->nReaders --;
+-    }
+-    if (pFile->local.bReserved){
+-      pFile->shared->bReserved = FALSE;
+-    }
+-    if (pFile->local.bPending){
+-      pFile->shared->bPending = FALSE;
++  UNUSED_PARAMETER(pNotUsed);
++  if( zName==0 ){
++    /* If no zName is given, restore all system calls to their default
++    ** settings and return NULL
++    */
++    rc = SQLITE_OK;
++    for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
++      if( aSyscall[i].pDefault ){
++        aSyscall[i].pCurrent = aSyscall[i].pDefault;
++      }
+     }
+-    if (pFile->local.bExclusive){
+-      pFile->shared->bExclusive = FALSE;
++  }else{
++    /* If zName is specified, operate on only the one system call
++    ** specified.
++    */
++    for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
++      if( strcmp(zName, aSyscall[i].zName)==0 ){
++        if( aSyscall[i].pDefault==0 ){
++          aSyscall[i].pDefault = aSyscall[i].pCurrent;
++        }
++        rc = SQLITE_OK;
++        if( pNewFunc==0 ) pNewFunc = aSyscall[i].pDefault;
++        aSyscall[i].pCurrent = pNewFunc;
++        break;
++      }
+     }
+-
+-    /* De-reference and close our copy of the shared memory handle */
+-    osUnmapViewOfFile(pFile->shared);
+-    osCloseHandle(pFile->hShared);
+-
+-    /* Done with the mutex */
+-    winceMutexRelease(pFile->hMutex);
+-    osCloseHandle(pFile->hMutex);
+-    pFile->hMutex = NULL;
+   }
++  return rc;
  }
+ 
+ /*
+-** An implementation of the LockFile() API of Windows for CE
++** Return the value of a system call.  Return NULL if zName is not a
++** recognized system call name.  NULL is also returned if the system call
++** is currently undefined.
+ */
+-static BOOL winceLockFile(
+-  LPHANDLE phFile,
+-  DWORD dwFileOffsetLow,
+-  DWORD dwFileOffsetHigh,
+-  DWORD nNumberOfBytesToLockLow,
+-  DWORD nNumberOfBytesToLockHigh
++static sqlite3_syscall_ptr winGetSystemCall(
++  sqlite3_vfs *pNotUsed,
++  const char *zName
+ ){
+-  winFile *pFile = HANDLE_TO_WINFILE(phFile);
+-  BOOL bReturn = FALSE;
++  unsigned int i;
+ 
+-  UNUSED_PARAMETER(dwFileOffsetHigh);
+-  UNUSED_PARAMETER(nNumberOfBytesToLockHigh);
++  UNUSED_PARAMETER(pNotUsed);
++  for(i=0; i<sizeof(aSyscall)/sizeof(aSyscall[0]); i++){
++    if( strcmp(zName, aSyscall[i].zName)==0 ) return aSyscall[i].pCurrent;
++  }
++  return 0;
++}
+ 
+-  if (!pFile->hMutex) return TRUE;
+-  winceMutexAcquire(pFile->hMutex);
++/*
++** Return the name of the first system call after zName.  If zName==NULL
++** then return the name of the first system call.  Return NULL if zName
++** is the last system call or if zName is not the name of a valid
++** system call.
++*/
++static const char *winNextSystemCall(sqlite3_vfs *p, const char *zName){
++  int i = -1;
+ 
+-  /* Wanting an exclusive lock? */
+-  if (dwFileOffsetLow == (DWORD)SHARED_FIRST
+-       && nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
+-    if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
+-       pFile->shared->bExclusive = TRUE;
+-       pFile->local.bExclusive = TRUE;
+-       bReturn = TRUE;
++  UNUSED_PARAMETER(p);
++  if( zName ){
++    for(i=0; i<ArraySize(aSyscall)-1; i++){
++      if( strcmp(zName, aSyscall[i].zName)==0 ) break;
+     }
+   }
+-
+-  /* Want a read-only lock? */
+-  else if (dwFileOffsetLow == (DWORD)SHARED_FIRST &&
+-           nNumberOfBytesToLockLow == 1){
+-    if (pFile->shared->bExclusive == 0){
+-      pFile->local.nReaders ++;
+-      if (pFile->local.nReaders == 1){
+-        pFile->shared->nReaders ++;
+-      }
+-      bReturn = TRUE;
+-    }
++  for(i++; i<ArraySize(aSyscall); i++){
++    if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName;
+   }
++  return 0;
++}
+ 
+-  /* Want a pending lock? */
+-  else if (dwFileOffsetLow == (DWORD)PENDING_BYTE
+-           && nNumberOfBytesToLockLow == 1){
+-    /* If no pending lock has been acquired, then acquire it */
+-    if (pFile->shared->bPending == 0) {
+-      pFile->shared->bPending = TRUE;
+-      pFile->local.bPending = TRUE;
+-      bReturn = TRUE;
+-    }
+-  }
++#ifdef SQLITE_WIN32_MALLOC
++/*
++** If a Win32 native heap has been configured, this function will attempt to
++** compact it.  Upon success, SQLITE_OK will be returned.  Upon failure, one
++** of SQLITE_NOMEM, SQLITE_ERROR, or SQLITE_NOTFOUND will be returned.  The
++** "pnLargest" argument, if non-zero, will be used to return the size of the
++** largest committed free block in the heap, in bytes.
++*/
++SQLITE_API int SQLITE_STDCALL sqlite3_win32_compact_heap(LPUINT pnLargest){
++  int rc = SQLITE_OK;
++  UINT nLargest = 0;
++  HANDLE hHeap;
+ 
+-  /* Want a reserved lock? */
+-  else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE
+-           && nNumberOfBytesToLockLow == 1){
+-    if (pFile->shared->bReserved == 0) {
+-      pFile->shared->bReserved = TRUE;
+-      pFile->local.bReserved = TRUE;
+-      bReturn = TRUE;
++  winMemAssertMagic();
++  hHeap = winMemGetHeap();
++  assert( hHeap!=0 );
++  assert( hHeap!=INVALID_HANDLE_VALUE );
++#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
++  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
++#endif
++#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT
++  if( (nLargest=osHeapCompact(hHeap, SQLITE_WIN32_HEAP_FLAGS))==0 ){
++    DWORD lastErrno = osGetLastError();
++    if( lastErrno==NO_ERROR ){
++      sqlite3_log(SQLITE_NOMEM, "failed to HeapCompact (no space), heap=%p",
++                  (void*)hHeap);
++      rc = SQLITE_NOMEM;
++    }else{
++      sqlite3_log(SQLITE_ERROR, "failed to HeapCompact (%lu), heap=%p",
++                  osGetLastError(), (void*)hHeap);
++      rc = SQLITE_ERROR;
+     }
+   }
+-
+-  winceMutexRelease(pFile->hMutex);
+-  return bReturn;
++#else
++  sqlite3_log(SQLITE_NOTFOUND, "failed to HeapCompact, heap=%p",
++              (void*)hHeap);
++  rc = SQLITE_NOTFOUND;
++#endif
++  if( pnLargest ) *pnLargest = nLargest;
++  return rc;
+ }
+ 
+ /*
+-** An implementation of the UnlockFile API of Windows for CE
++** If a Win32 native heap has been configured, this function will attempt to
++** destroy and recreate it.  If the Win32 native heap is not isolated and/or
++** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will
++** be returned and no changes will be made to the Win32 native heap.
+ */
+-static BOOL winceUnlockFile(
+-  LPHANDLE phFile,
+-  DWORD dwFileOffsetLow,
+-  DWORD dwFileOffsetHigh,
+-  DWORD nNumberOfBytesToUnlockLow,
+-  DWORD nNumberOfBytesToUnlockHigh
+-){
+-  winFile *pFile = HANDLE_TO_WINFILE(phFile);
+-  BOOL bReturn = FALSE;
+-
+-  UNUSED_PARAMETER(dwFileOffsetHigh);
+-  UNUSED_PARAMETER(nNumberOfBytesToUnlockHigh);
+-
+-  if (!pFile->hMutex) return TRUE;
+-  winceMutexAcquire(pFile->hMutex);
++SQLITE_API int SQLITE_STDCALL sqlite3_win32_reset_heap(){
++  int rc;
++  MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
++  MUTEX_LOGIC( sqlite3_mutex *pMem; )    /* The memsys static mutex */
++  MUTEX_LOGIC( pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER); )
++  MUTEX_LOGIC( pMem = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM); )
++  sqlite3_mutex_enter(pMaster);
++  sqlite3_mutex_enter(pMem);
++  winMemAssertMagic();
++  if( winMemGetHeap()!=NULL && winMemGetOwned() && sqlite3_memory_used()==0 ){
++    /*
++    ** At this point, there should be no outstanding memory allocations on
++    ** the heap.  Also, since both the master and memsys locks are currently
++    ** being held by us, no other function (i.e. from another thread) should
++    ** be able to even access the heap.  Attempt to destroy and recreate our
++    ** isolated Win32 native heap now.
++    */
++    assert( winMemGetHeap()!=NULL );
++    assert( winMemGetOwned() );
++    assert( sqlite3_memory_used()==0 );
++    winMemShutdown(winMemGetDataPtr());
++    assert( winMemGetHeap()==NULL );
++    assert( !winMemGetOwned() );
++    assert( sqlite3_memory_used()==0 );
++    rc = winMemInit(winMemGetDataPtr());
++    assert( rc!=SQLITE_OK || winMemGetHeap()!=NULL );
++    assert( rc!=SQLITE_OK || winMemGetOwned() );
++    assert( rc!=SQLITE_OK || sqlite3_memory_used()==0 );
++  }else{
++    /*
++    ** The Win32 native heap cannot be modified because it may be in use.
++    */
++    rc = SQLITE_BUSY;
++  }
++  sqlite3_mutex_leave(pMem);
++  sqlite3_mutex_leave(pMaster);
++  return rc;
++}
++#endif /* SQLITE_WIN32_MALLOC */
+ 
+-  /* Releasing a reader lock or an exclusive lock */
+-  if (dwFileOffsetLow == (DWORD)SHARED_FIRST){
+-    /* Did we have an exclusive lock? */
+-    if (pFile->local.bExclusive){
+-      assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE);
+-      pFile->local.bExclusive = FALSE;
+-      pFile->shared->bExclusive = FALSE;
+-      bReturn = TRUE;
+-    }
++/*
++** This function outputs the specified (ANSI) string to the Win32 debugger
++** (if available).
++*/
+ 
+-    /* Did we just have a reader lock? */
+-    else if (pFile->local.nReaders){
+-      assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE
+-             || nNumberOfBytesToUnlockLow == 1);
+-      pFile->local.nReaders --;
+-      if (pFile->local.nReaders == 0)
+-      {
+-        pFile->shared->nReaders --;
+-      }
+-      bReturn = TRUE;
+-    }
++SQLITE_API void SQLITE_STDCALL sqlite3_win32_write_debug(const char *zBuf, int nBuf){
++  char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE];
++  int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */
++  if( nMin<-1 ) nMin = -1; /* all negative values become -1. */
++  assert( nMin==-1 || nMin==0 || nMin<SQLITE_WIN32_DBG_BUF_SIZE );
++#if defined(SQLITE_WIN32_HAS_ANSI)
++  if( nMin>0 ){
++    memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
++    memcpy(zDbgBuf, zBuf, nMin);
++    osOutputDebugStringA(zDbgBuf);
++  }else{
++    osOutputDebugStringA(zBuf);
+   }
+-
+-  /* Releasing a pending lock */
+-  else if (dwFileOffsetLow == (DWORD)PENDING_BYTE
+-           && nNumberOfBytesToUnlockLow == 1){
+-    if (pFile->local.bPending){
+-      pFile->local.bPending = FALSE;
+-      pFile->shared->bPending = FALSE;
+-      bReturn = TRUE;
+-    }
++#elif defined(SQLITE_WIN32_HAS_WIDE)
++  memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
++  if ( osMultiByteToWideChar(
++          osAreFileApisANSI() ? CP_ACP : CP_OEMCP, 0, zBuf,
++          nMin, (LPWSTR)zDbgBuf, SQLITE_WIN32_DBG_BUF_SIZE/sizeof(WCHAR))<=0 ){
++    return;
+   }
+-  /* Releasing a reserved lock */
+-  else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE
+-           && nNumberOfBytesToUnlockLow == 1){
+-    if (pFile->local.bReserved) {
+-      pFile->local.bReserved = FALSE;
+-      pFile->shared->bReserved = FALSE;
+-      bReturn = TRUE;
+-    }
++  osOutputDebugStringW((LPCWSTR)zDbgBuf);
++#else
++  if( nMin>0 ){
++    memset(zDbgBuf, 0, SQLITE_WIN32_DBG_BUF_SIZE);
++    memcpy(zDbgBuf, zBuf, nMin);
++    fprintf(stderr, "%s", zDbgBuf);
++  }else{
++    fprintf(stderr, "%s", zBuf);
+   }
++#endif
++}
+ 
+-  winceMutexRelease(pFile->hMutex);
+-  return bReturn;
++/*
++** The following routine suspends the current thread for at least ms
++** milliseconds.  This is equivalent to the Win32 Sleep() interface.
++*/
++#if SQLITE_OS_WINRT
++static HANDLE sleepObj = NULL;
++#endif
++
++SQLITE_API void SQLITE_STDCALL sqlite3_win32_sleep(DWORD milliseconds){
++#if SQLITE_OS_WINRT
++  if ( sleepObj==NULL ){
++    sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET,
++                                SYNCHRONIZE);
++  }
++  assert( sleepObj!=NULL );
++  osWaitForSingleObjectEx(sleepObj, milliseconds, FALSE);
++#else
++  osSleep(milliseconds);
++#endif
++}
++
++#if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \
++        SQLITE_THREADSAFE>0
++SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){
++  DWORD rc;
++  while( (rc = osWaitForSingleObjectEx(hObject, INFINITE,
++                                       TRUE))==WAIT_IO_COMPLETION ){}
++  return rc;
+ }
++#endif
++
+ /*
+-** End of the special code for wince
+-*****************************************************************************/
+-#endif /* SQLITE_OS_WINCE */
++** Return true (non-zero) if we are running under WinNT, Win2K, WinXP,
++** or WinCE.  Return false (zero) for Win95, Win98, or WinME.
++**
++** Here is an interesting observation:  Win95, Win98, and WinME lack
++** the LockFileEx() API.  But we can still statically link against that
++** API as long as we don't call it when running Win95/98/ME.  A call to
++** this routine is used to determine if the host is Win95/98/ME or
++** WinNT/2K/XP so that we will know whether or not we can safely call
++** the LockFileEx() API.
++*/
++
++#if !defined(SQLITE_WIN32_GETVERSIONEX) || !SQLITE_WIN32_GETVERSIONEX
++# define osIsNT()  (1)
++#elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI)
++# define osIsNT()  (1)
++#elif !defined(SQLITE_WIN32_HAS_WIDE)
++# define osIsNT()  (0)
++#else
++# define osIsNT()  ((sqlite3_os_type==2) || sqlite3_win32_is_nt())
++#endif
+ 
+ /*
+-** Lock a file region.
++** This function determines if the machine is running a version of Windows
++** based on the NT kernel.
+ */
+-static BOOL winLockFile(
+-  LPHANDLE phFile,
+-  DWORD flags,
+-  DWORD offsetLow,
+-  DWORD offsetHigh,
+-  DWORD numBytesLow,
+-  DWORD numBytesHigh
+-){
+-#if SQLITE_OS_WINCE
++SQLITE_API int SQLITE_STDCALL sqlite3_win32_is_nt(void){
++#if SQLITE_OS_WINRT
+   /*
+-  ** NOTE: Windows CE is handled differently here due its lack of the Win32
+-  **       API LockFile.
++  ** NOTE: The WinRT sub-platform is always assumed to be based on the NT
++  **       kernel.
+   */
+-  return winceLockFile(phFile, offsetLow, offsetHigh,
+-                       numBytesLow, numBytesHigh);
++  return 1;
++#elif defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX
++  if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){
++#if defined(SQLITE_WIN32_HAS_ANSI)
++    OSVERSIONINFOA sInfo;
++    sInfo.dwOSVersionInfoSize = sizeof(sInfo);
++    osGetVersionExA(&sInfo);
++    osInterlockedCompareExchange(&sqlite3_os_type,
++        (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0);
++#elif defined(SQLITE_WIN32_HAS_WIDE)
++    OSVERSIONINFOW sInfo;
++    sInfo.dwOSVersionInfoSize = sizeof(sInfo);
++    osGetVersionExW(&sInfo);
++    osInterlockedCompareExchange(&sqlite3_os_type,
++        (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0);
++#endif
++  }
++  return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2;
++#elif SQLITE_TEST
++  return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2;
+ #else
+-  if( osIsNT() ){
+-    OVERLAPPED ovlp;
+-    memset(&ovlp, 0, sizeof(OVERLAPPED));
+-    ovlp.Offset = offsetLow;
+-    ovlp.OffsetHigh = offsetHigh;
+-    return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp);
+-  }else{
+-    return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
+-                      numBytesHigh);
++  /*
++  ** NOTE: All sub-platforms where the GetVersionEx[AW] functions are
++  **       deprecated are always assumed to be based on the NT kernel.
++  */
++  return 1;
++#endif
++}
++
++#ifdef SQLITE_WIN32_MALLOC
++/*
++** Allocate nBytes of memory.
++*/
++static void *winMemMalloc(int nBytes){
++  HANDLE hHeap;
++  void *p;
++
++  winMemAssertMagic();
++  hHeap = winMemGetHeap();
++  assert( hHeap!=0 );
++  assert( hHeap!=INVALID_HANDLE_VALUE );
++#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
++  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
++#endif
++  assert( nBytes>=0 );
++  p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
++  if( !p ){
++    sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%lu), heap=%p",
++                nBytes, osGetLastError(), (void*)hHeap);
+   }
++  return p;
++}
++
++/*
++** Free memory.
++*/
++static void winMemFree(void *pPrior){
++  HANDLE hHeap;
++
++  winMemAssertMagic();
++  hHeap = winMemGetHeap();
++  assert( hHeap!=0 );
++  assert( hHeap!=INVALID_HANDLE_VALUE );
++#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
++  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
  #endif
++  if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */
++  if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){
++    sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%lu), heap=%p",
++                pPrior, osGetLastError(), (void*)hHeap);
++  }
+ }
  
--#endif /* SQLITE_OMIT_DISKIO */
-+#endif /* SQLITE_OMIT_DISKIO */
+ /*
+-** Unlock a file region.
+- */
+-static BOOL winUnlockFile(
+-  LPHANDLE phFile,
+-  DWORD offsetLow,
+-  DWORD offsetHigh,
+-  DWORD numBytesLow,
+-  DWORD numBytesHigh
+-){
+-#if SQLITE_OS_WINCE
+-  /*
+-  ** NOTE: Windows CE is handled differently here due its lack of the Win32
+-  **       API UnlockFile.
+-  */
+-  return winceUnlockFile(phFile, offsetLow, offsetHigh,
+-                         numBytesLow, numBytesHigh);
+-#else
+-  if( osIsNT() ){
+-    OVERLAPPED ovlp;
+-    memset(&ovlp, 0, sizeof(OVERLAPPED));
+-    ovlp.Offset = offsetLow;
+-    ovlp.OffsetHigh = offsetHigh;
+-    return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp);
+-  }else{
+-    return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
+-                        numBytesHigh);
++** Change the size of an existing memory allocation
++*/
++static void *winMemRealloc(void *pPrior, int nBytes){
++  HANDLE hHeap;
++  void *p;
++
++  winMemAssertMagic();
++  hHeap = winMemGetHeap();
++  assert( hHeap!=0 );
++  assert( hHeap!=INVALID_HANDLE_VALUE );
++#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
++  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) );
++#endif
++  assert( nBytes>=0 );
++  if( !pPrior ){
++    p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes);
++  }else{
++    p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes);
+   }
+-#endif
++  if( !p ){
++    sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%lu), heap=%p",
++                pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, osGetLastError(),
++                (void*)hHeap);
++  }
++  return p;
+ }
+ 
+-/*****************************************************************************
+-** The next group of routines implement the I/O methods specified
+-** by the sqlite3_io_methods object.
+-******************************************************************************/
+-
+ /*
+-** Some Microsoft compilers lack this definition.
++** Return the size of an outstanding allocation, in bytes.
+ */
+-#ifndef INVALID_SET_FILE_POINTER
+-# define INVALID_SET_FILE_POINTER ((DWORD)-1)
++static int winMemSize(void *p){
++  HANDLE hHeap;
++  SIZE_T n;
++
++  winMemAssertMagic();
++  hHeap = winMemGetHeap();
++  assert( hHeap!=0 );
++  assert( hHeap!=INVALID_HANDLE_VALUE );
++#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
++  assert( osHeapValidate(hHeap, SQLITE_WIN32_HEAP_FLAGS, p) );
+ #endif
++  if( !p ) return 0;
++  n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p);
++  if( n==(SIZE_T)-1 ){
++    sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%lu), heap=%p",
++                p, osGetLastError(), (void*)hHeap);
++    return 0;
++  }
++  return (int)n;
++}
+ 
+ /*
+-** Move the current position of the file handle passed as the first
+-** argument to offset iOffset within the file. If successful, return 0.
+-** Otherwise, set pFile->lastErrno and return non-zero.
++** Round up a request size to the next valid allocation size.
+ */
+-static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){
+-#if !SQLITE_OS_WINRT
+-  LONG upperBits;                 /* Most sig. 32 bits of new offset */
+-  LONG lowerBits;                 /* Least sig. 32 bits of new offset */
+-  DWORD dwRet;                    /* Value returned by SetFilePointer() */
+-  DWORD lastErrno;                /* Value returned by GetLastError() */
+-
+-  OSTRACE(("SEEK file=%p, offset=%lld\n", pFile->h, iOffset));
++static int winMemRoundup(int n){
++  return n;
++}
+ 
+-  upperBits = (LONG)((iOffset>>32) & 0x7fffffff);
+-  lowerBits = (LONG)(iOffset & 0xffffffff);
++/*
++** Initialize this module.
++*/
++static int winMemInit(void *pAppData){
++  winMemData *pWinMemData = (winMemData *)pAppData;
+ 
+-  /* API oddity: If successful, SetFilePointer() returns a dword
+-  ** containing the lower 32-bits of the new file-offset. Or, if it fails,
+-  ** it returns INVALID_SET_FILE_POINTER. However according to MSDN,
+-  ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine
+-  ** whether an error has actually occurred, it is also necessary to call
+-  ** GetLastError().
+-  */
+-  dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
++  if( !pWinMemData ) return SQLITE_ERROR;
++  assert( pWinMemData->magic1==WINMEM_MAGIC1 );
++  assert( pWinMemData->magic2==WINMEM_MAGIC2 );
+ 
+-  if( (dwRet==INVALID_SET_FILE_POINTER
+-      && ((lastErrno = osGetLastError())!=NO_ERROR)) ){
+-    pFile->lastErrno = lastErrno;
+-    winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
+-                "winSeekFile", pFile->zPath);
+-    OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
+-    return 1;
++#if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE
++  if( !pWinMemData->hHeap ){
++    DWORD dwInitialSize = SQLITE_WIN32_HEAP_INIT_SIZE;
++    DWORD dwMaximumSize = (DWORD)sqlite3GlobalConfig.nHeap;
++    if( dwMaximumSize==0 ){
++      dwMaximumSize = SQLITE_WIN32_HEAP_MAX_SIZE;
++    }else if( dwInitialSize>dwMaximumSize ){
++      dwInitialSize = dwMaximumSize;
++    }
++    pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS,
++                                      dwInitialSize, dwMaximumSize);
++    if( !pWinMemData->hHeap ){
++      sqlite3_log(SQLITE_NOMEM,
++          "failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu",
++          osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize,
++          dwMaximumSize);
++      return SQLITE_NOMEM;
++    }
++    pWinMemData->bOwned = TRUE;
++    assert( pWinMemData->bOwned );
+   }
+-
+-  OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h));
+-  return 0;
+ #else
+-  /*
+-  ** Same as above, except that this implementation works for WinRT.
+-  */
+-
+-  LARGE_INTEGER x;                /* The new offset */
+-  BOOL bRet;                      /* Value returned by SetFilePointerEx() */
+-
+-  x.QuadPart = iOffset;
+-  bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN);
+-
+-  if(!bRet){
+-    pFile->lastErrno = osGetLastError();
+-    winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
+-                "winSeekFile", pFile->zPath);
+-    OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
+-    return 1;
++  pWinMemData->hHeap = osGetProcessHeap();
++  if( !pWinMemData->hHeap ){
++    sqlite3_log(SQLITE_NOMEM,
++        "failed to GetProcessHeap (%lu)", osGetLastError());
++    return SQLITE_NOMEM;
+   }
+-
+-  OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h));
+-  return 0;
++  pWinMemData->bOwned = FALSE;
++  assert( !pWinMemData->bOwned );
+ #endif
+-}
+-
+-#if SQLITE_MAX_MMAP_SIZE>0
+-/* Forward references to VFS helper methods used for memory mapped files */
+-static int winMapfile(winFile*, sqlite3_int64);
+-static int winUnmapfile(winFile*);
++  assert( pWinMemData->hHeap!=0 );
++  assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
++#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
++  assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
+ #endif
++  return SQLITE_OK;
++}
+ 
+ /*
+-** Close a file.
+-**
+-** It is reported that an attempt to close a handle might sometimes
+-** fail.  This is a very unreasonable result, but Windows is notorious
+-** for being unreasonable so I do not doubt that it might happen.  If
+-** the close fails, we pause for 100 milliseconds and try again.  As
+-** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before
+-** giving up and returning an error.
++** Deinitialize this module.
+ */
+-#define MX_CLOSE_ATTEMPT 3
+-static int winClose(sqlite3_file *id){
+-  int rc, cnt = 0;
+-  winFile *pFile = (winFile*)id;
++static void winMemShutdown(void *pAppData){
++  winMemData *pWinMemData = (winMemData *)pAppData;
+ 
+-  assert( id!=0 );
+-#ifndef SQLITE_OMIT_WAL
+-  assert( pFile->pShm==0 );
+-#endif
+-  assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE );
+-  OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p\n",
+-           osGetCurrentProcessId(), pFile, pFile->h));
++  if( !pWinMemData ) return;
++  assert( pWinMemData->magic1==WINMEM_MAGIC1 );
++  assert( pWinMemData->magic2==WINMEM_MAGIC2 );
+ 
+-#if SQLITE_MAX_MMAP_SIZE>0
+-  winUnmapfile(pFile);
++  if( pWinMemData->hHeap ){
++    assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
++#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_MALLOC_VALIDATE)
++    assert( osHeapValidate(pWinMemData->hHeap, SQLITE_WIN32_HEAP_FLAGS, NULL) );
+ #endif
+-
+-  do{
+-    rc = osCloseHandle(pFile->h);
+-    /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
+-  }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) );
+-#if SQLITE_OS_WINCE
+-#define WINCE_DELETION_ATTEMPTS 3
+-  winceDestroyLock(pFile);
+-  if( pFile->zDeleteOnClose ){
+-    int cnt = 0;
+-    while(
+-           osDeleteFileW(pFile->zDeleteOnClose)==0
+-        && osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff
+-        && cnt++ < WINCE_DELETION_ATTEMPTS
+-    ){
+-       sqlite3_win32_sleep(100);  /* Wait a little before trying again */
++    if( pWinMemData->bOwned ){
++      if( !osHeapDestroy(pWinMemData->hHeap) ){
++        sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%lu), heap=%p",
++                    osGetLastError(), (void*)pWinMemData->hHeap);
++      }
++      pWinMemData->bOwned = FALSE;
+     }
+-    sqlite3_free(pFile->zDeleteOnClose);
+-  }
+-#endif
+-  if( rc ){
+-    pFile->h = NULL;
++    pWinMemData->hHeap = NULL;
+   }
+-  OpenCounter(-1);
+-  OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p, rc=%s\n",
+-           osGetCurrentProcessId(), pFile, pFile->h, rc ? "ok" : "failed"));
+-  return rc ? SQLITE_OK
+-            : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(),
+-                          "winClose", pFile->zPath);
+ }
+ 
+ /*
+-** Read data from a file into a buffer.  Return SQLITE_OK if all
+-** bytes were read successfully and SQLITE_IOERR if anything goes
+-** wrong.
++** Populate the low-level memory allocation function pointers in
++** sqlite3GlobalConfig.m with pointers to the routines in this file. The
++** arguments specify the block of memory to manage.
++**
++** This routine is only called by sqlite3_config(), and therefore
++** is not required to be threadsafe (it is not).
+ */
+-static int winRead(
+-  sqlite3_file *id,          /* File to read from */
+-  void *pBuf,                /* Write content into this buffer */
+-  int amt,                   /* Number of bytes to read */
+-  sqlite3_int64 offset       /* Begin reading at this offset */
+-){
+-#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
+-  OVERLAPPED overlapped;          /* The offset for ReadFile. */
+-#endif
+-  winFile *pFile = (winFile*)id;  /* file handle */
+-  DWORD nRead;                    /* Number of bytes actually read from file */
+-  int nRetry = 0;                 /* Number of retrys */
++SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void){
++  static const sqlite3_mem_methods winMemMethods = {
++    winMemMalloc,
++    winMemFree,
++    winMemRealloc,
++    winMemSize,
++    winMemRoundup,
++    winMemInit,
++    winMemShutdown,
++    &win_mem_data
++  };
++  return &winMemMethods;
++}
+ 
+-  assert( id!=0 );
+-  assert( amt>0 );
+-  assert( offset>=0 );
+-  SimulateIOError(return SQLITE_IOERR_READ);
+-  OSTRACE(("READ pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, "
+-           "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile,
+-           pFile->h, pBuf, amt, offset, pFile->locktype));
++SQLITE_PRIVATE void sqlite3MemSetDefault(void){
++  sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetWin32());
++}
++#endif /* SQLITE_WIN32_MALLOC */
+ 
+-#if SQLITE_MAX_MMAP_SIZE>0
+-  /* Deal with as much of this read request as possible by transfering
+-  ** data from the memory mapping using memcpy().  */
+-  if( offset<pFile->mmapSize ){
+-    if( offset+amt <= pFile->mmapSize ){
+-      memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt);
+-      OSTRACE(("READ-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
+-               osGetCurrentProcessId(), pFile, pFile->h));
+-      return SQLITE_OK;
+-    }else{
+-      int nCopy = (int)(pFile->mmapSize - offset);
+-      memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy);
+-      pBuf = &((u8 *)pBuf)[nCopy];
+-      amt -= nCopy;
+-      offset += nCopy;
+-    }
+-  }
+-#endif
++/*
++** Convert a UTF-8 string to Microsoft Unicode (UTF-16?).
++**
++** Space to hold the returned string is obtained from malloc.
++*/
++static LPWSTR winUtf8ToUnicode(const char *zFilename){
++  int nChar;
++  LPWSTR zWideFilename;
+ 
+-#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
+-  if( winSeekFile(pFile, offset) ){
+-    OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n",
+-             osGetCurrentProcessId(), pFile, pFile->h));
+-    return SQLITE_FULL;
++  nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
++  if( nChar==0 ){
++    return 0;
+   }
+-  while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
+-#else
+-  memset(&overlapped, 0, sizeof(OVERLAPPED));
+-  overlapped.Offset = (LONG)(offset & 0xffffffff);
+-  overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
+-  while( !osReadFile(pFile->h, pBuf, amt, &nRead, &overlapped) &&
+-         osGetLastError()!=ERROR_HANDLE_EOF ){
+-#endif
+-    DWORD lastErrno;
+-    if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
+-    pFile->lastErrno = lastErrno;
+-    OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_READ\n",
+-             osGetCurrentProcessId(), pFile, pFile->h));
+-    return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
+-                       "winRead", pFile->zPath);
++  zWideFilename = sqlite3MallocZero( nChar*sizeof(zWideFilename[0]) );
++  if( zWideFilename==0 ){
++    return 0;
+   }
+-  winLogIoerr(nRetry, __LINE__);
+-  if( nRead<(DWORD)amt ){
+-    /* Unread parts of the buffer must be zero-filled */
+-    memset(&((char*)pBuf)[nRead], 0, amt-nRead);
+-    OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_SHORT_READ\n",
+-             osGetCurrentProcessId(), pFile, pFile->h));
+-    return SQLITE_IOERR_SHORT_READ;
++  nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename,
++                                nChar);
++  if( nChar==0 ){
++    sqlite3_free(zWideFilename);
++    zWideFilename = 0;
+   }
+-
+-  OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
+-           osGetCurrentProcessId(), pFile, pFile->h));
+-  return SQLITE_OK;
++  return zWideFilename;
+ }
+ 
+ /*
+-** Write data from a buffer into a file.  Return SQLITE_OK on success
+-** or some other error code on failure.
++** Convert Microsoft Unicode to UTF-8.  Space to hold the returned string is
++** obtained from sqlite3_malloc().
+ */
+-static int winWrite(
+-  sqlite3_file *id,               /* File to write into */
+-  const void *pBuf,               /* The bytes to be written */
+-  int amt,                        /* Number of bytes to write */
+-  sqlite3_int64 offset            /* Offset into the file to begin writing at */
+-){
+-  int rc = 0;                     /* True if error has occurred, else false */
+-  winFile *pFile = (winFile*)id;  /* File handle */
+-  int nRetry = 0;                 /* Number of retries */
+-
+-  assert( amt>0 );
+-  assert( pFile );
+-  SimulateIOError(return SQLITE_IOERR_WRITE);
+-  SimulateDiskfullError(return SQLITE_FULL);
+-
+-  OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, "
+-           "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile,
+-           pFile->h, pBuf, amt, offset, pFile->locktype));
++static char *winUnicodeToUtf8(LPCWSTR zWideFilename){
++  int nByte;
++  char *zFilename;
+ 
+-#if SQLITE_MAX_MMAP_SIZE>0
+-  /* Deal with as much of this write request as possible by transfering
+-  ** data from the memory mapping using memcpy().  */
+-  if( offset<pFile->mmapSize ){
+-    if( offset+amt <= pFile->mmapSize ){
+-      memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt);
+-      OSTRACE(("WRITE-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
+-               osGetCurrentProcessId(), pFile, pFile->h));
+-      return SQLITE_OK;
+-    }else{
+-      int nCopy = (int)(pFile->mmapSize - offset);
+-      memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy);
+-      pBuf = &((u8 *)pBuf)[nCopy];
+-      amt -= nCopy;
+-      offset += nCopy;
+-    }
++  nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
++  if( nByte == 0 ){
++    return 0;
+   }
+-#endif
+-
+-#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
+-  rc = winSeekFile(pFile, offset);
+-  if( rc==0 ){
+-#else
+-  {
+-#endif
+-#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
+-    OVERLAPPED overlapped;        /* The offset for WriteFile. */
+-#endif
+-    u8 *aRem = (u8 *)pBuf;        /* Data yet to be written */
+-    int nRem = amt;               /* Number of bytes yet to be written */
+-    DWORD nWrite;                 /* Bytes written by each WriteFile() call */
+-    DWORD lastErrno = NO_ERROR;   /* Value returned by GetLastError() */
++  zFilename = sqlite3MallocZero( nByte );
++  if( zFilename==0 ){
++    return 0;
++  }
++  nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
++                                0, 0);
++  if( nByte == 0 ){
++    sqlite3_free(zFilename);
++    zFilename = 0;
++  }
++  return zFilename;
++}
+ 
+-#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
+-    memset(&overlapped, 0, sizeof(OVERLAPPED));
+-    overlapped.Offset = (LONG)(offset & 0xffffffff);
+-    overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
+-#endif
++/*
++** Convert an ANSI string to Microsoft Unicode, based on the
++** current codepage settings for file apis.
++**
++** Space to hold the returned string is obtained
++** from sqlite3_malloc.
++*/
++static LPWSTR winMbcsToUnicode(const char *zFilename){
++  int nByte;
++  LPWSTR zMbcsFilename;
++  int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
+ 
+-    while( nRem>0 ){
+-#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
+-      if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
+-#else
+-      if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
+-#endif
+-        if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
+-        break;
+-      }
+-      assert( nWrite==0 || nWrite<=(DWORD)nRem );
+-      if( nWrite==0 || nWrite>(DWORD)nRem ){
+-        lastErrno = osGetLastError();
+-        break;
+-      }
+-#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
+-      offset += nWrite;
+-      overlapped.Offset = (LONG)(offset & 0xffffffff);
+-      overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
+-#endif
+-      aRem += nWrite;
+-      nRem -= nWrite;
+-    }
+-    if( nRem>0 ){
+-      pFile->lastErrno = lastErrno;
+-      rc = 1;
+-    }
++  nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL,
++                                0)*sizeof(WCHAR);
++  if( nByte==0 ){
++    return 0;
+   }
+-
+-  if( rc ){
+-    if(   ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL )
+-       || ( pFile->lastErrno==ERROR_DISK_FULL )){
+-      OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n",
+-               osGetCurrentProcessId(), pFile, pFile->h));
+-      return winLogError(SQLITE_FULL, pFile->lastErrno,
+-                         "winWrite1", pFile->zPath);
+-    }
+-    OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_WRITE\n",
+-             osGetCurrentProcessId(), pFile, pFile->h));
+-    return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno,
+-                       "winWrite2", pFile->zPath);
+-  }else{
+-    winLogIoerr(nRetry, __LINE__);
++  zMbcsFilename = sqlite3MallocZero( nByte*sizeof(zMbcsFilename[0]) );
++  if( zMbcsFilename==0 ){
++    return 0;
+   }
+-  OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
+-           osGetCurrentProcessId(), pFile, pFile->h));
+-  return SQLITE_OK;
++  nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename,
++                                nByte);
++  if( nByte==0 ){
++    sqlite3_free(zMbcsFilename);
++    zMbcsFilename = 0;
++  }
++  return zMbcsFilename;
+ }
+ 
+ /*
+-** Truncate an open file to a specified size
++** Convert Microsoft Unicode to multi-byte character string, based on the
++** user's ANSI codepage.
++**
++** Space to hold the returned string is obtained from
++** sqlite3_malloc().
+ */
+-static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
+-  winFile *pFile = (winFile*)id;  /* File handle object */
+-  int rc = SQLITE_OK;             /* Return code for this function */
+-  DWORD lastErrno;
+-
+-  assert( pFile );
+-  SimulateIOError(return SQLITE_IOERR_TRUNCATE);
+-  OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, size=%lld, lock=%d\n",
+-           osGetCurrentProcessId(), pFile, pFile->h, nByte, pFile->locktype));
++static char *winUnicodeToMbcs(LPCWSTR zWideFilename){
++  int nByte;
++  char *zFilename;
++  int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
+ 
+-  /* If the user has configured a chunk-size for this file, truncate the
+-  ** file so that it consists of an integer number of chunks (i.e. the
+-  ** actual file size after the operation may be larger than the requested
+-  ** size).
+-  */
+-  if( pFile->szChunk>0 ){
+-    nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
++  nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
++  if( nByte == 0 ){
++    return 0;
+   }
+-
+-  /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
+-  if( winSeekFile(pFile, nByte) ){
+-    rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
+-                     "winTruncate1", pFile->zPath);
+-  }else if( 0==osSetEndOfFile(pFile->h) &&
+-            ((lastErrno = osGetLastError())!=ERROR_USER_MAPPED_FILE) ){
+-    pFile->lastErrno = lastErrno;
+-    rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
+-                     "winTruncate2", pFile->zPath);
++  zFilename = sqlite3MallocZero( nByte );
++  if( zFilename==0 ){
++    return 0;
+   }
+-
+-#if SQLITE_MAX_MMAP_SIZE>0
+-  /* If the file was truncated to a size smaller than the currently
+-  ** mapped region, reduce the effective mapping size as well. SQLite will
+-  ** use read() and write() to access data beyond this point from now on.
+-  */
+-  if( pFile->pMapRegion && nByte<pFile->mmapSize ){
+-    pFile->mmapSize = nByte;
++  nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename,
++                                nByte, 0, 0);
++  if( nByte == 0 ){
++    sqlite3_free(zFilename);
++    zFilename = 0;
+   }
+-#endif
+-
+-  OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, rc=%s\n",
+-           osGetCurrentProcessId(), pFile, pFile->h, sqlite3ErrName(rc)));
+-  return rc;
++  return zFilename;
+ }
+ 
+-#ifdef SQLITE_TEST
+ /*
+-** Count the number of fullsyncs and normal syncs.  This is used to test
+-** that syncs and fullsyncs are occuring at the right times.
++** Convert multibyte character string to UTF-8.  Space to hold the
++** returned string is obtained from sqlite3_malloc().
+ */
+-SQLITE_API int sqlite3_sync_count = 0;
+-SQLITE_API int sqlite3_fullsync_count = 0;
+-#endif
++SQLITE_API char *SQLITE_STDCALL sqlite3_win32_mbcs_to_utf8(const char *zFilename){
++  char *zFilenameUtf8;
++  LPWSTR zTmpWide;
 +
-+/* BEGIN SQLCIPHER */
++  zTmpWide = winMbcsToUnicode(zFilename);
++  if( zTmpWide==0 ){
++    return 0;
++  }
++  zFilenameUtf8 = winUnicodeToUtf8(zTmpWide);
++  sqlite3_free(zTmpWide);
++  return zFilenameUtf8;
++}
+ 
+ /*
+-** Make sure all writes to a particular file are committed to disk.
++** Convert UTF-8 to multibyte character string.  Space to hold the
++** returned string is obtained from sqlite3_malloc().
+ */
+-static int winSync(sqlite3_file *id, int flags){
+-#ifndef SQLITE_NO_SYNC
+-  /*
+-  ** Used only when SQLITE_NO_SYNC is not defined.
+-   */
+-  BOOL rc;
+-#endif
+-#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \
+-    defined(SQLITE_HAVE_OS_TRACE)
+-  /*
+-  ** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or
+-  ** OSTRACE() macros.
+-   */
+-  winFile *pFile = (winFile*)id;
+-#else
+-  UNUSED_PARAMETER(id);
+-#endif
+-
+-  assert( pFile );
+-  /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */
+-  assert((flags&0x0F)==SQLITE_SYNC_NORMAL
+-      || (flags&0x0F)==SQLITE_SYNC_FULL
+-  );
+-
+-  /* Unix cannot, but some systems may return SQLITE_FULL from here. This
+-  ** line is to test that doing so does not cause any problems.
+-  */
+-  SimulateDiskfullError( return SQLITE_FULL );
+-
+-  OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, flags=%x, lock=%d\n",
+-           osGetCurrentProcessId(), pFile, pFile->h, flags,
+-           pFile->locktype));
++SQLITE_API char *SQLITE_STDCALL sqlite3_win32_utf8_to_mbcs(const char *zFilename){
++  char *zFilenameMbcs;
++  LPWSTR zTmpWide;
+ 
+-#ifndef SQLITE_TEST
+-  UNUSED_PARAMETER(flags);
+-#else
+-  if( (flags&0x0F)==SQLITE_SYNC_FULL ){
+-    sqlite3_fullsync_count++;
++  zTmpWide = winUtf8ToUnicode(zFilename);
++  if( zTmpWide==0 ){
++    return 0;
+   }
+-  sqlite3_sync_count++;
+-#endif
++  zFilenameMbcs = winUnicodeToMbcs(zTmpWide);
++  sqlite3_free(zTmpWide);
++  return zFilenameMbcs;
++}
+ 
+-  /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
+-  ** no-op
+-  */
+-#ifdef SQLITE_NO_SYNC
+-  OSTRACE(("SYNC-NOP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
+-           osGetCurrentProcessId(), pFile, pFile->h));
+-  return SQLITE_OK;
+-#else
+-#if SQLITE_MAX_MMAP_SIZE>0
+-  if( pFile->pMapRegion ){
+-    if( osFlushViewOfFile(pFile->pMapRegion, 0) ){
+-      OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, "
+-               "rc=SQLITE_OK\n", osGetCurrentProcessId(),
+-               pFile, pFile->pMapRegion));
+-    }else{
+-      pFile->lastErrno = osGetLastError();
+-      OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, "
+-               "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(),
+-               pFile, pFile->pMapRegion));
+-      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
+-                         "winSync1", pFile->zPath);
+-    }
+-  }
++/*
++** This function sets the data directory or the temporary directory based on
++** the provided arguments.  The type argument must be 1 in order to set the
++** data directory or 2 in order to set the temporary directory.  The zValue
++** argument is the name of the directory to use.  The return value will be
++** SQLITE_OK if successful.
++*/
++SQLITE_API int SQLITE_STDCALL sqlite3_win32_set_directory(DWORD type, LPCWSTR zValue){
++  char **ppDirectory = 0;
++#ifndef SQLITE_OMIT_AUTOINIT
++  int rc = sqlite3_initialize();
++  if( rc ) return rc;
+ #endif
+-  rc = osFlushFileBuffers(pFile->h);
+-  SimulateIOError( rc=FALSE );
+-  if( rc ){
+-    OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
+-             osGetCurrentProcessId(), pFile, pFile->h));
++  if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){
++    ppDirectory = &sqlite3_data_directory;
++  }else if( type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE ){
++    ppDirectory = &sqlite3_temp_directory;
++  }
++  assert( !ppDirectory || type==SQLITE_WIN32_DATA_DIRECTORY_TYPE
++          || type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE
++  );
++  assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) );
++  if( ppDirectory ){
++    char *zValueUtf8 = 0;
++    if( zValue && zValue[0] ){
++      zValueUtf8 = winUnicodeToUtf8(zValue);
++      if ( zValueUtf8==0 ){
++        return SQLITE_NOMEM;
++      }
++    }
++    sqlite3_free(*ppDirectory);
++    *ppDirectory = zValueUtf8;
+     return SQLITE_OK;
+-  }else{
+-    pFile->lastErrno = osGetLastError();
+-    OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_FSYNC\n",
+-             osGetCurrentProcessId(), pFile, pFile->h));
+-    return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno,
+-                       "winSync2", pFile->zPath);
+   }
+-#endif
++  return SQLITE_ERROR;
+ }
+ 
+ /*
+-** Determine the current size of a file in bytes
++** The return value of winGetLastErrorMsg
++** is zero if the error message fits in the buffer, or non-zero
++** otherwise (if the message was truncated).
+ */
+-static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
+-  winFile *pFile = (winFile*)id;
+-  int rc = SQLITE_OK;
+-
+-  assert( id!=0 );
+-  assert( pSize!=0 );
+-  SimulateIOError(return SQLITE_IOERR_FSTAT);
+-  OSTRACE(("SIZE file=%p, pSize=%p\n", pFile->h, pSize));
++static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){
++  /* FormatMessage returns 0 on failure.  Otherwise it
++  ** returns the number of TCHARs written to the output
++  ** buffer, excluding the terminating null char.
++  */
++  DWORD dwLen = 0;
++  char *zOut = 0;
+ 
++  if( osIsNT() ){
+ #if SQLITE_OS_WINRT
+-  {
+-    FILE_STANDARD_INFO info;
+-    if( osGetFileInformationByHandleEx(pFile->h, FileStandardInfo,
+-                                     &info, sizeof(info)) ){
+-      *pSize = info.EndOfFile.QuadPart;
+-    }else{
+-      pFile->lastErrno = osGetLastError();
+-      rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
+-                       "winFileSize", pFile->zPath);
++    WCHAR zTempWide[SQLITE_WIN32_MAX_ERRMSG_CHARS+1];
++    dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
++                             FORMAT_MESSAGE_IGNORE_INSERTS,
++                             NULL,
++                             lastErrno,
++                             0,
++                             zTempWide,
++                             SQLITE_WIN32_MAX_ERRMSG_CHARS,
++                             0);
++#else
++    LPWSTR zTempWide = NULL;
++    dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
++                             FORMAT_MESSAGE_FROM_SYSTEM |
++                             FORMAT_MESSAGE_IGNORE_INSERTS,
++                             NULL,
++                             lastErrno,
++                             0,
++                             (LPWSTR) &zTempWide,
++                             0,
++                             0);
++#endif
++    if( dwLen > 0 ){
++      /* allocate a buffer and convert to UTF8 */
++      sqlite3BeginBenignMalloc();
++      zOut = winUnicodeToUtf8(zTempWide);
++      sqlite3EndBenignMalloc();
++#if !SQLITE_OS_WINRT
++      /* free the system buffer allocated by FormatMessage */
++      osLocalFree(zTempWide);
++#endif
+     }
+   }
+-#else
+-  {
+-    DWORD upperBits;
+-    DWORD lowerBits;
+-    DWORD lastErrno;
+-
+-    lowerBits = osGetFileSize(pFile->h, &upperBits);
+-    *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
+-    if(   (lowerBits == INVALID_FILE_SIZE)
+-       && ((lastErrno = osGetLastError())!=NO_ERROR) ){
+-      pFile->lastErrno = lastErrno;
+-      rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
+-                       "winFileSize", pFile->zPath);
++#ifdef SQLITE_WIN32_HAS_ANSI
++  else{
++    char *zTemp = NULL;
++    dwLen = osFormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
++                             FORMAT_MESSAGE_FROM_SYSTEM |
++                             FORMAT_MESSAGE_IGNORE_INSERTS,
++                             NULL,
++                             lastErrno,
++                             0,
++                             (LPSTR) &zTemp,
++                             0,
++                             0);
++    if( dwLen > 0 ){
++      /* allocate a buffer and convert to UTF8 */
++      sqlite3BeginBenignMalloc();
++      zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
++      sqlite3EndBenignMalloc();
++      /* free the system buffer allocated by FormatMessage */
++      osLocalFree(zTemp);
+     }
+   }
+ #endif
+-  OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n",
+-           pFile->h, pSize, *pSize, sqlite3ErrName(rc)));
+-  return rc;
++  if( 0 == dwLen ){
++    sqlite3_snprintf(nBuf, zBuf, "OsError 0x%lx (%lu)", lastErrno, lastErrno);
++  }else{
++    /* copy a maximum of nBuf chars to output buffer */
++    sqlite3_snprintf(nBuf, zBuf, "%s", zOut);
++    /* free the UTF8 buffer */
++    sqlite3_free(zOut);
++  }
++  return 0;
+ }
+ 
+ /*
+-** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
++**
++** This function - winLogErrorAtLine() - is only ever called via the macro
++** winLogError().
++**
++** This routine is invoked after an error occurs in an OS function.
++** It logs a message using sqlite3_log() containing the current value of
++** error code and, if possible, the human-readable equivalent from
++** FormatMessage.
++**
++** The first argument passed to the macro should be the error code that
++** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN).
++** The two subsequent arguments should be the name of the OS function that
++** failed and the associated file-system path, if any.
+ */
+-#ifndef LOCKFILE_FAIL_IMMEDIATELY
+-# define LOCKFILE_FAIL_IMMEDIATELY 1
+-#endif
++#define winLogError(a,b,c,d)   winLogErrorAtLine(a,b,c,d,__LINE__)
++static int winLogErrorAtLine(
++  int errcode,                    /* SQLite error code */
++  DWORD lastErrno,                /* Win32 last error */
++  const char *zFunc,              /* Name of OS function that failed */
++  const char *zPath,              /* File path associated with error */
++  int iLine                       /* Source line number where error occurred */
++){
++  char zMsg[500];                 /* Human readable error text */
++  int i;                          /* Loop counter */
+ 
+-#ifndef LOCKFILE_EXCLUSIVE_LOCK
+-# define LOCKFILE_EXCLUSIVE_LOCK 2
+-#endif
++  zMsg[0] = 0;
++  winGetLastErrorMsg(lastErrno, sizeof(zMsg), zMsg);
++  assert( errcode!=SQLITE_OK );
++  if( zPath==0 ) zPath = "";
++  for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){}
++  zMsg[i] = 0;
++  sqlite3_log(errcode,
++      "os_win.c:%d: (%lu) %s(%s) - %s",
++      iLine, lastErrno, zFunc, zPath, zMsg
++  );
++
++  return errcode;
++}
+ 
+ /*
+-** Historically, SQLite has used both the LockFile and LockFileEx functions.
+-** When the LockFile function was used, it was always expected to fail
+-** immediately if the lock could not be obtained.  Also, it always expected to
+-** obtain an exclusive lock.  These flags are used with the LockFileEx function
+-** and reflect those expectations; therefore, they should not be changed.
++** The number of times that a ReadFile(), WriteFile(), and DeleteFile()
++** will be retried following a locking error - probably caused by
++** antivirus software.  Also the initial delay before the first retry.
++** The delay increases linearly with each retry.
+ */
+-#ifndef SQLITE_LOCKFILE_FLAGS
+-# define SQLITE_LOCKFILE_FLAGS   (LOCKFILE_FAIL_IMMEDIATELY | \
+-                                  LOCKFILE_EXCLUSIVE_LOCK)
++#ifndef SQLITE_WIN32_IOERR_RETRY
++# define SQLITE_WIN32_IOERR_RETRY 10
++#endif
++#ifndef SQLITE_WIN32_IOERR_RETRY_DELAY
++# define SQLITE_WIN32_IOERR_RETRY_DELAY 25
+ #endif
++static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY;
++static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY;
+ 
+ /*
+-** Currently, SQLite never calls the LockFileEx function without wanting the
+-** call to fail immediately if the lock cannot be obtained.
++** The "winIoerrCanRetry1" macro is used to determine if a particular I/O
++** error code obtained via GetLastError() is eligible to be retried.  It
++** must accept the error code DWORD as its only argument and should return
++** non-zero if the error code is transient in nature and the operation
++** responsible for generating the original error might succeed upon being
++** retried.  The argument to this macro should be a variable.
++**
++** Additionally, a macro named "winIoerrCanRetry2" may be defined.  If it
++** is defined, it will be consulted only when the macro "winIoerrCanRetry1"
++** returns zero.  The "winIoerrCanRetry2" macro is completely optional and
++** may be used to include additional error codes in the set that should
++** result in the failing I/O operation being retried by the caller.  If
++** defined, the "winIoerrCanRetry2" macro must exhibit external semantics
++** identical to those of the "winIoerrCanRetry1" macro.
+ */
+-#ifndef SQLITE_LOCKFILEEX_FLAGS
+-# define SQLITE_LOCKFILEEX_FLAGS (LOCKFILE_FAIL_IMMEDIATELY)
++#if !defined(winIoerrCanRetry1)
++#define winIoerrCanRetry1(a) (((a)==ERROR_ACCESS_DENIED)        || \
++                              ((a)==ERROR_SHARING_VIOLATION)    || \
++                              ((a)==ERROR_LOCK_VIOLATION)       || \
++                              ((a)==ERROR_DEV_NOT_EXIST)        || \
++                              ((a)==ERROR_NETNAME_DELETED)      || \
++                              ((a)==ERROR_SEM_TIMEOUT)          || \
++                              ((a)==ERROR_NETWORK_UNREACHABLE))
+ #endif
+ 
+ /*
+-** Acquire a reader lock.
+-** Different API routines are called depending on whether or not this
+-** is Win9x or WinNT.
++** If a ReadFile() or WriteFile() error occurs, invoke this routine
++** to see if it should be retried.  Return TRUE to retry.  Return FALSE
++** to give up with an error.
+ */
+-static int winGetReadLock(winFile *pFile){
+-  int res;
+-  OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
+-  if( osIsNT() ){
+-#if SQLITE_OS_WINCE
+-    /*
+-    ** NOTE: Windows CE is handled differently here due its lack of the Win32
+-    **       API LockFileEx.
+-    */
+-    res = winceLockFile(&pFile->h, SHARED_FIRST, 0, 1, 0);
+-#else
+-    res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS, SHARED_FIRST, 0,
+-                      SHARED_SIZE, 0);
+-#endif
++static int winRetryIoerr(int *pnRetry, DWORD *pError){
++  DWORD e = osGetLastError();
++  if( *pnRetry>=winIoerrRetry ){
++    if( pError ){
++      *pError = e;
++    }
++    return 0;
+   }
+-#ifdef SQLITE_WIN32_HAS_ANSI
+-  else{
+-    int lk;
+-    sqlite3_randomness(sizeof(lk), &lk);
+-    pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1));
+-    res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
+-                      SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
++  if( winIoerrCanRetry1(e) ){
++    sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry));
++    ++*pnRetry;
++    return 1;
++  }
++#if defined(winIoerrCanRetry2)
++  else if( winIoerrCanRetry2(e) ){
++    sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry));
++    ++*pnRetry;
++    return 1;
+   }
+ #endif
+-  if( res == 0 ){
+-    pFile->lastErrno = osGetLastError();
+-    /* No need to log a failure to lock */
++  if( pError ){
++    *pError = e;
+   }
+-  OSTRACE(("READ-LOCK file=%p, result=%d\n", pFile->h, res));
+-  return res;
++  return 0;
+ }
+ 
+ /*
+-** Undo a readlock
++** Log a I/O error retry episode.
+ */
+-static int winUnlockReadLock(winFile *pFile){
+-  int res;
+-  DWORD lastErrno;
+-  OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
+-  if( osIsNT() ){
+-    res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
+-  }
+-#ifdef SQLITE_WIN32_HAS_ANSI
+-  else{
+-    res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
+-  }
+-#endif
+-  if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){
+-    pFile->lastErrno = lastErrno;
+-    winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno,
+-                "winUnlockReadLock", pFile->zPath);
++static void winLogIoerr(int nRetry, int lineno){
++  if( nRetry ){
++    sqlite3_log(SQLITE_NOTICE,
++      "delayed %dms for lock/sharing conflict at line %d",
++      winIoerrRetryDelay*nRetry*(nRetry+1)/2, lineno
++    );
+   }
+-  OSTRACE(("READ-UNLOCK file=%p, result=%d\n", pFile->h, res));
+-  return res;
+ }
+ 
++#if SQLITE_OS_WINCE
++/*************************************************************************
++** This section contains code for WinCE only.
++*/
++#if !defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API
+ /*
+-** Lock the file with the lock specified by parameter locktype - one
+-** of the following:
+-**
+-**     (1) SHARED_LOCK
+-**     (2) RESERVED_LOCK
+-**     (3) PENDING_LOCK
+-**     (4) EXCLUSIVE_LOCK
+-**
+-** Sometimes when requesting one lock state, additional lock states
+-** are inserted in between.  The locking might fail on one of the later
+-** transitions leaving the lock state different from what it started but
+-** still short of its goal.  The following chart shows the allowed
+-** transitions and the inserted intermediate states:
+-**
+-**    UNLOCKED -> SHARED
+-**    SHARED -> RESERVED
+-**    SHARED -> (PENDING) -> EXCLUSIVE
+-**    RESERVED -> (PENDING) -> EXCLUSIVE
+-**    PENDING -> EXCLUSIVE
+-**
+-** This routine will only increase a lock.  The winUnlock() routine
+-** erases all locks at once and returns us immediately to locking level 0.
+-** It is not possible to lower the locking level one step at a time.  You
+-** must go straight to locking level 0.
++** The MSVC CRT on Windows CE may not have a localtime() function.  So
++** create a substitute.
+ */
+-static int winLock(sqlite3_file *id, int locktype){
+-  int rc = SQLITE_OK;    /* Return code from subroutines */
+-  int res = 1;           /* Result of a Windows lock call */
+-  int newLocktype;       /* Set pFile->locktype to this value before exiting */
+-  int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
+-  winFile *pFile = (winFile*)id;
+-  DWORD lastErrno = NO_ERROR;
++/* #include <time.h> */
++struct tm *__cdecl localtime(const time_t *t)
++{
++  static struct tm y;
++  FILETIME uTm, lTm;
++  SYSTEMTIME pTm;
++  sqlite3_int64 t64;
++  t64 = *t;
++  t64 = (t64 + 11644473600)*10000000;
++  uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF);
++  uTm.dwHighDateTime= (DWORD)(t64 >> 32);
++  osFileTimeToLocalFileTime(&uTm,&lTm);
++  osFileTimeToSystemTime(&lTm,&pTm);
++  y.tm_year = pTm.wYear - 1900;
++  y.tm_mon = pTm.wMonth - 1;
++  y.tm_wday = pTm.wDayOfWeek;
++  y.tm_mday = pTm.wDay;
++  y.tm_hour = pTm.wHour;
++  y.tm_min = pTm.wMinute;
++  y.tm_sec = pTm.wSecond;
++  return &y;
++}
++#endif
+ 
+-  assert( id!=0 );
+-  OSTRACE(("LOCK file=%p, oldLock=%d(%d), newLock=%d\n",
+-           pFile->h, pFile->locktype, pFile->sharedLockByte, locktype));
++#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]
+ 
+-  /* If there is already a lock of this type or more restrictive on the
+-  ** OsFile, do nothing. Don't use the end_lock: exit path, as
+-  ** sqlite3OsEnterMutex() hasn't been called yet.
+-  */
+-  if( pFile->locktype>=locktype ){
+-    OSTRACE(("LOCK-HELD file=%p, rc=SQLITE_OK\n", pFile->h));
+-    return SQLITE_OK;
++/*
++** Acquire a lock on the handle h
++*/
++static void winceMutexAcquire(HANDLE h){
++   DWORD dwErr;
++   do {
++     dwErr = osWaitForSingleObject(h, INFINITE);
++   } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);
++}
++/*
++** Release a lock acquired by winceMutexAcquire()
++*/
++#define winceMutexRelease(h) ReleaseMutex(h)
++
++/*
++** Create the mutex and shared memory used for locking in the file
++** descriptor pFile
++*/
++static int winceCreateLock(const char *zFilename, winFile *pFile){
++  LPWSTR zTok;
++  LPWSTR zName;
++  DWORD lastErrno;
++  BOOL bLogged = FALSE;
++  BOOL bInit = TRUE;
++
++  zName = winUtf8ToUnicode(zFilename);
++  if( zName==0 ){
++    /* out of memory */
++    return SQLITE_IOERR_NOMEM;
+   }
+ 
+-  /* Make sure the locking sequence is correct
+-  */
+-  assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
+-  assert( locktype!=PENDING_LOCK );
+-  assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
++  /* Initialize the local lockdata */
++  memset(&pFile->local, 0, sizeof(pFile->local));
+ 
+-  /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
+-  ** a SHARED lock.  If we are acquiring a SHARED lock, the acquisition of
+-  ** the PENDING_LOCK byte is temporary.
+-  */
+-  newLocktype = pFile->locktype;
+-  if(   (pFile->locktype==NO_LOCK)
+-     || (   (locktype==EXCLUSIVE_LOCK)
+-         && (pFile->locktype==RESERVED_LOCK))
+-  ){
+-    int cnt = 3;
+-    while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
+-                                         PENDING_BYTE, 0, 1, 0))==0 ){
+-      /* Try 3 times to get the pending lock.  This is needed to work
+-      ** around problems caused by indexing and/or anti-virus software on
+-      ** Windows systems.
+-      ** If you are using this code as a model for alternative VFSes, do not
+-      ** copy this retry logic.  It is a hack intended for Windows only.
+-      */
+-      lastErrno = osGetLastError();
+-      OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, result=%d\n",
+-               pFile->h, cnt, res));
+-      if( lastErrno==ERROR_INVALID_HANDLE ){
+-        pFile->lastErrno = lastErrno;
+-        rc = SQLITE_IOERR_LOCK;
+-        OSTRACE(("LOCK-FAIL file=%p, count=%d, rc=%s\n",
+-                 pFile->h, cnt, sqlite3ErrName(rc)));
+-        return rc;
+-      }
+-      if( cnt ) sqlite3_win32_sleep(1);
+-    }
+-    gotPendingLock = res;
+-    if( !res ){
+-      lastErrno = osGetLastError();
+-    }
++  /* Replace the backslashes from the filename and lowercase it
++  ** to derive a mutex name. */
++  zTok = osCharLowerW(zName);
++  for (;*zTok;zTok++){
++    if (*zTok == '\\') *zTok = '_';
+   }
+ 
+-  /* Acquire a shared lock
+-  */
+-  if( locktype==SHARED_LOCK && res ){
+-    assert( pFile->locktype==NO_LOCK );
+-    res = winGetReadLock(pFile);
+-    if( res ){
+-      newLocktype = SHARED_LOCK;
+-    }else{
+-      lastErrno = osGetLastError();
+-    }
++  /* Create/open the named mutex */
++  pFile->hMutex = osCreateMutexW(NULL, FALSE, zName);
++  if (!pFile->hMutex){
++    pFile->lastErrno = osGetLastError();
++    sqlite3_free(zName);
++    return winLogError(SQLITE_IOERR, pFile->lastErrno,
++                       "winceCreateLock1", zFilename);
+   }
+ 
+-  /* Acquire a RESERVED lock
+-  */
+-  if( locktype==RESERVED_LOCK && res ){
+-    assert( pFile->locktype==SHARED_LOCK );
+-    res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0);
+-    if( res ){
+-      newLocktype = RESERVED_LOCK;
+-    }else{
+-      lastErrno = osGetLastError();
+-    }
+-  }
++  /* Acquire the mutex before continuing */
++  winceMutexAcquire(pFile->hMutex);
+ 
+-  /* Acquire a PENDING lock
++  /* Since the names of named mutexes, semaphores, file mappings etc are
++  ** case-sensitive, take advantage of that by uppercasing the mutex name
++  ** and using that as the shared filemapping name.
+   */
+-  if( locktype==EXCLUSIVE_LOCK && res ){
+-    newLocktype = PENDING_LOCK;
+-    gotPendingLock = 0;
++  osCharUpperW(zName);
++  pFile->hShared = osCreateFileMappingW(INVALID_HANDLE_VALUE, NULL,
++                                        PAGE_READWRITE, 0, sizeof(winceLock),
++                                        zName);
++
++  /* Set a flag that indicates we're the first to create the memory so it
++  ** must be zero-initialized */
++  lastErrno = osGetLastError();
++  if (lastErrno == ERROR_ALREADY_EXISTS){
++    bInit = FALSE;
+   }
+ 
+-  /* Acquire an EXCLUSIVE lock
+-  */
+-  if( locktype==EXCLUSIVE_LOCK && res ){
+-    assert( pFile->locktype>=SHARED_LOCK );
+-    res = winUnlockReadLock(pFile);
+-    res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0,
+-                      SHARED_SIZE, 0);
+-    if( res ){
+-      newLocktype = EXCLUSIVE_LOCK;
+-    }else{
+-      lastErrno = osGetLastError();
+-      winGetReadLock(pFile);
++  sqlite3_free(zName);
++
++  /* If we succeeded in making the shared memory handle, map it. */
++  if( pFile->hShared ){
++    pFile->shared = (winceLock*)osMapViewOfFile(pFile->hShared,
++             FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
++    /* If mapping failed, close the shared memory handle and erase it */
++    if( !pFile->shared ){
++      pFile->lastErrno = osGetLastError();
++      winLogError(SQLITE_IOERR, pFile->lastErrno,
++                  "winceCreateLock2", zFilename);
++      bLogged = TRUE;
++      osCloseHandle(pFile->hShared);
++      pFile->hShared = NULL;
+     }
+   }
+ 
+-  /* If we are holding a PENDING lock that ought to be released, then
+-  ** release it now.
+-  */
+-  if( gotPendingLock && locktype==SHARED_LOCK ){
+-    winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
++  /* If shared memory could not be created, then close the mutex and fail */
++  if( pFile->hShared==NULL ){
++    if( !bLogged ){
++      pFile->lastErrno = lastErrno;
++      winLogError(SQLITE_IOERR, pFile->lastErrno,
++                  "winceCreateLock3", zFilename);
++      bLogged = TRUE;
++    }
++    winceMutexRelease(pFile->hMutex);
++    osCloseHandle(pFile->hMutex);
++    pFile->hMutex = NULL;
++    return SQLITE_IOERR;
+   }
+ 
+-  /* Update the state of the lock has held in the file descriptor then
+-  ** return the appropriate result code.
+-  */
+-  if( res ){
+-    rc = SQLITE_OK;
+-  }else{
+-    pFile->lastErrno = lastErrno;
+-    rc = SQLITE_BUSY;
+-    OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n",
+-             pFile->h, locktype, newLocktype));
++  /* Initialize the shared memory if we're supposed to */
++  if( bInit ){
++    memset(pFile->shared, 0, sizeof(winceLock));
+   }
+-  pFile->locktype = (u8)newLocktype;
+-  OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n",
+-           pFile->h, pFile->locktype, sqlite3ErrName(rc)));
+-  return rc;
++
++  winceMutexRelease(pFile->hMutex);
++  return SQLITE_OK;
+ }
+ 
+ /*
+-** This routine checks if there is a RESERVED lock held on the specified
+-** file by this or any other process. If such a lock is held, return
+-** non-zero, otherwise zero.
++** Destroy the part of winFile that deals with wince locks
+ */
+-static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
+-  int res;
+-  winFile *pFile = (winFile*)id;
+-
+-  SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
+-  OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p\n", pFile->h, pResOut));
++static void winceDestroyLock(winFile *pFile){
++  if (pFile->hMutex){
++    /* Acquire the mutex */
++    winceMutexAcquire(pFile->hMutex);
+ 
+-  assert( id!=0 );
+-  if( pFile->locktype>=RESERVED_LOCK ){
+-    res = 1;
+-    OSTRACE(("TEST-WR-LOCK file=%p, result=%d (local)\n", pFile->h, res));
+-  }else{
+-    res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE, 0, 1, 0);
+-    if( res ){
+-      winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
++    /* The following blocks should probably assert in debug mode, but they
++       are to cleanup in case any locks remained open */
++    if (pFile->local.nReaders){
++      pFile->shared->nReaders --;
+     }
+-    res = !res;
+-    OSTRACE(("TEST-WR-LOCK file=%p, result=%d (remote)\n", pFile->h, res));
++    if (pFile->local.bReserved){
++      pFile->shared->bReserved = FALSE;
++    }
++    if (pFile->local.bPending){
++      pFile->shared->bPending = FALSE;
++    }
++    if (pFile->local.bExclusive){
++      pFile->shared->bExclusive = FALSE;
++    }
++
++    /* De-reference and close our copy of the shared memory handle */
++    osUnmapViewOfFile(pFile->shared);
++    osCloseHandle(pFile->hShared);
++
++    /* Done with the mutex */
++    winceMutexRelease(pFile->hMutex);
++    osCloseHandle(pFile->hMutex);
++    pFile->hMutex = NULL;
+   }
+-  *pResOut = res;
+-  OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
+-           pFile->h, pResOut, *pResOut));
+-  return SQLITE_OK;
+ }
+ 
+ /*
+-** Lower the locking level on file descriptor id to locktype.  locktype
+-** must be either NO_LOCK or SHARED_LOCK.
+-**
+-** If the locking level of the file descriptor is already at or below
+-** the requested locking level, this routine is a no-op.
+-**
+-** It is not possible for this routine to fail if the second argument
+-** is NO_LOCK.  If the second argument is SHARED_LOCK then this routine
+-** might return SQLITE_IOERR;
++** An implementation of the LockFile() API of Windows for CE
+ */
+-static int winUnlock(sqlite3_file *id, int locktype){
+-  int type;
+-  winFile *pFile = (winFile*)id;
+-  int rc = SQLITE_OK;
+-  assert( pFile!=0 );
+-  assert( locktype<=SHARED_LOCK );
+-  OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n",
+-           pFile->h, pFile->locktype, pFile->sharedLockByte, locktype));
+-  type = pFile->locktype;
+-  if( type>=EXCLUSIVE_LOCK ){
+-    winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
+-    if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){
+-      /* This should never happen.  We should always be able to
+-      ** reacquire the read lock */
+-      rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(),
+-                       "winUnlock", pFile->zPath);
++static BOOL winceLockFile(
++  LPHANDLE phFile,
++  DWORD dwFileOffsetLow,
++  DWORD dwFileOffsetHigh,
++  DWORD nNumberOfBytesToLockLow,
++  DWORD nNumberOfBytesToLockHigh
++){
++  winFile *pFile = HANDLE_TO_WINFILE(phFile);
++  BOOL bReturn = FALSE;
++
++  UNUSED_PARAMETER(dwFileOffsetHigh);
++  UNUSED_PARAMETER(nNumberOfBytesToLockHigh);
++
++  if (!pFile->hMutex) return TRUE;
++  winceMutexAcquire(pFile->hMutex);
++
++  /* Wanting an exclusive lock? */
++  if (dwFileOffsetLow == (DWORD)SHARED_FIRST
++       && nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){
++    if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){
++       pFile->shared->bExclusive = TRUE;
++       pFile->local.bExclusive = TRUE;
++       bReturn = TRUE;
+     }
+   }
+-  if( type>=RESERVED_LOCK ){
+-    winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
++
++  /* Want a read-only lock? */
++  else if (dwFileOffsetLow == (DWORD)SHARED_FIRST &&
++           nNumberOfBytesToLockLow == 1){
++    if (pFile->shared->bExclusive == 0){
++      pFile->local.nReaders ++;
++      if (pFile->local.nReaders == 1){
++        pFile->shared->nReaders ++;
++      }
++      bReturn = TRUE;
++    }
+   }
+-  if( locktype==NO_LOCK && type>=SHARED_LOCK ){
+-    winUnlockReadLock(pFile);
++
++  /* Want a pending lock? */
++  else if (dwFileOffsetLow == (DWORD)PENDING_BYTE
++           && nNumberOfBytesToLockLow == 1){
++    /* If no pending lock has been acquired, then acquire it */
++    if (pFile->shared->bPending == 0) {
++      pFile->shared->bPending = TRUE;
++      pFile->local.bPending = TRUE;
++      bReturn = TRUE;
++    }
+   }
+-  if( type>=PENDING_LOCK ){
+-    winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
++
++  /* Want a reserved lock? */
++  else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE
++           && nNumberOfBytesToLockLow == 1){
++    if (pFile->shared->bReserved == 0) {
++      pFile->shared->bReserved = TRUE;
++      pFile->local.bReserved = TRUE;
++      bReturn = TRUE;
++    }
+   }
+-  pFile->locktype = (u8)locktype;
+-  OSTRACE(("UNLOCK file=%p, lock=%d, rc=%s\n",
+-           pFile->h, pFile->locktype, sqlite3ErrName(rc)));
+-  return rc;
++
++  winceMutexRelease(pFile->hMutex);
++  return bReturn;
+ }
+ 
+ /*
+-** If *pArg is initially negative then this is a query.  Set *pArg to
+-** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.
+-**
+-** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags.
++** An implementation of the UnlockFile API of Windows for CE
+ */
+-static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){
+-  if( *pArg<0 ){
+-    *pArg = (pFile->ctrlFlags & mask)!=0;
+-  }else if( (*pArg)==0 ){
+-    pFile->ctrlFlags &= ~mask;
+-  }else{
+-    pFile->ctrlFlags |= mask;
+-  }
+-}
++static BOOL winceUnlockFile(
++  LPHANDLE phFile,
++  DWORD dwFileOffsetLow,
++  DWORD dwFileOffsetHigh,
++  DWORD nNumberOfBytesToUnlockLow,
++  DWORD nNumberOfBytesToUnlockHigh
++){
++  winFile *pFile = HANDLE_TO_WINFILE(phFile);
++  BOOL bReturn = FALSE;
+ 
+-/* Forward references to VFS helper methods used for temporary files */
+-static int winGetTempname(sqlite3_vfs *, char **);
+-static int winIsDir(const void *);
+-static BOOL winIsDriveLetterAndColon(const char *);
++  UNUSED_PARAMETER(dwFileOffsetHigh);
++  UNUSED_PARAMETER(nNumberOfBytesToUnlockHigh);
+ 
+-/*
+-** Control and query of the open file handle.
+-*/
+-static int winFileControl(sqlite3_file *id, int op, void *pArg){
+-  winFile *pFile = (winFile*)id;
+-  OSTRACE(("FCNTL file=%p, op=%d, pArg=%p\n", pFile->h, op, pArg));
+-  switch( op ){
+-    case SQLITE_FCNTL_LOCKSTATE: {
+-      *(int*)pArg = pFile->locktype;
+-      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
+-      return SQLITE_OK;
+-    }
+-    case SQLITE_LAST_ERRNO: {
+-      *(int*)pArg = (int)pFile->lastErrno;
+-      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
+-      return SQLITE_OK;
+-    }
+-    case SQLITE_FCNTL_CHUNK_SIZE: {
+-      pFile->szChunk = *(int *)pArg;
+-      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
+-      return SQLITE_OK;
+-    }
+-    case SQLITE_FCNTL_SIZE_HINT: {
+-      if( pFile->szChunk>0 ){
+-        sqlite3_int64 oldSz;
+-        int rc = winFileSize(id, &oldSz);
+-        if( rc==SQLITE_OK ){
+-          sqlite3_int64 newSz = *(sqlite3_int64*)pArg;
+-          if( newSz>oldSz ){
+-            SimulateIOErrorBenign(1);
+-            rc = winTruncate(id, newSz);
+-            SimulateIOErrorBenign(0);
+-          }
+-        }
+-        OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
+-        return rc;
+-      }
+-      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
+-      return SQLITE_OK;
+-    }
+-    case SQLITE_FCNTL_PERSIST_WAL: {
+-      winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg);
+-      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
+-      return SQLITE_OK;
+-    }
+-    case SQLITE_FCNTL_POWERSAFE_OVERWRITE: {
+-      winModeBit(pFile, WINFILE_PSOW, (int*)pArg);
+-      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
+-      return SQLITE_OK;
+-    }
+-    case SQLITE_FCNTL_VFSNAME: {
+-      *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
+-      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
+-      return SQLITE_OK;
++  if (!pFile->hMutex) return TRUE;
++  winceMutexAcquire(pFile->hMutex);
++
++  /* Releasing a reader lock or an exclusive lock */
++  if (dwFileOffsetLow == (DWORD)SHARED_FIRST){
++    /* Did we have an exclusive lock? */
++    if (pFile->local.bExclusive){
++      assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE);
++      pFile->local.bExclusive = FALSE;
++      pFile->shared->bExclusive = FALSE;
++      bReturn = TRUE;
+     }
+-    case SQLITE_FCNTL_WIN32_AV_RETRY: {
+-      int *a = (int*)pArg;
+-      if( a[0]>0 ){
+-        winIoerrRetry = a[0];
+-      }else{
+-        a[0] = winIoerrRetry;
+-      }
+-      if( a[1]>0 ){
+-        winIoerrRetryDelay = a[1];
+-      }else{
+-        a[1] = winIoerrRetryDelay;
++
++    /* Did we just have a reader lock? */
++    else if (pFile->local.nReaders){
++      assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE
++             || nNumberOfBytesToUnlockLow == 1);
++      pFile->local.nReaders --;
++      if (pFile->local.nReaders == 0)
++      {
++        pFile->shared->nReaders --;
+       }
+-      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
+-      return SQLITE_OK;
+-    }
+-#ifdef SQLITE_TEST
+-    case SQLITE_FCNTL_WIN32_SET_HANDLE: {
+-      LPHANDLE phFile = (LPHANDLE)pArg;
+-      HANDLE hOldFile = pFile->h;
+-      pFile->h = *phFile;
+-      *phFile = hOldFile;
+-      OSTRACE(("FCNTL oldFile=%p, newFile=%p, rc=SQLITE_OK\n",
+-               hOldFile, pFile->h));
+-      return SQLITE_OK;
++      bReturn = TRUE;
+     }
+-#endif
+-    case SQLITE_FCNTL_TEMPFILENAME: {
+-      char *zTFile = 0;
+-      int rc = winGetTempname(pFile->pVfs, &zTFile);
+-      if( rc==SQLITE_OK ){
+-        *(char**)pArg = zTFile;
+-      }
+-      OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
+-      return rc;
++  }
++
++  /* Releasing a pending lock */
++  else if (dwFileOffsetLow == (DWORD)PENDING_BYTE
++           && nNumberOfBytesToUnlockLow == 1){
++    if (pFile->local.bPending){
++      pFile->local.bPending = FALSE;
++      pFile->shared->bPending = FALSE;
++      bReturn = TRUE;
+     }
+-#if SQLITE_MAX_MMAP_SIZE>0
+-    case SQLITE_FCNTL_MMAP_SIZE: {
+-      i64 newLimit = *(i64*)pArg;
+-      int rc = SQLITE_OK;
+-      if( newLimit>sqlite3GlobalConfig.mxMmap ){
+-        newLimit = sqlite3GlobalConfig.mxMmap;
+-      }
+-      *(i64*)pArg = pFile->mmapSizeMax;
+-      if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
+-        pFile->mmapSizeMax = newLimit;
+-        if( pFile->mmapSize>0 ){
+-          winUnmapfile(pFile);
+-          rc = winMapfile(pFile, -1);
+-        }
+-      }
+-      OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
+-      return rc;
++  }
++  /* Releasing a reserved lock */
++  else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE
++           && nNumberOfBytesToUnlockLow == 1){
++    if (pFile->local.bReserved) {
++      pFile->local.bReserved = FALSE;
++      pFile->shared->bReserved = FALSE;
++      bReturn = TRUE;
+     }
+-#endif
+   }
+-  OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h));
+-  return SQLITE_NOTFOUND;
++
++  winceMutexRelease(pFile->hMutex);
++  return bReturn;
++}
++/*
++** End of the special code for wince
++*****************************************************************************/
++#endif /* SQLITE_OS_WINCE */
++
++/*
++** Lock a file region.
++*/
++static BOOL winLockFile(
++  LPHANDLE phFile,
++  DWORD flags,
++  DWORD offsetLow,
++  DWORD offsetHigh,
++  DWORD numBytesLow,
++  DWORD numBytesHigh
++){
++#if SQLITE_OS_WINCE
++  /*
++  ** NOTE: Windows CE is handled differently here due its lack of the Win32
++  **       API LockFile.
++  */
++  return winceLockFile(phFile, offsetLow, offsetHigh,
++                       numBytesLow, numBytesHigh);
++#else
++  if( osIsNT() ){
++    OVERLAPPED ovlp;
++    memset(&ovlp, 0, sizeof(OVERLAPPED));
++    ovlp.Offset = offsetLow;
++    ovlp.OffsetHigh = offsetHigh;
++    return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp);
++  }else{
++    return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
++                      numBytesHigh);
++  }
++#endif
+ }
+ 
+ /*
+-** Return the sector size in bytes of the underlying block device for
+-** the specified file. This is almost always 512 bytes, but may be
+-** larger for some devices.
+-**
+-** SQLite code assumes this function cannot fail. It also assumes that
+-** if two files are created in the same file-system directory (i.e.
+-** a database and its journal file) that the sector size will be the
+-** same for both.
+-*/
+-static int winSectorSize(sqlite3_file *id){
+-  (void)id;
+-  return SQLITE_DEFAULT_SECTOR_SIZE;
++** Unlock a file region.
++ */
++static BOOL winUnlockFile(
++  LPHANDLE phFile,
++  DWORD offsetLow,
++  DWORD offsetHigh,
++  DWORD numBytesLow,
++  DWORD numBytesHigh
++){
++#if SQLITE_OS_WINCE
++  /*
++  ** NOTE: Windows CE is handled differently here due its lack of the Win32
++  **       API UnlockFile.
++  */
++  return winceUnlockFile(phFile, offsetLow, offsetHigh,
++                         numBytesLow, numBytesHigh);
++#else
++  if( osIsNT() ){
++    OVERLAPPED ovlp;
++    memset(&ovlp, 0, sizeof(OVERLAPPED));
++    ovlp.Offset = offsetLow;
++    ovlp.OffsetHigh = offsetHigh;
++    return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp);
++  }else{
++    return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
++                        numBytesHigh);
++  }
++#endif
+ }
+ 
++/*****************************************************************************
++** The next group of routines implement the I/O methods specified
++** by the sqlite3_io_methods object.
++******************************************************************************/
++
+ /*
+-** Return a vector of device characteristics.
++** Some Microsoft compilers lack this definition.
+ */
+-static int winDeviceCharacteristics(sqlite3_file *id){
+-  winFile *p = (winFile*)id;
+-  return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN |
+-         ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0);
+-}
++#ifndef INVALID_SET_FILE_POINTER
++# define INVALID_SET_FILE_POINTER ((DWORD)-1)
++#endif
+ 
+ /*
+-** Windows will only let you create file view mappings
+-** on allocation size granularity boundaries.
+-** During sqlite3_os_init() we do a GetSystemInfo()
+-** to get the granularity size.
++** Move the current position of the file handle passed as the first
++** argument to offset iOffset within the file. If successful, return 0.
++** Otherwise, set pFile->lastErrno and return non-zero.
+ */
+-static SYSTEM_INFO winSysInfo;
++static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){
++#if !SQLITE_OS_WINRT
++  LONG upperBits;                 /* Most sig. 32 bits of new offset */
++  LONG lowerBits;                 /* Least sig. 32 bits of new offset */
++  DWORD dwRet;                    /* Value returned by SetFilePointer() */
++  DWORD lastErrno;                /* Value returned by GetLastError() */
+ 
+-#ifndef SQLITE_OMIT_WAL
++  OSTRACE(("SEEK file=%p, offset=%lld\n", pFile->h, iOffset));
+ 
+-/*
+-** Helper functions to obtain and relinquish the global mutex. The
+-** global mutex is used to protect the winLockInfo objects used by
+-** this file, all of which may be shared by multiple threads.
+-**
+-** Function winShmMutexHeld() is used to assert() that the global mutex
+-** is held when required. This function is only used as part of assert()
+-** statements. e.g.
+-**
+-**   winShmEnterMutex()
+-**     assert( winShmMutexHeld() );
+-**   winShmLeaveMutex()
+-*/
+-static void winShmEnterMutex(void){
+-  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
+-}
+-static void winShmLeaveMutex(void){
+-  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
+-}
+-#ifndef NDEBUG
+-static int winShmMutexHeld(void) {
+-  return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
++  upperBits = (LONG)((iOffset>>32) & 0x7fffffff);
++  lowerBits = (LONG)(iOffset & 0xffffffff);
++
++  /* API oddity: If successful, SetFilePointer() returns a dword
++  ** containing the lower 32-bits of the new file-offset. Or, if it fails,
++  ** it returns INVALID_SET_FILE_POINTER. However according to MSDN,
++  ** INVALID_SET_FILE_POINTER may also be a valid new offset. So to determine
++  ** whether an error has actually occurred, it is also necessary to call
++  ** GetLastError().
++  */
++  dwRet = osSetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
++
++  if( (dwRet==INVALID_SET_FILE_POINTER
++      && ((lastErrno = osGetLastError())!=NO_ERROR)) ){
++    pFile->lastErrno = lastErrno;
++    winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
++                "winSeekFile", pFile->zPath);
++    OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
++    return 1;
++  }
++
++  OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h));
++  return 0;
++#else
++  /*
++  ** Same as above, except that this implementation works for WinRT.
++  */
++
++  LARGE_INTEGER x;                /* The new offset */
++  BOOL bRet;                      /* Value returned by SetFilePointerEx() */
++
++  x.QuadPart = iOffset;
++  bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN);
++
++  if(!bRet){
++    pFile->lastErrno = osGetLastError();
++    winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno,
++                "winSeekFile", pFile->zPath);
++    OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h));
++    return 1;
++  }
++
++  OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h));
++  return 0;
++#endif
+ }
++
++#if SQLITE_MAX_MMAP_SIZE>0
++/* Forward references to VFS helper methods used for memory mapped files */
++static int winMapfile(winFile*, sqlite3_int64);
++static int winUnmapfile(winFile*);
+ #endif
+ 
+ /*
+-** Object used to represent a single file opened and mmapped to provide
+-** shared memory.  When multiple threads all reference the same
+-** log-summary, each thread has its own winFile object, but they all
+-** point to a single instance of this object.  In other words, each
+-** log-summary is opened only once per process.
+-**
+-** winShmMutexHeld() must be true when creating or destroying
+-** this object or while reading or writing the following fields:
+-**
+-**      nRef
+-**      pNext
+-**
+-** The following fields are read-only after the object is created:
+-**
+-**      fid
+-**      zFilename
+-**
+-** Either winShmNode.mutex must be held or winShmNode.nRef==0 and
+-** winShmMutexHeld() is true when reading or writing any other field
+-** in this structure.
++** Close a file.
+ **
++** It is reported that an attempt to close a handle might sometimes
++** fail.  This is a very unreasonable result, but Windows is notorious
++** for being unreasonable so I do not doubt that it might happen.  If
++** the close fails, we pause for 100 milliseconds and try again.  As
++** many as MX_CLOSE_ATTEMPT attempts to close the handle are made before
++** giving up and returning an error.
+ */
+-struct winShmNode {
+-  sqlite3_mutex *mutex;      /* Mutex to access this object */
+-  char *zFilename;           /* Name of the file */
+-  winFile hFile;             /* File handle from winOpen */
++#define MX_CLOSE_ATTEMPT 3
++static int winClose(sqlite3_file *id){
++  int rc, cnt = 0;
++  winFile *pFile = (winFile*)id;
+ 
+-  int szRegion;              /* Size of shared-memory regions */
+-  int nRegion;               /* Size of array apRegion */
+-  struct ShmRegion {
+-    HANDLE hMap;             /* File handle from CreateFileMapping */
+-    void *pMap;
+-  } *aRegion;
+-  DWORD lastErrno;           /* The Windows errno from the last I/O error */
++  assert( id!=0 );
++#ifndef SQLITE_OMIT_WAL
++  assert( pFile->pShm==0 );
++#endif
++  assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE );
++  OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p\n",
++           osGetCurrentProcessId(), pFile, pFile->h));
+ 
+-  int nRef;                  /* Number of winShm objects pointing to this */
+-  winShm *pFirst;            /* All winShm objects pointing to this */
+-  winShmNode *pNext;         /* Next in list of all winShmNode objects */
+-#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
+-  u8 nextShmId;              /* Next available winShm.id value */
++#if SQLITE_MAX_MMAP_SIZE>0
++  winUnmapfile(pFile);
+ #endif
+-};
+ 
+-/*
+-** A global array of all winShmNode objects.
+-**
+-** The winShmMutexHeld() must be true while reading or writing this list.
+-*/
+-static winShmNode *winShmNodeList = 0;
++  do{
++    rc = osCloseHandle(pFile->h);
++    /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
++  }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) );
++#if SQLITE_OS_WINCE
++#define WINCE_DELETION_ATTEMPTS 3
++  winceDestroyLock(pFile);
++  if( pFile->zDeleteOnClose ){
++    int cnt = 0;
++    while(
++           osDeleteFileW(pFile->zDeleteOnClose)==0
++        && osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff
++        && cnt++ < WINCE_DELETION_ATTEMPTS
++    ){
++       sqlite3_win32_sleep(100);  /* Wait a little before trying again */
++    }
++    sqlite3_free(pFile->zDeleteOnClose);
++  }
++#endif
++  if( rc ){
++    pFile->h = NULL;
++  }
++  OpenCounter(-1);
++  OSTRACE(("CLOSE pid=%lu, pFile=%p, file=%p, rc=%s\n",
++           osGetCurrentProcessId(), pFile, pFile->h, rc ? "ok" : "failed"));
++  return rc ? SQLITE_OK
++            : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(),
++                          "winClose", pFile->zPath);
++}
+ 
+ /*
+-** Structure used internally by this VFS to record the state of an
+-** open shared memory connection.
+-**
+-** The following fields are initialized when this object is created and
+-** are read-only thereafter:
+-**
+-**    winShm.pShmNode
+-**    winShm.id
+-**
+-** All other fields are read/write.  The winShm.pShmNode->mutex must be held
+-** while accessing any read/write fields.
++** Read data from a file into a buffer.  Return SQLITE_OK if all
++** bytes were read successfully and SQLITE_IOERR if anything goes
++** wrong.
+ */
+-struct winShm {
+-  winShmNode *pShmNode;      /* The underlying winShmNode object */
+-  winShm *pNext;             /* Next winShm with the same winShmNode */
+-  u8 hasMutex;               /* True if holding the winShmNode mutex */
+-  u16 sharedMask;            /* Mask of shared locks held */
+-  u16 exclMask;              /* Mask of exclusive locks held */
+-#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
+-  u8 id;                     /* Id of this connection with its winShmNode */
++static int winRead(
++  sqlite3_file *id,          /* File to read from */
++  void *pBuf,                /* Write content into this buffer */
++  int amt,                   /* Number of bytes to read */
++  sqlite3_int64 offset       /* Begin reading at this offset */
++){
++#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
++  OVERLAPPED overlapped;          /* The offset for ReadFile. */
+ #endif
+-};
++  winFile *pFile = (winFile*)id;  /* file handle */
++  DWORD nRead;                    /* Number of bytes actually read from file */
++  int nRetry = 0;                 /* Number of retrys */
+ 
+-/*
+-** Constants used for locking
+-*/
+-#define WIN_SHM_BASE   ((22+SQLITE_SHM_NLOCK)*4)        /* first lock byte */
+-#define WIN_SHM_DMS    (WIN_SHM_BASE+SQLITE_SHM_NLOCK)  /* deadman switch */
++  assert( id!=0 );
++  assert( amt>0 );
++  assert( offset>=0 );
++  SimulateIOError(return SQLITE_IOERR_READ);
++  OSTRACE(("READ pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, "
++           "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile,
++           pFile->h, pBuf, amt, offset, pFile->locktype));
++
++#if SQLITE_MAX_MMAP_SIZE>0
++  /* Deal with as much of this read request as possible by transfering
++  ** data from the memory mapping using memcpy().  */
++  if( offset<pFile->mmapSize ){
++    if( offset+amt <= pFile->mmapSize ){
++      memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt);
++      OSTRACE(("READ-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
++               osGetCurrentProcessId(), pFile, pFile->h));
++      return SQLITE_OK;
++    }else{
++      int nCopy = (int)(pFile->mmapSize - offset);
++      memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy);
++      pBuf = &((u8 *)pBuf)[nCopy];
++      amt -= nCopy;
++      offset += nCopy;
++    }
++  }
++#endif
++
++#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
++  if( winSeekFile(pFile, offset) ){
++    OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n",
++             osGetCurrentProcessId(), pFile, pFile->h));
++    return SQLITE_FULL;
++  }
++  while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){
++#else
++  memset(&overlapped, 0, sizeof(OVERLAPPED));
++  overlapped.Offset = (LONG)(offset & 0xffffffff);
++  overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
++  while( !osReadFile(pFile->h, pBuf, amt, &nRead, &overlapped) &&
++         osGetLastError()!=ERROR_HANDLE_EOF ){
++#endif
++    DWORD lastErrno;
++    if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
++    pFile->lastErrno = lastErrno;
++    OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_READ\n",
++             osGetCurrentProcessId(), pFile, pFile->h));
++    return winLogError(SQLITE_IOERR_READ, pFile->lastErrno,
++                       "winRead", pFile->zPath);
++  }
++  winLogIoerr(nRetry, __LINE__);
++  if( nRead<(DWORD)amt ){
++    /* Unread parts of the buffer must be zero-filled */
++    memset(&((char*)pBuf)[nRead], 0, amt-nRead);
++    OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_SHORT_READ\n",
++             osGetCurrentProcessId(), pFile, pFile->h));
++    return SQLITE_IOERR_SHORT_READ;
++  }
++
++  OSTRACE(("READ pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
++           osGetCurrentProcessId(), pFile, pFile->h));
++  return SQLITE_OK;
++}
+ 
+ /*
+-** Apply advisory locks for all n bytes beginning at ofst.
++** Write data from a buffer into a file.  Return SQLITE_OK on success
++** or some other error code on failure.
+ */
+-#define _SHM_UNLCK  1
+-#define _SHM_RDLCK  2
+-#define _SHM_WRLCK  3
+-static int winShmSystemLock(
+-  winShmNode *pFile,    /* Apply locks to this open shared-memory segment */
+-  int lockType,         /* _SHM_UNLCK, _SHM_RDLCK, or _SHM_WRLCK */
+-  int ofst,             /* Offset to first byte to be locked/unlocked */
+-  int nByte             /* Number of bytes to lock or unlock */
++static int winWrite(
++  sqlite3_file *id,               /* File to write into */
++  const void *pBuf,               /* The bytes to be written */
++  int amt,                        /* Number of bytes to write */
++  sqlite3_int64 offset            /* Offset into the file to begin writing at */
+ ){
+-  int rc = 0;           /* Result code form Lock/UnlockFileEx() */
+-
+-  /* Access to the winShmNode object is serialized by the caller */
+-  assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 );
++  int rc = 0;                     /* True if error has occurred, else false */
++  winFile *pFile = (winFile*)id;  /* File handle */
++  int nRetry = 0;                 /* Number of retries */
+ 
+-  OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n",
+-           pFile->hFile.h, lockType, ofst, nByte));
++  assert( amt>0 );
++  assert( pFile );
++  SimulateIOError(return SQLITE_IOERR_WRITE);
++  SimulateDiskfullError(return SQLITE_FULL);
+ 
+-  /* Release/Acquire the system-level lock */
+-  if( lockType==_SHM_UNLCK ){
+-    rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0);
+-  }else{
+-    /* Initialize the locking parameters */
+-    DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY;
+-    if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
+-    rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0);
+-  }
++  OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, buffer=%p, amount=%d, "
++           "offset=%lld, lock=%d\n", osGetCurrentProcessId(), pFile,
++           pFile->h, pBuf, amt, offset, pFile->locktype));
+ 
+-  if( rc!= 0 ){
+-    rc = SQLITE_OK;
+-  }else{
+-    pFile->lastErrno =  osGetLastError();
+-    rc = SQLITE_BUSY;
++#if SQLITE_MAX_MMAP_SIZE>0
++  /* Deal with as much of this write request as possible by transfering
++  ** data from the memory mapping using memcpy().  */
++  if( offset<pFile->mmapSize ){
++    if( offset+amt <= pFile->mmapSize ){
++      memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt);
++      OSTRACE(("WRITE-MMAP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
++               osGetCurrentProcessId(), pFile, pFile->h));
++      return SQLITE_OK;
++    }else{
++      int nCopy = (int)(pFile->mmapSize - offset);
++      memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy);
++      pBuf = &((u8 *)pBuf)[nCopy];
++      amt -= nCopy;
++      offset += nCopy;
++    }
+   }
++#endif
+ 
+-  OSTRACE(("SHM-LOCK file=%p, func=%s, errno=%lu, rc=%s\n",
+-           pFile->hFile.h, (lockType == _SHM_UNLCK) ? "winUnlockFile" :
+-           "winLockFile", pFile->lastErrno, sqlite3ErrName(rc)));
+-
+-  return rc;
+-}
++#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
++  rc = winSeekFile(pFile, offset);
++  if( rc==0 ){
++#else
++  {
++#endif
++#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
++    OVERLAPPED overlapped;        /* The offset for WriteFile. */
++#endif
++    u8 *aRem = (u8 *)pBuf;        /* Data yet to be written */
++    int nRem = amt;               /* Number of bytes yet to be written */
++    DWORD nWrite;                 /* Bytes written by each WriteFile() call */
++    DWORD lastErrno = NO_ERROR;   /* Value returned by GetLastError() */
+ 
+-/* Forward references to VFS methods */
+-static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*);
+-static int winDelete(sqlite3_vfs *,const char*,int);
++#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
++    memset(&overlapped, 0, sizeof(OVERLAPPED));
++    overlapped.Offset = (LONG)(offset & 0xffffffff);
++    overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
++#endif
+ 
+-/*
+-** Purge the winShmNodeList list of all entries with winShmNode.nRef==0.
+-**
+-** This is not a VFS shared-memory method; it is a utility function called
+-** by VFS shared-memory methods.
+-*/
+-static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
+-  winShmNode **pp;
+-  winShmNode *p;
+-  assert( winShmMutexHeld() );
+-  OSTRACE(("SHM-PURGE pid=%lu, deleteFlag=%d\n",
+-           osGetCurrentProcessId(), deleteFlag));
+-  pp = &winShmNodeList;
+-  while( (p = *pp)!=0 ){
+-    if( p->nRef==0 ){
+-      int i;
+-      if( p->mutex ){ sqlite3_mutex_free(p->mutex); }
+-      for(i=0; i<p->nRegion; i++){
+-        BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap);
+-        OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n",
+-                 osGetCurrentProcessId(), i, bRc ? "ok" : "failed"));
+-        UNUSED_VARIABLE_VALUE(bRc);
+-        bRc = osCloseHandle(p->aRegion[i].hMap);
+-        OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n",
+-                 osGetCurrentProcessId(), i, bRc ? "ok" : "failed"));
+-        UNUSED_VARIABLE_VALUE(bRc);
+-      }
+-      if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){
+-        SimulateIOErrorBenign(1);
+-        winClose((sqlite3_file *)&p->hFile);
+-        SimulateIOErrorBenign(0);
++    while( nRem>0 ){
++#if SQLITE_OS_WINCE || defined(SQLITE_WIN32_NO_OVERLAPPED)
++      if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){
++#else
++      if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
++#endif
++        if( winRetryIoerr(&nRetry, &lastErrno) ) continue;
++        break;
+       }
+-      if( deleteFlag ){
+-        SimulateIOErrorBenign(1);
+-        sqlite3BeginBenignMalloc();
+-        winDelete(pVfs, p->zFilename, 0);
+-        sqlite3EndBenignMalloc();
+-        SimulateIOErrorBenign(0);
++      assert( nWrite==0 || nWrite<=(DWORD)nRem );
++      if( nWrite==0 || nWrite>(DWORD)nRem ){
++        lastErrno = osGetLastError();
++        break;
+       }
+-      *pp = p->pNext;
+-      sqlite3_free(p->aRegion);
+-      sqlite3_free(p);
+-    }else{
+-      pp = &p->pNext;
++#if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
++      offset += nWrite;
++      overlapped.Offset = (LONG)(offset & 0xffffffff);
++      overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
++#endif
++      aRem += nWrite;
++      nRem -= nWrite;
++    }
++    if( nRem>0 ){
++      pFile->lastErrno = lastErrno;
++      rc = 1;
++    }
++  }
++
++  if( rc ){
++    if(   ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL )
++       || ( pFile->lastErrno==ERROR_DISK_FULL )){
++      OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_FULL\n",
++               osGetCurrentProcessId(), pFile, pFile->h));
++      return winLogError(SQLITE_FULL, pFile->lastErrno,
++                         "winWrite1", pFile->zPath);
+     }
++    OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_WRITE\n",
++             osGetCurrentProcessId(), pFile, pFile->h));
++    return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno,
++                       "winWrite2", pFile->zPath);
++  }else{
++    winLogIoerr(nRetry, __LINE__);
+   }
++  OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
++           osGetCurrentProcessId(), pFile, pFile->h));
++  return SQLITE_OK;
+ }
+ 
+ /*
+-** Open the shared-memory area associated with database file pDbFd.
+-**
+-** When opening a new shared-memory file, if no other instances of that
+-** file are currently open, in this process or in other processes, then
+-** the file must be truncated to zero length or have its header cleared.
++** Truncate an open file to a specified size
+ */
+-static int winOpenSharedMemory(winFile *pDbFd){
+-  struct winShm *p;                  /* The connection to be opened */
+-  struct winShmNode *pShmNode = 0;   /* The underlying mmapped file */
+-  int rc;                            /* Result code */
+-  struct winShmNode *pNew;           /* Newly allocated winShmNode */
+-  int nName;                         /* Size of zName in bytes */
++static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
++  winFile *pFile = (winFile*)id;  /* File handle object */
++  int rc = SQLITE_OK;             /* Return code for this function */
++  DWORD lastErrno;
+ 
+-  assert( pDbFd->pShm==0 );    /* Not previously opened */
++  assert( pFile );
++  SimulateIOError(return SQLITE_IOERR_TRUNCATE);
++  OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, size=%lld, lock=%d\n",
++           osGetCurrentProcessId(), pFile, pFile->h, nByte, pFile->locktype));
+ 
+-  /* Allocate space for the new sqlite3_shm object.  Also speculatively
+-  ** allocate space for a new winShmNode and filename.
++  /* If the user has configured a chunk-size for this file, truncate the
++  ** file so that it consists of an integer number of chunks (i.e. the
++  ** actual file size after the operation may be larger than the requested
++  ** size).
+   */
+-  p = sqlite3MallocZero( sizeof(*p) );
+-  if( p==0 ) return SQLITE_IOERR_NOMEM;
+-  nName = sqlite3Strlen30(pDbFd->zPath);
+-  pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 );
+-  if( pNew==0 ){
+-    sqlite3_free(p);
+-    return SQLITE_IOERR_NOMEM;
++  if( pFile->szChunk>0 ){
++    nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk;
+   }
+-  pNew->zFilename = (char*)&pNew[1];
+-  sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
+-  sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename);
+ 
+-  /* Look to see if there is an existing winShmNode that can be used.
+-  ** If no matching winShmNode currently exists, create a new one.
+-  */
+-  winShmEnterMutex();
+-  for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){
+-    /* TBD need to come up with better match here.  Perhaps
+-    ** use FILE_ID_BOTH_DIR_INFO Structure.
+-    */
+-    if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break;
++  /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */
++  if( winSeekFile(pFile, nByte) ){
++    rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
++                     "winTruncate1", pFile->zPath);
++  }else if( 0==osSetEndOfFile(pFile->h) &&
++            ((lastErrno = osGetLastError())!=ERROR_USER_MAPPED_FILE) ){
++    pFile->lastErrno = lastErrno;
++    rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno,
++                     "winTruncate2", pFile->zPath);
+   }
+-  if( pShmNode ){
+-    sqlite3_free(pNew);
+-  }else{
+-    pShmNode = pNew;
+-    pNew = 0;
+-    ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE;
+-    pShmNode->pNext = winShmNodeList;
+-    winShmNodeList = pShmNode;
+-
+-    pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
+-    if( pShmNode->mutex==0 ){
+-      rc = SQLITE_IOERR_NOMEM;
+-      goto shm_open_err;
+-    }
+-
+-    rc = winOpen(pDbFd->pVfs,
+-                 pShmNode->zFilename,             /* Name of the file (UTF-8) */
+-                 (sqlite3_file*)&pShmNode->hFile,  /* File handle here */
+-                 SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
+-                 0);
+-    if( SQLITE_OK!=rc ){
+-      goto shm_open_err;
+-    }
+ 
+-    /* Check to see if another process is holding the dead-man switch.
+-    ** If not, truncate the file to zero length.
+-    */
+-    if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
+-      rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
+-      if( rc!=SQLITE_OK ){
+-        rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
+-                         "winOpenShm", pDbFd->zPath);
+-      }
+-    }
+-    if( rc==SQLITE_OK ){
+-      winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
+-      rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
+-    }
+-    if( rc ) goto shm_open_err;
++#if SQLITE_MAX_MMAP_SIZE>0
++  /* If the file was truncated to a size smaller than the currently
++  ** mapped region, reduce the effective mapping size as well. SQLite will
++  ** use read() and write() to access data beyond this point from now on.
++  */
++  if( pFile->pMapRegion && nByte<pFile->mmapSize ){
++    pFile->mmapSize = nByte;
+   }
+-
+-  /* Make the new connection a child of the winShmNode */
+-  p->pShmNode = pShmNode;
+-#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
+-  p->id = pShmNode->nextShmId++;
+ #endif
+-  pShmNode->nRef++;
+-  pDbFd->pShm = p;
+-  winShmLeaveMutex();
+-
+-  /* The reference count on pShmNode has already been incremented under
+-  ** the cover of the winShmEnterMutex() mutex and the pointer from the
+-  ** new (struct winShm) object to the pShmNode has been set. All that is
+-  ** left to do is to link the new object into the linked list starting
+-  ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex
+-  ** mutex.
+-  */
+-  sqlite3_mutex_enter(pShmNode->mutex);
+-  p->pNext = pShmNode->pFirst;
+-  pShmNode->pFirst = p;
+-  sqlite3_mutex_leave(pShmNode->mutex);
+-  return SQLITE_OK;
+ 
+-  /* Jump here on any error */
+-shm_open_err:
+-  winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
+-  winShmPurge(pDbFd->pVfs, 0);      /* This call frees pShmNode if required */
+-  sqlite3_free(p);
+-  sqlite3_free(pNew);
+-  winShmLeaveMutex();
++  OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, rc=%s\n",
++           osGetCurrentProcessId(), pFile, pFile->h, sqlite3ErrName(rc)));
+   return rc;
+ }
+ 
++#ifdef SQLITE_TEST
+ /*
+-** Close a connection to shared-memory.  Delete the underlying
+-** storage if deleteFlag is true.
++** Count the number of fullsyncs and normal syncs.  This is used to test
++** that syncs and fullsyncs are occuring at the right times.
+ */
+-static int winShmUnmap(
+-  sqlite3_file *fd,          /* Database holding shared memory */
+-  int deleteFlag             /* Delete after closing if true */
+-){
+-  winFile *pDbFd;       /* Database holding shared-memory */
+-  winShm *p;            /* The connection to be closed */
+-  winShmNode *pShmNode; /* The underlying shared-memory file */
+-  winShm **pp;          /* For looping over sibling connections */
++SQLITE_API int sqlite3_sync_count = 0;
++SQLITE_API int sqlite3_fullsync_count = 0;
++#endif
+ 
+-  pDbFd = (winFile*)fd;
+-  p = pDbFd->pShm;
+-  if( p==0 ) return SQLITE_OK;
+-  pShmNode = p->pShmNode;
++/*
++** Make sure all writes to a particular file are committed to disk.
++*/
++static int winSync(sqlite3_file *id, int flags){
++#ifndef SQLITE_NO_SYNC
++  /*
++  ** Used only when SQLITE_NO_SYNC is not defined.
++   */
++  BOOL rc;
++#endif
++#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || \
++    defined(SQLITE_HAVE_OS_TRACE)
++  /*
++  ** Used when SQLITE_NO_SYNC is not defined and by the assert() and/or
++  ** OSTRACE() macros.
++   */
++  winFile *pFile = (winFile*)id;
++#else
++  UNUSED_PARAMETER(id);
++#endif
+ 
+-  /* Remove connection p from the set of connections associated
+-  ** with pShmNode */
+-  sqlite3_mutex_enter(pShmNode->mutex);
+-  for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
+-  *pp = p->pNext;
++  assert( pFile );
++  /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */
++  assert((flags&0x0F)==SQLITE_SYNC_NORMAL
++      || (flags&0x0F)==SQLITE_SYNC_FULL
++  );
+ 
+-  /* Free the connection p */
+-  sqlite3_free(p);
+-  pDbFd->pShm = 0;
+-  sqlite3_mutex_leave(pShmNode->mutex);
++  /* Unix cannot, but some systems may return SQLITE_FULL from here. This
++  ** line is to test that doing so does not cause any problems.
++  */
++  SimulateDiskfullError( return SQLITE_FULL );
+ 
+-  /* If pShmNode->nRef has reached 0, then close the underlying
+-  ** shared-memory file, too */
+-  winShmEnterMutex();
+-  assert( pShmNode->nRef>0 );
+-  pShmNode->nRef--;
+-  if( pShmNode->nRef==0 ){
+-    winShmPurge(pDbFd->pVfs, deleteFlag);
++  OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, flags=%x, lock=%d\n",
++           osGetCurrentProcessId(), pFile, pFile->h, flags,
++           pFile->locktype));
++
++#ifndef SQLITE_TEST
++  UNUSED_PARAMETER(flags);
++#else
++  if( (flags&0x0F)==SQLITE_SYNC_FULL ){
++    sqlite3_fullsync_count++;
+   }
+-  winShmLeaveMutex();
++  sqlite3_sync_count++;
++#endif
+ 
++  /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
++  ** no-op
++  */
++#ifdef SQLITE_NO_SYNC
++  OSTRACE(("SYNC-NOP pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
++           osGetCurrentProcessId(), pFile, pFile->h));
+   return SQLITE_OK;
++#else
++#if SQLITE_MAX_MMAP_SIZE>0
++  if( pFile->pMapRegion ){
++    if( osFlushViewOfFile(pFile->pMapRegion, 0) ){
++      OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, "
++               "rc=SQLITE_OK\n", osGetCurrentProcessId(),
++               pFile, pFile->pMapRegion));
++    }else{
++      pFile->lastErrno = osGetLastError();
++      OSTRACE(("SYNC-MMAP pid=%lu, pFile=%p, pMapRegion=%p, "
++               "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(),
++               pFile, pFile->pMapRegion));
++      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
++                         "winSync1", pFile->zPath);
++    }
++  }
++#endif
++  rc = osFlushFileBuffers(pFile->h);
++  SimulateIOError( rc=FALSE );
++  if( rc ){
++    OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
++             osGetCurrentProcessId(), pFile, pFile->h));
++    return SQLITE_OK;
++  }else{
++    pFile->lastErrno = osGetLastError();
++    OSTRACE(("SYNC pid=%lu, pFile=%p, file=%p, rc=SQLITE_IOERR_FSYNC\n",
++             osGetCurrentProcessId(), pFile, pFile->h));
++    return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno,
++                       "winSync2", pFile->zPath);
++  }
++#endif
+ }
+ 
+ /*
+-** Change the lock state for a shared-memory segment.
++** Determine the current size of a file in bytes
+ */
+-static int winShmLock(
+-  sqlite3_file *fd,          /* Database file holding the shared memory */
+-  int ofst,                  /* First lock to acquire or release */
+-  int n,                     /* Number of locks to acquire or release */
+-  int flags                  /* What to do with the lock */
+-){
+-  winFile *pDbFd = (winFile*)fd;        /* Connection holding shared memory */
+-  winShm *p = pDbFd->pShm;              /* The shared memory being locked */
+-  winShm *pX;                           /* For looping over all siblings */
+-  winShmNode *pShmNode = p->pShmNode;
+-  int rc = SQLITE_OK;                   /* Result code */
+-  u16 mask;                             /* Mask of locks to take or release */
+-
+-  assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
+-  assert( n>=1 );
+-  assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
+-       || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
+-       || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
+-       || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
+-  assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
+-
+-  mask = (u16)((1U<<(ofst+n)) - (1U<<ofst));
+-  assert( n>1 || mask==(1<<ofst) );
+-  sqlite3_mutex_enter(pShmNode->mutex);
+-  if( flags & SQLITE_SHM_UNLOCK ){
+-    u16 allMask = 0; /* Mask of locks held by siblings */
++static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){
++  winFile *pFile = (winFile*)id;
++  int rc = SQLITE_OK;
+ 
+-    /* See if any siblings hold this same lock */
+-    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
+-      if( pX==p ) continue;
+-      assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 );
+-      allMask |= pX->sharedMask;
+-    }
++  assert( id!=0 );
++  assert( pSize!=0 );
++  SimulateIOError(return SQLITE_IOERR_FSTAT);
++  OSTRACE(("SIZE file=%p, pSize=%p\n", pFile->h, pSize));
+ 
+-    /* Unlock the system-level locks */
+-    if( (mask & allMask)==0 ){
+-      rc = winShmSystemLock(pShmNode, _SHM_UNLCK, ofst+WIN_SHM_BASE, n);
++#if SQLITE_OS_WINRT
++  {
++    FILE_STANDARD_INFO info;
++    if( osGetFileInformationByHandleEx(pFile->h, FileStandardInfo,
++                                     &info, sizeof(info)) ){
++      *pSize = info.EndOfFile.QuadPart;
+     }else{
+-      rc = SQLITE_OK;
++      pFile->lastErrno = osGetLastError();
++      rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
++                       "winFileSize", pFile->zPath);
+     }
++  }
++#else
++  {
++    DWORD upperBits;
++    DWORD lowerBits;
++    DWORD lastErrno;
+ 
+-    /* Undo the local locks */
+-    if( rc==SQLITE_OK ){
+-      p->exclMask &= ~mask;
+-      p->sharedMask &= ~mask;
++    lowerBits = osGetFileSize(pFile->h, &upperBits);
++    *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits;
++    if(   (lowerBits == INVALID_FILE_SIZE)
++       && ((lastErrno = osGetLastError())!=NO_ERROR) ){
++      pFile->lastErrno = lastErrno;
++      rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno,
++                       "winFileSize", pFile->zPath);
+     }
+-  }else if( flags & SQLITE_SHM_SHARED ){
+-    u16 allShared = 0;  /* Union of locks held by connections other than "p" */
++  }
++#endif
++  OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n",
++           pFile->h, pSize, *pSize, sqlite3ErrName(rc)));
++  return rc;
++}
+ 
+-    /* Find out which shared locks are already held by sibling connections.
+-    ** If any sibling already holds an exclusive lock, go ahead and return
+-    ** SQLITE_BUSY.
+-    */
+-    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
+-      if( (pX->exclMask & mask)!=0 ){
+-        rc = SQLITE_BUSY;
+-        break;
+-      }
+-      allShared |= pX->sharedMask;
+-    }
++/*
++** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems.
++*/
++#ifndef LOCKFILE_FAIL_IMMEDIATELY
++# define LOCKFILE_FAIL_IMMEDIATELY 1
++#endif
+ 
+-    /* Get shared locks at the system level, if necessary */
+-    if( rc==SQLITE_OK ){
+-      if( (allShared & mask)==0 ){
+-        rc = winShmSystemLock(pShmNode, _SHM_RDLCK, ofst+WIN_SHM_BASE, n);
+-      }else{
+-        rc = SQLITE_OK;
+-      }
+-    }
++#ifndef LOCKFILE_EXCLUSIVE_LOCK
++# define LOCKFILE_EXCLUSIVE_LOCK 2
++#endif
+ 
+-    /* Get the local shared locks */
+-    if( rc==SQLITE_OK ){
+-      p->sharedMask |= mask;
+-    }
+-  }else{
+-    /* Make sure no sibling connections hold locks that will block this
+-    ** lock.  If any do, return SQLITE_BUSY right away.
+-    */
+-    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
+-      if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){
+-        rc = SQLITE_BUSY;
+-        break;
+-      }
+-    }
++/*
++** Historically, SQLite has used both the LockFile and LockFileEx functions.
++** When the LockFile function was used, it was always expected to fail
++** immediately if the lock could not be obtained.  Also, it always expected to
++** obtain an exclusive lock.  These flags are used with the LockFileEx function
++** and reflect those expectations; therefore, they should not be changed.
++*/
++#ifndef SQLITE_LOCKFILE_FLAGS
++# define SQLITE_LOCKFILE_FLAGS   (LOCKFILE_FAIL_IMMEDIATELY | \
++                                  LOCKFILE_EXCLUSIVE_LOCK)
++#endif
+ 
+-    /* Get the exclusive locks at the system level.  Then if successful
+-    ** also mark the local connection as being locked.
++/*
++** Currently, SQLite never calls the LockFileEx function without wanting the
++** call to fail immediately if the lock cannot be obtained.
++*/
++#ifndef SQLITE_LOCKFILEEX_FLAGS
++# define SQLITE_LOCKFILEEX_FLAGS (LOCKFILE_FAIL_IMMEDIATELY)
++#endif
++
++/*
++** Acquire a reader lock.
++** Different API routines are called depending on whether or not this
++** is Win9x or WinNT.
++*/
++static int winGetReadLock(winFile *pFile){
++  int res;
++  OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
++  if( osIsNT() ){
++#if SQLITE_OS_WINCE
++    /*
++    ** NOTE: Windows CE is handled differently here due its lack of the Win32
++    **       API LockFileEx.
+     */
+-    if( rc==SQLITE_OK ){
+-      rc = winShmSystemLock(pShmNode, _SHM_WRLCK, ofst+WIN_SHM_BASE, n);
+-      if( rc==SQLITE_OK ){
+-        assert( (p->sharedMask & mask)==0 );
+-        p->exclMask |= mask;
+-      }
+-    }
++    res = winceLockFile(&pFile->h, SHARED_FIRST, 0, 1, 0);
++#else
++    res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS, SHARED_FIRST, 0,
++                      SHARED_SIZE, 0);
++#endif
+   }
+-  sqlite3_mutex_leave(pShmNode->mutex);
+-  OSTRACE(("SHM-LOCK pid=%lu, id=%d, sharedMask=%03x, exclMask=%03x, rc=%s\n",
+-           osGetCurrentProcessId(), p->id, p->sharedMask, p->exclMask,
+-           sqlite3ErrName(rc)));
+-  return rc;
++#ifdef SQLITE_WIN32_HAS_ANSI
++  else{
++    int lk;
++    sqlite3_randomness(sizeof(lk), &lk);
++    pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1));
++    res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
++                      SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
++  }
++#endif
++  if( res == 0 ){
++    pFile->lastErrno = osGetLastError();
++    /* No need to log a failure to lock */
++  }
++  OSTRACE(("READ-LOCK file=%p, result=%d\n", pFile->h, res));
++  return res;
+ }
+ 
+ /*
+-** Implement a memory barrier or memory fence on shared memory.
+-**
+-** All loads and stores begun before the barrier must complete before
+-** any load or store begun after the barrier.
++** Undo a readlock
+ */
+-static void winShmBarrier(
+-  sqlite3_file *fd          /* Database holding the shared memory */
+-){
+-  UNUSED_PARAMETER(fd);
+-  /* MemoryBarrier(); // does not work -- do not know why not */
+-  winShmEnterMutex();
+-  winShmLeaveMutex();
++static int winUnlockReadLock(winFile *pFile){
++  int res;
++  DWORD lastErrno;
++  OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype));
++  if( osIsNT() ){
++    res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
++  }
++#ifdef SQLITE_WIN32_HAS_ANSI
++  else{
++    res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0);
++  }
++#endif
++  if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){
++    pFile->lastErrno = lastErrno;
++    winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno,
++                "winUnlockReadLock", pFile->zPath);
++  }
++  OSTRACE(("READ-UNLOCK file=%p, result=%d\n", pFile->h, res));
++  return res;
+ }
+ 
+ /*
+-** This function is called to obtain a pointer to region iRegion of the
+-** shared-memory associated with the database file fd. Shared-memory regions
+-** are numbered starting from zero. Each shared-memory region is szRegion
+-** bytes in size.
+-**
+-** If an error occurs, an error code is returned and *pp is set to NULL.
+-**
+-** Otherwise, if the isWrite parameter is 0 and the requested shared-memory
+-** region has not been allocated (by any client, including one running in a
+-** separate process), then *pp is set to NULL and SQLITE_OK returned. If
+-** isWrite is non-zero and the requested shared-memory region has not yet
+-** been allocated, it is allocated by this function.
++** Lock the file with the lock specified by parameter locktype - one
++** of the following:
+ **
+-** If the shared-memory region has already been allocated or is allocated by
+-** this call as described above, then it is mapped into this processes
+-** address space (if it is not already), *pp is set to point to the mapped
+-** memory and SQLITE_OK returned.
+-*/
+-static int winShmMap(
+-  sqlite3_file *fd,               /* Handle open on database file */
+-  int iRegion,                    /* Region to retrieve */
+-  int szRegion,                   /* Size of regions */
+-  int isWrite,                    /* True to extend file if necessary */
+-  void volatile **pp              /* OUT: Mapped memory */
+-){
+-  winFile *pDbFd = (winFile*)fd;
+-  winShm *pShm = pDbFd->pShm;
+-  winShmNode *pShmNode;
+-  int rc = SQLITE_OK;
+-
+-  if( !pShm ){
+-    rc = winOpenSharedMemory(pDbFd);
+-    if( rc!=SQLITE_OK ) return rc;
+-    pShm = pDbFd->pShm;
+-  }
+-  pShmNode = pShm->pShmNode;
+-
+-  sqlite3_mutex_enter(pShmNode->mutex);
+-  assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
++**     (1) SHARED_LOCK
++**     (2) RESERVED_LOCK
++**     (3) PENDING_LOCK
++**     (4) EXCLUSIVE_LOCK
++**
++** Sometimes when requesting one lock state, additional lock states
++** are inserted in between.  The locking might fail on one of the later
++** transitions leaving the lock state different from what it started but
++** still short of its goal.  The following chart shows the allowed
++** transitions and the inserted intermediate states:
++**
++**    UNLOCKED -> SHARED
++**    SHARED -> RESERVED
++**    SHARED -> (PENDING) -> EXCLUSIVE
++**    RESERVED -> (PENDING) -> EXCLUSIVE
++**    PENDING -> EXCLUSIVE
++**
++** This routine will only increase a lock.  The winUnlock() routine
++** erases all locks at once and returns us immediately to locking level 0.
++** It is not possible to lower the locking level one step at a time.  You
++** must go straight to locking level 0.
++*/
++static int winLock(sqlite3_file *id, int locktype){
++  int rc = SQLITE_OK;    /* Return code from subroutines */
++  int res = 1;           /* Result of a Windows lock call */
++  int newLocktype;       /* Set pFile->locktype to this value before exiting */
++  int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */
++  winFile *pFile = (winFile*)id;
++  DWORD lastErrno = NO_ERROR;
+ 
+-  if( pShmNode->nRegion<=iRegion ){
+-    struct ShmRegion *apNew;           /* New aRegion[] array */
+-    int nByte = (iRegion+1)*szRegion;  /* Minimum required file size */
+-    sqlite3_int64 sz;                  /* Current size of wal-index file */
++  assert( id!=0 );
++  OSTRACE(("LOCK file=%p, oldLock=%d(%d), newLock=%d\n",
++           pFile->h, pFile->locktype, pFile->sharedLockByte, locktype));
+ 
+-    pShmNode->szRegion = szRegion;
++  /* If there is already a lock of this type or more restrictive on the
++  ** OsFile, do nothing. Don't use the end_lock: exit path, as
++  ** sqlite3OsEnterMutex() hasn't been called yet.
++  */
++  if( pFile->locktype>=locktype ){
++    OSTRACE(("LOCK-HELD file=%p, rc=SQLITE_OK\n", pFile->h));
++    return SQLITE_OK;
++  }
+ 
+-    /* The requested region is not mapped into this processes address space.
+-    ** Check to see if it has been allocated (i.e. if the wal-index file is
+-    ** large enough to contain the requested region).
+-    */
+-    rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
+-    if( rc!=SQLITE_OK ){
+-      rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
+-                       "winShmMap1", pDbFd->zPath);
+-      goto shmpage_out;
+-    }
++  /* Make sure the locking sequence is correct
++  */
++  assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
++  assert( locktype!=PENDING_LOCK );
++  assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
+ 
+-    if( sz<nByte ){
+-      /* The requested memory region does not exist. If isWrite is set to
+-      ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned.
+-      **
+-      ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate
+-      ** the requested memory region.
++  /* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or
++  ** a SHARED lock.  If we are acquiring a SHARED lock, the acquisition of
++  ** the PENDING_LOCK byte is temporary.
++  */
++  newLocktype = pFile->locktype;
++  if(   (pFile->locktype==NO_LOCK)
++     || (   (locktype==EXCLUSIVE_LOCK)
++         && (pFile->locktype==RESERVED_LOCK))
++  ){
++    int cnt = 3;
++    while( cnt-->0 && (res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS,
++                                         PENDING_BYTE, 0, 1, 0))==0 ){
++      /* Try 3 times to get the pending lock.  This is needed to work
++      ** around problems caused by indexing and/or anti-virus software on
++      ** Windows systems.
++      ** If you are using this code as a model for alternative VFSes, do not
++      ** copy this retry logic.  It is a hack intended for Windows only.
+       */
+-      if( !isWrite ) goto shmpage_out;
+-      rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
+-      if( rc!=SQLITE_OK ){
+-        rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
+-                         "winShmMap2", pDbFd->zPath);
+-        goto shmpage_out;
++      lastErrno = osGetLastError();
++      OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, result=%d\n",
++               pFile->h, cnt, res));
++      if( lastErrno==ERROR_INVALID_HANDLE ){
++        pFile->lastErrno = lastErrno;
++        rc = SQLITE_IOERR_LOCK;
++        OSTRACE(("LOCK-FAIL file=%p, count=%d, rc=%s\n",
++                 pFile->h, cnt, sqlite3ErrName(rc)));
++        return rc;
+       }
++      if( cnt ) sqlite3_win32_sleep(1);
++    }
++    gotPendingLock = res;
++    if( !res ){
++      lastErrno = osGetLastError();
+     }
++  }
+ 
+-    /* Map the requested memory region into this processes address space. */
+-    apNew = (struct ShmRegion *)sqlite3_realloc64(
+-        pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
+-    );
+-    if( !apNew ){
+-      rc = SQLITE_IOERR_NOMEM;
+-      goto shmpage_out;
++  /* Acquire a shared lock
++  */
++  if( locktype==SHARED_LOCK && res ){
++    assert( pFile->locktype==NO_LOCK );
++    res = winGetReadLock(pFile);
++    if( res ){
++      newLocktype = SHARED_LOCK;
++    }else{
++      lastErrno = osGetLastError();
+     }
+-    pShmNode->aRegion = apNew;
++  }
+ 
+-    while( pShmNode->nRegion<=iRegion ){
+-      HANDLE hMap = NULL;         /* file-mapping handle */
+-      void *pMap = 0;             /* Mapped memory region */
++  /* Acquire a RESERVED lock
++  */
++  if( locktype==RESERVED_LOCK && res ){
++    assert( pFile->locktype==SHARED_LOCK );
++    res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, RESERVED_BYTE, 0, 1, 0);
++    if( res ){
++      newLocktype = RESERVED_LOCK;
++    }else{
++      lastErrno = osGetLastError();
++    }
++  }
+ 
+-#if SQLITE_OS_WINRT
+-      hMap = osCreateFileMappingFromApp(pShmNode->hFile.h,
+-          NULL, PAGE_READWRITE, nByte, NULL
+-      );
+-#elif defined(SQLITE_WIN32_HAS_WIDE)
+-      hMap = osCreateFileMappingW(pShmNode->hFile.h,
+-          NULL, PAGE_READWRITE, 0, nByte, NULL
+-      );
+-#elif defined(SQLITE_WIN32_HAS_ANSI)
+-      hMap = osCreateFileMappingA(pShmNode->hFile.h,
+-          NULL, PAGE_READWRITE, 0, nByte, NULL
+-      );
+-#endif
+-      OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n",
+-               osGetCurrentProcessId(), pShmNode->nRegion, nByte,
+-               hMap ? "ok" : "failed"));
+-      if( hMap ){
+-        int iOffset = pShmNode->nRegion*szRegion;
+-        int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
+-#if SQLITE_OS_WINRT
+-        pMap = osMapViewOfFileFromApp(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
+-            iOffset - iOffsetShift, szRegion + iOffsetShift
+-        );
+-#else
+-        pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
+-            0, iOffset - iOffsetShift, szRegion + iOffsetShift
+-        );
+-#endif
+-        OSTRACE(("SHM-MAP-MAP pid=%lu, region=%d, offset=%d, size=%d, rc=%s\n",
+-                 osGetCurrentProcessId(), pShmNode->nRegion, iOffset,
+-                 szRegion, pMap ? "ok" : "failed"));
+-      }
+-      if( !pMap ){
+-        pShmNode->lastErrno = osGetLastError();
+-        rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno,
+-                         "winShmMap3", pDbFd->zPath);
+-        if( hMap ) osCloseHandle(hMap);
+-        goto shmpage_out;
+-      }
++  /* Acquire a PENDING lock
++  */
++  if( locktype==EXCLUSIVE_LOCK && res ){
++    newLocktype = PENDING_LOCK;
++    gotPendingLock = 0;
++  }
+ 
+-      pShmNode->aRegion[pShmNode->nRegion].pMap = pMap;
+-      pShmNode->aRegion[pShmNode->nRegion].hMap = hMap;
+-      pShmNode->nRegion++;
++  /* Acquire an EXCLUSIVE lock
++  */
++  if( locktype==EXCLUSIVE_LOCK && res ){
++    assert( pFile->locktype>=SHARED_LOCK );
++    res = winUnlockReadLock(pFile);
++    res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0,
++                      SHARED_SIZE, 0);
++    if( res ){
++      newLocktype = EXCLUSIVE_LOCK;
++    }else{
++      lastErrno = osGetLastError();
++      winGetReadLock(pFile);
+     }
+   }
+ 
+-shmpage_out:
+-  if( pShmNode->nRegion>iRegion ){
+-    int iOffset = iRegion*szRegion;
+-    int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
+-    char *p = (char *)pShmNode->aRegion[iRegion].pMap;
+-    *pp = (void *)&p[iOffsetShift];
++  /* If we are holding a PENDING lock that ought to be released, then
++  ** release it now.
++  */
++  if( gotPendingLock && locktype==SHARED_LOCK ){
++    winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
++  }
++
++  /* Update the state of the lock has held in the file descriptor then
++  ** return the appropriate result code.
++  */
++  if( res ){
++    rc = SQLITE_OK;
+   }else{
+-    *pp = 0;
++    pFile->lastErrno = lastErrno;
++    rc = SQLITE_BUSY;
++    OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n",
++             pFile->h, locktype, newLocktype));
+   }
+-  sqlite3_mutex_leave(pShmNode->mutex);
++  pFile->locktype = (u8)newLocktype;
++  OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n",
++           pFile->h, pFile->locktype, sqlite3ErrName(rc)));
+   return rc;
+ }
+ 
+-#else
+-# define winShmMap     0
+-# define winShmLock    0
+-# define winShmBarrier 0
+-# define winShmUnmap   0
+-#endif /* #ifndef SQLITE_OMIT_WAL */
+-
+ /*
+-** Cleans up the mapped region of the specified file, if any.
++** This routine checks if there is a RESERVED lock held on the specified
++** file by this or any other process. If such a lock is held, return
++** non-zero, otherwise zero.
+ */
+-#if SQLITE_MAX_MMAP_SIZE>0
+-static int winUnmapfile(winFile *pFile){
+-  assert( pFile!=0 );
+-  OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, "
+-           "mmapSize=%lld, mmapSizeActual=%lld, mmapSizeMax=%lld\n",
+-           osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion,
+-           pFile->mmapSize, pFile->mmapSizeActual, pFile->mmapSizeMax));
+-  if( pFile->pMapRegion ){
+-    if( !osUnmapViewOfFile(pFile->pMapRegion) ){
+-      pFile->lastErrno = osGetLastError();
+-      OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, "
+-               "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile,
+-               pFile->pMapRegion));
+-      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
+-                         "winUnmapfile1", pFile->zPath);
+-    }
+-    pFile->pMapRegion = 0;
+-    pFile->mmapSize = 0;
+-    pFile->mmapSizeActual = 0;
+-  }
+-  if( pFile->hMap!=NULL ){
+-    if( !osCloseHandle(pFile->hMap) ){
+-      pFile->lastErrno = osGetLastError();
+-      OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n",
+-               osGetCurrentProcessId(), pFile, pFile->hMap));
+-      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
+-                         "winUnmapfile2", pFile->zPath);
++static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
++  int res;
++  winFile *pFile = (winFile*)id;
++
++  SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
++  OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p\n", pFile->h, pResOut));
++
++  assert( id!=0 );
++  if( pFile->locktype>=RESERVED_LOCK ){
++    res = 1;
++    OSTRACE(("TEST-WR-LOCK file=%p, result=%d (local)\n", pFile->h, res));
++  }else{
++    res = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE, 0, 1, 0);
++    if( res ){
++      winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
+     }
+-    pFile->hMap = NULL;
++    res = !res;
++    OSTRACE(("TEST-WR-LOCK file=%p, result=%d (remote)\n", pFile->h, res));
+   }
+-  OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
+-           osGetCurrentProcessId(), pFile));
++  *pResOut = res;
++  OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
++           pFile->h, pResOut, *pResOut));
+   return SQLITE_OK;
+ }
+ 
+ /*
+-** Memory map or remap the file opened by file-descriptor pFd (if the file
+-** is already mapped, the existing mapping is replaced by the new). Or, if
+-** there already exists a mapping for this file, and there are still
+-** outstanding xFetch() references to it, this function is a no-op.
++** Lower the locking level on file descriptor id to locktype.  locktype
++** must be either NO_LOCK or SHARED_LOCK.
+ **
+-** If parameter nByte is non-negative, then it is the requested size of
+-** the mapping to create. Otherwise, if nByte is less than zero, then the
+-** requested size is the size of the file on disk. The actual size of the
+-** created mapping is either the requested size or the value configured
+-** using SQLITE_FCNTL_MMAP_SIZE, whichever is smaller.
++** If the locking level of the file descriptor is already at or below
++** the requested locking level, this routine is a no-op.
+ **
+-** SQLITE_OK is returned if no error occurs (even if the mapping is not
+-** recreated as a result of outstanding references) or an SQLite error
+-** code otherwise.
++** It is not possible for this routine to fail if the second argument
++** is NO_LOCK.  If the second argument is SHARED_LOCK then this routine
++** might return SQLITE_IOERR;
+ */
+-static int winMapfile(winFile *pFd, sqlite3_int64 nByte){
+-  sqlite3_int64 nMap = nByte;
+-  int rc;
+-
+-  assert( nMap>=0 || pFd->nFetchOut==0 );
+-  OSTRACE(("MAP-FILE pid=%lu, pFile=%p, size=%lld\n",
+-           osGetCurrentProcessId(), pFd, nByte));
+-
+-  if( pFd->nFetchOut>0 ) return SQLITE_OK;
+-
+-  if( nMap<0 ){
+-    rc = winFileSize((sqlite3_file*)pFd, &nMap);
+-    if( rc ){
+-      OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_IOERR_FSTAT\n",
+-               osGetCurrentProcessId(), pFd));
+-      return SQLITE_IOERR_FSTAT;
++static int winUnlock(sqlite3_file *id, int locktype){
++  int type;
++  winFile *pFile = (winFile*)id;
++  int rc = SQLITE_OK;
++  assert( pFile!=0 );
++  assert( locktype<=SHARED_LOCK );
++  OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n",
++           pFile->h, pFile->locktype, pFile->sharedLockByte, locktype));
++  type = pFile->locktype;
++  if( type>=EXCLUSIVE_LOCK ){
++    winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0);
++    if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){
++      /* This should never happen.  We should always be able to
++      ** reacquire the read lock */
++      rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(),
++                       "winUnlock", pFile->zPath);
+     }
+   }
+-  if( nMap>pFd->mmapSizeMax ){
+-    nMap = pFd->mmapSizeMax;
++  if( type>=RESERVED_LOCK ){
++    winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0);
+   }
+-  nMap &= ~(sqlite3_int64)(winSysInfo.dwPageSize - 1);
+-
+-  if( nMap==0 && pFd->mmapSize>0 ){
+-    winUnmapfile(pFd);
++  if( locktype==NO_LOCK && type>=SHARED_LOCK ){
++    winUnlockReadLock(pFile);
+   }
+-  if( nMap!=pFd->mmapSize ){
+-    void *pNew = 0;
+-    DWORD protect = PAGE_READONLY;
+-    DWORD flags = FILE_MAP_READ;
+-
+-    winUnmapfile(pFd);
+-    if( (pFd->ctrlFlags & WINFILE_RDONLY)==0 ){
+-      protect = PAGE_READWRITE;
+-      flags |= FILE_MAP_WRITE;
+-    }
+-#if SQLITE_OS_WINRT
+-    pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL);
+-#elif defined(SQLITE_WIN32_HAS_WIDE)
+-    pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect,
+-                                (DWORD)((nMap>>32) & 0xffffffff),
+-                                (DWORD)(nMap & 0xffffffff), NULL);
+-#elif defined(SQLITE_WIN32_HAS_ANSI)
+-    pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect,
+-                                (DWORD)((nMap>>32) & 0xffffffff),
+-                                (DWORD)(nMap & 0xffffffff), NULL);
+-#endif
+-    if( pFd->hMap==NULL ){
+-      pFd->lastErrno = osGetLastError();
+-      rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
+-                       "winMapfile1", pFd->zPath);
+-      /* Log the error, but continue normal operation using xRead/xWrite */
+-      OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=%s\n",
+-               osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
+-      return SQLITE_OK;
+-    }
+-    assert( (nMap % winSysInfo.dwPageSize)==0 );
+-    assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff );
+-#if SQLITE_OS_WINRT
+-    pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap);
+-#else
+-    pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap);
+-#endif
+-    if( pNew==NULL ){
+-      osCloseHandle(pFd->hMap);
+-      pFd->hMap = NULL;
+-      pFd->lastErrno = osGetLastError();
+-      rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
+-                       "winMapfile2", pFd->zPath);
+-      /* Log the error, but continue normal operation using xRead/xWrite */
+-      OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=%s\n",
+-               osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
+-      return SQLITE_OK;
+-    }
+-    pFd->pMapRegion = pNew;
+-    pFd->mmapSize = nMap;
+-    pFd->mmapSizeActual = nMap;
++  if( type>=PENDING_LOCK ){
++    winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0);
+   }
+-
+-  OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
+-           osGetCurrentProcessId(), pFd));
+-  return SQLITE_OK;
++  pFile->locktype = (u8)locktype;
++  OSTRACE(("UNLOCK file=%p, lock=%d, rc=%s\n",
++           pFile->h, pFile->locktype, sqlite3ErrName(rc)));
++  return rc;
+ }
+-#endif /* SQLITE_MAX_MMAP_SIZE>0 */
+ 
+ /*
+-** If possible, return a pointer to a mapping of file fd starting at offset
+-** iOff. The mapping must be valid for at least nAmt bytes.
+-**
+-** If such a pointer can be obtained, store it in *pp and return SQLITE_OK.
+-** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK.
+-** Finally, if an error does occur, return an SQLite error code. The final
+-** value of *pp is undefined in this case.
++** If *pArg is initially negative then this is a query.  Set *pArg to
++** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.
+ **
+-** If this function does return a pointer, the caller must eventually
+-** release the reference by calling winUnfetch().
++** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags.
+ */
+-static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
+-#if SQLITE_MAX_MMAP_SIZE>0
+-  winFile *pFd = (winFile*)fd;   /* The underlying database file */
+-#endif
+-  *pp = 0;
++static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){
++  if( *pArg<0 ){
++    *pArg = (pFile->ctrlFlags & mask)!=0;
++  }else if( (*pArg)==0 ){
++    pFile->ctrlFlags &= ~mask;
++  }else{
++    pFile->ctrlFlags |= mask;
++  }
++}
+ 
+-  OSTRACE(("FETCH pid=%lu, pFile=%p, offset=%lld, amount=%d, pp=%p\n",
+-           osGetCurrentProcessId(), fd, iOff, nAmt, pp));
++/* Forward references to VFS helper methods used for temporary files */
++static int winGetTempname(sqlite3_vfs *, char **);
++static int winIsDir(const void *);
++static BOOL winIsDriveLetterAndColon(const char *);
+ 
+-#if SQLITE_MAX_MMAP_SIZE>0
+-  if( pFd->mmapSizeMax>0 ){
+-    if( pFd->pMapRegion==0 ){
+-      int rc = winMapfile(pFd, -1);
+-      if( rc!=SQLITE_OK ){
+-        OSTRACE(("FETCH pid=%lu, pFile=%p, rc=%s\n",
+-                 osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
++/*
++** Control and query of the open file handle.
++*/
++static int winFileControl(sqlite3_file *id, int op, void *pArg){
++  winFile *pFile = (winFile*)id;
++  OSTRACE(("FCNTL file=%p, op=%d, pArg=%p\n", pFile->h, op, pArg));
++  switch( op ){
++    case SQLITE_FCNTL_LOCKSTATE: {
++      *(int*)pArg = pFile->locktype;
++      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
++      return SQLITE_OK;
++    }
++    case SQLITE_LAST_ERRNO: {
++      *(int*)pArg = (int)pFile->lastErrno;
++      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
++      return SQLITE_OK;
++    }
++    case SQLITE_FCNTL_CHUNK_SIZE: {
++      pFile->szChunk = *(int *)pArg;
++      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
++      return SQLITE_OK;
++    }
++    case SQLITE_FCNTL_SIZE_HINT: {
++      if( pFile->szChunk>0 ){
++        sqlite3_int64 oldSz;
++        int rc = winFileSize(id, &oldSz);
++        if( rc==SQLITE_OK ){
++          sqlite3_int64 newSz = *(sqlite3_int64*)pArg;
++          if( newSz>oldSz ){
++            SimulateIOErrorBenign(1);
++            rc = winTruncate(id, newSz);
++            SimulateIOErrorBenign(0);
++          }
++        }
++        OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
+         return rc;
+       }
++      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
++      return SQLITE_OK;
++    }
++    case SQLITE_FCNTL_PERSIST_WAL: {
++      winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg);
++      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
++      return SQLITE_OK;
++    }
++    case SQLITE_FCNTL_POWERSAFE_OVERWRITE: {
++      winModeBit(pFile, WINFILE_PSOW, (int*)pArg);
++      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
++      return SQLITE_OK;
++    }
++    case SQLITE_FCNTL_VFSNAME: {
++      *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
++      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
++      return SQLITE_OK;
++    }
++    case SQLITE_FCNTL_WIN32_AV_RETRY: {
++      int *a = (int*)pArg;
++      if( a[0]>0 ){
++        winIoerrRetry = a[0];
++      }else{
++        a[0] = winIoerrRetry;
++      }
++      if( a[1]>0 ){
++        winIoerrRetryDelay = a[1];
++      }else{
++        a[1] = winIoerrRetryDelay;
++      }
++      OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h));
++      return SQLITE_OK;
++    }
++#ifdef SQLITE_TEST
++    case SQLITE_FCNTL_WIN32_SET_HANDLE: {
++      LPHANDLE phFile = (LPHANDLE)pArg;
++      HANDLE hOldFile = pFile->h;
++      pFile->h = *phFile;
++      *phFile = hOldFile;
++      OSTRACE(("FCNTL oldFile=%p, newFile=%p, rc=SQLITE_OK\n",
++               hOldFile, pFile->h));
++      return SQLITE_OK;
++    }
++#endif
++    case SQLITE_FCNTL_TEMPFILENAME: {
++      char *zTFile = 0;
++      int rc = winGetTempname(pFile->pVfs, &zTFile);
++      if( rc==SQLITE_OK ){
++        *(char**)pArg = zTFile;
++      }
++      OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
++      return rc;
+     }
+-    if( pFd->mmapSize >= iOff+nAmt ){
+-      *pp = &((u8 *)pFd->pMapRegion)[iOff];
+-      pFd->nFetchOut++;
++#if SQLITE_MAX_MMAP_SIZE>0
++    case SQLITE_FCNTL_MMAP_SIZE: {
++      i64 newLimit = *(i64*)pArg;
++      int rc = SQLITE_OK;
++      if( newLimit>sqlite3GlobalConfig.mxMmap ){
++        newLimit = sqlite3GlobalConfig.mxMmap;
++      }
++      *(i64*)pArg = pFile->mmapSizeMax;
++      if( newLimit>=0 && newLimit!=pFile->mmapSizeMax && pFile->nFetchOut==0 ){
++        pFile->mmapSizeMax = newLimit;
++        if( pFile->mmapSize>0 ){
++          winUnmapfile(pFile);
++          rc = winMapfile(pFile, -1);
++        }
++      }
++      OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc)));
++      return rc;
+     }
+-  }
+ #endif
+-
+-  OSTRACE(("FETCH pid=%lu, pFile=%p, pp=%p, *pp=%p, rc=SQLITE_OK\n",
+-           osGetCurrentProcessId(), fd, pp, *pp));
+-  return SQLITE_OK;
++  }
++  OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h));
++  return SQLITE_NOTFOUND;
+ }
+ 
+ /*
+-** If the third argument is non-NULL, then this function releases a
+-** reference obtained by an earlier call to winFetch(). The second
+-** argument passed to this function must be the same as the corresponding
+-** argument that was passed to the winFetch() invocation.
++** Return the sector size in bytes of the underlying block device for
++** the specified file. This is almost always 512 bytes, but may be
++** larger for some devices.
+ **
+-** Or, if the third argument is NULL, then this function is being called
+-** to inform the VFS layer that, according to POSIX, any existing mapping
+-** may now be invalid and should be unmapped.
++** SQLite code assumes this function cannot fail. It also assumes that
++** if two files are created in the same file-system directory (i.e.
++** a database and its journal file) that the sector size will be the
++** same for both.
+ */
+-static int winUnfetch(sqlite3_file *fd, i64 iOff, void *p){
+-#if SQLITE_MAX_MMAP_SIZE>0
+-  winFile *pFd = (winFile*)fd;   /* The underlying database file */
+-
+-  /* If p==0 (unmap the entire file) then there must be no outstanding
+-  ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference),
+-  ** then there must be at least one outstanding.  */
+-  assert( (p==0)==(pFd->nFetchOut==0) );
+-
+-  /* If p!=0, it must match the iOff value. */
+-  assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] );
+-
+-  OSTRACE(("UNFETCH pid=%lu, pFile=%p, offset=%lld, p=%p\n",
+-           osGetCurrentProcessId(), pFd, iOff, p));
+-
+-  if( p ){
+-    pFd->nFetchOut--;
+-  }else{
+-    /* FIXME:  If Windows truly always prevents truncating or deleting a
+-    ** file while a mapping is held, then the following winUnmapfile() call
+-    ** is unnecessary can be omitted - potentially improving
+-    ** performance.  */
+-    winUnmapfile(pFd);
+-  }
+-
+-  assert( pFd->nFetchOut>=0 );
+-#endif
+-
+-  OSTRACE(("UNFETCH pid=%lu, pFile=%p, rc=SQLITE_OK\n",
+-           osGetCurrentProcessId(), fd));
+-  return SQLITE_OK;
++static int winSectorSize(sqlite3_file *id){
++  (void)id;
++  return SQLITE_DEFAULT_SECTOR_SIZE;
+ }
+ 
+ /*
+-** Here ends the implementation of all sqlite3_file methods.
+-**
+-********************** End sqlite3_file Methods *******************************
+-******************************************************************************/
++** Return a vector of device characteristics.
++*/
++static int winDeviceCharacteristics(sqlite3_file *id){
++  winFile *p = (winFile*)id;
++  return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN |
++         ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0);
++}
+ 
+ /*
+-** This vector defines all the methods that can operate on an
+-** sqlite3_file for win32.
++** Windows will only let you create file view mappings
++** on allocation size granularity boundaries.
++** During sqlite3_os_init() we do a GetSystemInfo()
++** to get the granularity size.
+ */
+-static const sqlite3_io_methods winIoMethod = {
+-  3,                              /* iVersion */
+-  winClose,                       /* xClose */
+-  winRead,                        /* xRead */
+-  winWrite,                       /* xWrite */
+-  winTruncate,                    /* xTruncate */
+-  winSync,                        /* xSync */
+-  winFileSize,                    /* xFileSize */
+-  winLock,                        /* xLock */
+-  winUnlock,                      /* xUnlock */
+-  winCheckReservedLock,           /* xCheckReservedLock */
+-  winFileControl,                 /* xFileControl */
+-  winSectorSize,                  /* xSectorSize */
+-  winDeviceCharacteristics,       /* xDeviceCharacteristics */
+-  winShmMap,                      /* xShmMap */
+-  winShmLock,                     /* xShmLock */
+-  winShmBarrier,                  /* xShmBarrier */
+-  winShmUnmap,                    /* xShmUnmap */
+-  winFetch,                       /* xFetch */
+-  winUnfetch                      /* xUnfetch */
+-};
++static SYSTEM_INFO winSysInfo;
+ 
+-/****************************************************************************
+-**************************** sqlite3_vfs methods ****************************
+-**
+-** This division contains the implementation of methods on the
+-** sqlite3_vfs object.
+-*/
++#ifndef SQLITE_OMIT_WAL
+ 
+-#if defined(__CYGWIN__)
+ /*
+-** Convert a filename from whatever the underlying operating system
+-** supports for filenames into UTF-8.  Space to hold the result is
+-** obtained from malloc and must be freed by the calling function.
++** Helper functions to obtain and relinquish the global mutex. The
++** global mutex is used to protect the winLockInfo objects used by
++** this file, all of which may be shared by multiple threads.
++**
++** Function winShmMutexHeld() is used to assert() that the global mutex
++** is held when required. This function is only used as part of assert()
++** statements. e.g.
++**
++**   winShmEnterMutex()
++**     assert( winShmMutexHeld() );
++**   winShmLeaveMutex()
+ */
+-static char *winConvertToUtf8Filename(const void *zFilename){
+-  char *zConverted = 0;
+-  if( osIsNT() ){
+-    zConverted = winUnicodeToUtf8(zFilename);
+-  }
+-#ifdef SQLITE_WIN32_HAS_ANSI
+-  else{
+-    zConverted = sqlite3_win32_mbcs_to_utf8(zFilename);
+-  }
+-#endif
+-  /* caller will handle out of memory */
+-  return zConverted;
++static void winShmEnterMutex(void){
++  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
++}
++static void winShmLeaveMutex(void){
++  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
++}
++#ifndef NDEBUG
++static int winShmMutexHeld(void) {
++  return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
+ }
+ #endif
+ 
+ /*
+-** Convert a UTF-8 filename into whatever form the underlying
+-** operating system wants filenames in.  Space to hold the result
+-** is obtained from malloc and must be freed by the calling
+-** function.
++** Object used to represent a single file opened and mmapped to provide
++** shared memory.  When multiple threads all reference the same
++** log-summary, each thread has its own winFile object, but they all
++** point to a single instance of this object.  In other words, each
++** log-summary is opened only once per process.
++**
++** winShmMutexHeld() must be true when creating or destroying
++** this object or while reading or writing the following fields:
++**
++**      nRef
++**      pNext
++**
++** The following fields are read-only after the object is created:
++**
++**      fid
++**      zFilename
++**
++** Either winShmNode.mutex must be held or winShmNode.nRef==0 and
++** winShmMutexHeld() is true when reading or writing any other field
++** in this structure.
++**
+ */
+-static void *winConvertFromUtf8Filename(const char *zFilename){
+-  void *zConverted = 0;
+-  if( osIsNT() ){
+-    zConverted = winUtf8ToUnicode(zFilename);
+-  }
+-#ifdef SQLITE_WIN32_HAS_ANSI
+-  else{
+-    zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);
+-  }
++struct winShmNode {
++  sqlite3_mutex *mutex;      /* Mutex to access this object */
++  char *zFilename;           /* Name of the file */
++  winFile hFile;             /* File handle from winOpen */
++
++  int szRegion;              /* Size of shared-memory regions */
++  int nRegion;               /* Size of array apRegion */
++  struct ShmRegion {
++    HANDLE hMap;             /* File handle from CreateFileMapping */
++    void *pMap;
++  } *aRegion;
++  DWORD lastErrno;           /* The Windows errno from the last I/O error */
++
++  int nRef;                  /* Number of winShm objects pointing to this */
++  winShm *pFirst;            /* All winShm objects pointing to this */
++  winShmNode *pNext;         /* Next in list of all winShmNode objects */
++#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
++  u8 nextShmId;              /* Next available winShm.id value */
+ #endif
+-  /* caller will handle out of memory */
+-  return zConverted;
+-}
++};
+ 
+ /*
+-** This function returns non-zero if the specified UTF-8 string buffer
+-** ends with a directory separator character or one was successfully
+-** added to it.
++** A global array of all winShmNode objects.
++**
++** The winShmMutexHeld() must be true while reading or writing this list.
+ */
+-static int winMakeEndInDirSep(int nBuf, char *zBuf){
+-  if( zBuf ){
+-    int nLen = sqlite3Strlen30(zBuf);
+-    if( nLen>0 ){
+-      if( winIsDirSep(zBuf[nLen-1]) ){
+-        return 1;
+-      }else if( nLen+1<nBuf ){
+-        zBuf[nLen] = winGetDirSep();
+-        zBuf[nLen+1] = '\0';
+-        return 1;
+-      }
+-    }
+-  }
+-  return 0;
+-}
++static winShmNode *winShmNodeList = 0;
+ 
+ /*
+-** Create a temporary file name and store the resulting pointer into pzBuf.
+-** The pointer returned in pzBuf must be freed via sqlite3_free().
++** Structure used internally by this VFS to record the state of an
++** open shared memory connection.
++**
++** The following fields are initialized when this object is created and
++** are read-only thereafter:
++**
++**    winShm.pShmNode
++**    winShm.id
++**
++** All other fields are read/write.  The winShm.pShmNode->mutex must be held
++** while accessing any read/write fields.
+ */
+-static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
+-  static char zChars[] =
+-    "abcdefghijklmnopqrstuvwxyz"
+-    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+-    "0123456789";
+-  size_t i, j;
+-  int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX);
+-  int nMax, nBuf, nDir, nLen;
+-  char *zBuf;
+-
+-  /* It's odd to simulate an io-error here, but really this is just
+-  ** using the io-error infrastructure to test that SQLite handles this
+-  ** function failing.
+-  */
+-  SimulateIOError( return SQLITE_IOERR );
++struct winShm {
++  winShmNode *pShmNode;      /* The underlying winShmNode object */
++  winShm *pNext;             /* Next winShm with the same winShmNode */
++  u8 hasMutex;               /* True if holding the winShmNode mutex */
++  u16 sharedMask;            /* Mask of shared locks held */
++  u16 exclMask;              /* Mask of exclusive locks held */
++#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
++  u8 id;                     /* Id of this connection with its winShmNode */
++#endif
++};
+ 
+-  /* Allocate a temporary buffer to store the fully qualified file
+-  ** name for the temporary file.  If this fails, we cannot continue.
+-  */
+-  nMax = pVfs->mxPathname; nBuf = nMax + 2;
+-  zBuf = sqlite3MallocZero( nBuf );
+-  if( !zBuf ){
+-    OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+-    return SQLITE_IOERR_NOMEM;
+-  }
++/*
++** Constants used for locking
++*/
++#define WIN_SHM_BASE   ((22+SQLITE_SHM_NLOCK)*4)        /* first lock byte */
++#define WIN_SHM_DMS    (WIN_SHM_BASE+SQLITE_SHM_NLOCK)  /* deadman switch */
+ 
+-  /* Figure out the effective temporary directory.  First, check if one
+-  ** has been explicitly set by the application; otherwise, use the one
+-  ** configured by the operating system.
+-  */
+-  nDir = nMax - (nPre + 15);
+-  assert( nDir>0 );
+-  if( sqlite3_temp_directory ){
+-    int nDirLen = sqlite3Strlen30(sqlite3_temp_directory);
+-    if( nDirLen>0 ){
+-      if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){
+-        nDirLen++;
+-      }
+-      if( nDirLen>nDir ){
+-        sqlite3_free(zBuf);
+-        OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
+-        return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0);
+-      }
+-      sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory);
+-    }
+-  }
+-#if defined(__CYGWIN__)
+-  else{
+-    static const char *azDirs[] = {
+-       0, /* getenv("SQLITE_TMPDIR") */
+-       0, /* getenv("TMPDIR") */
+-       0, /* getenv("TMP") */
+-       0, /* getenv("TEMP") */
+-       0, /* getenv("USERPROFILE") */
+-       "/var/tmp",
+-       "/usr/tmp",
+-       "/tmp",
+-       ".",
+-       0        /* List terminator */
+-    };
+-    unsigned int i;
+-    const char *zDir = 0;
++/*
++** Apply advisory locks for all n bytes beginning at ofst.
++*/
++#define _SHM_UNLCK  1
++#define _SHM_RDLCK  2
++#define _SHM_WRLCK  3
++static int winShmSystemLock(
++  winShmNode *pFile,    /* Apply locks to this open shared-memory segment */
++  int lockType,         /* _SHM_UNLCK, _SHM_RDLCK, or _SHM_WRLCK */
++  int ofst,             /* Offset to first byte to be locked/unlocked */
++  int nByte             /* Number of bytes to lock or unlock */
++){
++  int rc = 0;           /* Result code form Lock/UnlockFileEx() */
+ 
+-    if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR");
+-    if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
+-    if( !azDirs[2] ) azDirs[2] = getenv("TMP");
+-    if( !azDirs[3] ) azDirs[3] = getenv("TEMP");
+-    if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE");
+-    for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
+-      void *zConverted;
+-      if( zDir==0 ) continue;
+-      /* If the path starts with a drive letter followed by the colon
+-      ** character, assume it is already a native Win32 path; otherwise,
+-      ** it must be converted to a native Win32 path via the Cygwin API
+-      ** prior to using it.
+-      */
+-      if( winIsDriveLetterAndColon(zDir) ){
+-        zConverted = winConvertFromUtf8Filename(zDir);
+-        if( !zConverted ){
+-          sqlite3_free(zBuf);
+-          OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+-          return SQLITE_IOERR_NOMEM;
+-        }
+-        if( winIsDir(zConverted) ){
+-          sqlite3_snprintf(nMax, zBuf, "%s", zDir);
+-          sqlite3_free(zConverted);
+-          break;
+-        }
+-        sqlite3_free(zConverted);
+-      }else{
+-        zConverted = sqlite3MallocZero( nMax+1 );
+-        if( !zConverted ){
+-          sqlite3_free(zBuf);
+-          OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+-          return SQLITE_IOERR_NOMEM;
+-        }
+-        if( cygwin_conv_path(
+-                osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir,
+-                zConverted, nMax+1)<0 ){
+-          sqlite3_free(zConverted);
+-          sqlite3_free(zBuf);
+-          OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n"));
+-          return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno,
+-                             "winGetTempname2", zDir);
+-        }
+-        if( winIsDir(zConverted) ){
+-          /* At this point, we know the candidate directory exists and should
+-          ** be used.  However, we may need to convert the string containing
+-          ** its name into UTF-8 (i.e. if it is UTF-16 right now).
+-          */
+-          char *zUtf8 = winConvertToUtf8Filename(zConverted);
+-          if( !zUtf8 ){
+-            sqlite3_free(zConverted);
+-            sqlite3_free(zBuf);
+-            OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+-            return SQLITE_IOERR_NOMEM;
+-          }
+-          sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
+-          sqlite3_free(zUtf8);
+-          sqlite3_free(zConverted);
+-          break;
+-        }
+-        sqlite3_free(zConverted);
+-      }
+-    }
+-  }
+-#elif !SQLITE_OS_WINRT && !defined(__CYGWIN__)
+-  else if( osIsNT() ){
+-    char *zMulti;
+-    LPWSTR zWidePath = sqlite3MallocZero( nMax*sizeof(WCHAR) );
+-    if( !zWidePath ){
+-      sqlite3_free(zBuf);
+-      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+-      return SQLITE_IOERR_NOMEM;
+-    }
+-    if( osGetTempPathW(nMax, zWidePath)==0 ){
+-      sqlite3_free(zWidePath);
+-      sqlite3_free(zBuf);
+-      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
+-      return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
+-                         "winGetTempname2", 0);
+-    }
+-    zMulti = winUnicodeToUtf8(zWidePath);
+-    if( zMulti ){
+-      sqlite3_snprintf(nMax, zBuf, "%s", zMulti);
+-      sqlite3_free(zMulti);
+-      sqlite3_free(zWidePath);
+-    }else{
+-      sqlite3_free(zWidePath);
+-      sqlite3_free(zBuf);
+-      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+-      return SQLITE_IOERR_NOMEM;
+-    }
+-  }
+-#ifdef SQLITE_WIN32_HAS_ANSI
+-  else{
+-    char *zUtf8;
+-    char *zMbcsPath = sqlite3MallocZero( nMax );
+-    if( !zMbcsPath ){
+-      sqlite3_free(zBuf);
+-      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+-      return SQLITE_IOERR_NOMEM;
+-    }
+-    if( osGetTempPathA(nMax, zMbcsPath)==0 ){
+-      sqlite3_free(zBuf);
+-      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
+-      return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
+-                         "winGetTempname3", 0);
+-    }
+-    zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
+-    if( zUtf8 ){
+-      sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
+-      sqlite3_free(zUtf8);
+-    }else{
+-      sqlite3_free(zBuf);
+-      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+-      return SQLITE_IOERR_NOMEM;
+-    }
+-  }
+-#endif /* SQLITE_WIN32_HAS_ANSI */
+-#endif /* !SQLITE_OS_WINRT */
++  /* Access to the winShmNode object is serialized by the caller */
++  assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 );
+ 
+-  /*
+-  ** Check to make sure the temporary directory ends with an appropriate
+-  ** separator.  If it does not and there is not enough space left to add
+-  ** one, fail.
+-  */
+-  if( !winMakeEndInDirSep(nDir+1, zBuf) ){
+-    sqlite3_free(zBuf);
+-    OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
+-    return winLogError(SQLITE_ERROR, 0, "winGetTempname4", 0);
+-  }
++  OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n",
++           pFile->hFile.h, lockType, ofst, nByte));
+ 
+-  /*
+-  ** Check that the output buffer is large enough for the temporary file
+-  ** name in the following format:
+-  **
+-  **   "<temporary_directory>/etilqs_XXXXXXXXXXXXXXX\0\0"
+-  **
+-  ** If not, return SQLITE_ERROR.  The number 17 is used here in order to
+-  ** account for the space used by the 15 character random suffix and the
+-  ** two trailing NUL characters.  The final directory separator character
+-  ** has already added if it was not already present.
+-  */
+-  nLen = sqlite3Strlen30(zBuf);
+-  if( (nLen + nPre + 17) > nBuf ){
+-    sqlite3_free(zBuf);
+-    OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
+-    return winLogError(SQLITE_ERROR, 0, "winGetTempname5", 0);
++  /* Release/Acquire the system-level lock */
++  if( lockType==_SHM_UNLCK ){
++    rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0);
++  }else{
++    /* Initialize the locking parameters */
++    DWORD dwFlags = LOCKFILE_FAIL_IMMEDIATELY;
++    if( lockType == _SHM_WRLCK ) dwFlags |= LOCKFILE_EXCLUSIVE_LOCK;
++    rc = winLockFile(&pFile->hFile.h, dwFlags, ofst, 0, nByte, 0);
+   }
+ 
+-  sqlite3_snprintf(nBuf-16-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX);
+-
+-  j = sqlite3Strlen30(zBuf);
+-  sqlite3_randomness(15, &zBuf[j]);
+-  for(i=0; i<15; i++, j++){
+-    zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
++  if( rc!= 0 ){
++    rc = SQLITE_OK;
++  }else{
++    pFile->lastErrno =  osGetLastError();
++    rc = SQLITE_BUSY;
+   }
+-  zBuf[j] = 0;
+-  zBuf[j+1] = 0;
+-  *pzBuf = zBuf;
+ 
+-  OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf));
+-  return SQLITE_OK;
++  OSTRACE(("SHM-LOCK file=%p, func=%s, errno=%lu, rc=%s\n",
++           pFile->hFile.h, (lockType == _SHM_UNLCK) ? "winUnlockFile" :
++           "winLockFile", pFile->lastErrno, sqlite3ErrName(rc)));
++
++  return rc;
+ }
+ 
++/* Forward references to VFS methods */
++static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*);
++static int winDelete(sqlite3_vfs *,const char*,int);
++
+ /*
+-** Return TRUE if the named file is really a directory.  Return false if
+-** it is something other than a directory, or if there is any kind of memory
+-** allocation failure.
++** Purge the winShmNodeList list of all entries with winShmNode.nRef==0.
++**
++** This is not a VFS shared-memory method; it is a utility function called
++** by VFS shared-memory methods.
+ */
+-static int winIsDir(const void *zConverted){
+-  DWORD attr;
+-  int rc = 0;
+-  DWORD lastErrno;
+-
+-  if( osIsNT() ){
+-    int cnt = 0;
+-    WIN32_FILE_ATTRIBUTE_DATA sAttrData;
+-    memset(&sAttrData, 0, sizeof(sAttrData));
+-    while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
+-                             GetFileExInfoStandard,
+-                             &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){}
+-    if( !rc ){
+-      return 0; /* Invalid name? */
++static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){
++  winShmNode **pp;
++  winShmNode *p;
++  assert( winShmMutexHeld() );
++  OSTRACE(("SHM-PURGE pid=%lu, deleteFlag=%d\n",
++           osGetCurrentProcessId(), deleteFlag));
++  pp = &winShmNodeList;
++  while( (p = *pp)!=0 ){
++    if( p->nRef==0 ){
++      int i;
++      if( p->mutex ){ sqlite3_mutex_free(p->mutex); }
++      for(i=0; i<p->nRegion; i++){
++        BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap);
++        OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n",
++                 osGetCurrentProcessId(), i, bRc ? "ok" : "failed"));
++        UNUSED_VARIABLE_VALUE(bRc);
++        bRc = osCloseHandle(p->aRegion[i].hMap);
++        OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n",
++                 osGetCurrentProcessId(), i, bRc ? "ok" : "failed"));
++        UNUSED_VARIABLE_VALUE(bRc);
++      }
++      if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){
++        SimulateIOErrorBenign(1);
++        winClose((sqlite3_file *)&p->hFile);
++        SimulateIOErrorBenign(0);
++      }
++      if( deleteFlag ){
++        SimulateIOErrorBenign(1);
++        sqlite3BeginBenignMalloc();
++        winDelete(pVfs, p->zFilename, 0);
++        sqlite3EndBenignMalloc();
++        SimulateIOErrorBenign(0);
++      }
++      *pp = p->pNext;
++      sqlite3_free(p->aRegion);
++      sqlite3_free(p);
++    }else{
++      pp = &p->pNext;
+     }
+-    attr = sAttrData.dwFileAttributes;
+-#if SQLITE_OS_WINCE==0
+-  }else{
+-    attr = osGetFileAttributesA((char*)zConverted);
+-#endif
+   }
+-  return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY);
+ }
+ 
+ /*
+-** Open a file.
++** Open the shared-memory area associated with database file pDbFd.
++**
++** When opening a new shared-memory file, if no other instances of that
++** file are currently open, in this process or in other processes, then
++** the file must be truncated to zero length or have its header cleared.
+ */
+-static int winOpen(
+-  sqlite3_vfs *pVfs,        /* Used to get maximum path name length */
+-  const char *zName,        /* Name of the file (UTF-8) */
+-  sqlite3_file *id,         /* Write the SQLite file handle here */
+-  int flags,                /* Open mode flags */
+-  int *pOutFlags            /* Status return flags */
+-){
+-  HANDLE h;
+-  DWORD lastErrno = 0;
+-  DWORD dwDesiredAccess;
+-  DWORD dwShareMode;
+-  DWORD dwCreationDisposition;
+-  DWORD dwFlagsAndAttributes = 0;
+-#if SQLITE_OS_WINCE
+-  int isTemp = 0;
+-#endif
+-  winFile *pFile = (winFile*)id;
+-  void *zConverted;              /* Filename in OS encoding */
+-  const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */
+-  int cnt = 0;
+-
+-  /* If argument zPath is a NULL pointer, this function is required to open
+-  ** a temporary file. Use this buffer to store the file name in.
+-  */
+-  char *zTmpname = 0; /* For temporary filename, if necessary. */
+-
+-  int rc = SQLITE_OK;            /* Function Return Code */
+-#if !defined(NDEBUG) || SQLITE_OS_WINCE
+-  int eType = flags&0xFFFFFF00;  /* Type of file to open */
+-#endif
+-
+-  int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);
+-  int isDelete     = (flags & SQLITE_OPEN_DELETEONCLOSE);
+-  int isCreate     = (flags & SQLITE_OPEN_CREATE);
+-  int isReadonly   = (flags & SQLITE_OPEN_READONLY);
+-  int isReadWrite  = (flags & SQLITE_OPEN_READWRITE);
+-
+-#ifndef NDEBUG
+-  int isOpenJournal = (isCreate && (
+-        eType==SQLITE_OPEN_MASTER_JOURNAL
+-     || eType==SQLITE_OPEN_MAIN_JOURNAL
+-     || eType==SQLITE_OPEN_WAL
+-  ));
+-#endif
++static int winOpenSharedMemory(winFile *pDbFd){
++  struct winShm *p;                  /* The connection to be opened */
++  struct winShmNode *pShmNode = 0;   /* The underlying mmapped file */
++  int rc;                            /* Result code */
++  struct winShmNode *pNew;           /* Newly allocated winShmNode */
++  int nName;                         /* Size of zName in bytes */
+ 
+-  OSTRACE(("OPEN name=%s, pFile=%p, flags=%x, pOutFlags=%p\n",
+-           zUtf8Name, id, flags, pOutFlags));
++  assert( pDbFd->pShm==0 );    /* Not previously opened */
+ 
+-  /* Check the following statements are true:
+-  **
+-  **   (a) Exactly one of the READWRITE and READONLY flags must be set, and
+-  **   (b) if CREATE is set, then READWRITE must also be set, and
+-  **   (c) if EXCLUSIVE is set, then CREATE must also be set.
+-  **   (d) if DELETEONCLOSE is set, then CREATE must also be set.
++  /* Allocate space for the new sqlite3_shm object.  Also speculatively
++  ** allocate space for a new winShmNode and filename.
+   */
+-  assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly));
+-  assert(isCreate==0 || isReadWrite);
+-  assert(isExclusive==0 || isCreate);
+-  assert(isDelete==0 || isCreate);
++  p = sqlite3MallocZero( sizeof(*p) );
++  if( p==0 ) return SQLITE_IOERR_NOMEM;
++  nName = sqlite3Strlen30(pDbFd->zPath);
++  pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 );
++  if( pNew==0 ){
++    sqlite3_free(p);
++    return SQLITE_IOERR_NOMEM;
++  }
++  pNew->zFilename = (char*)&pNew[1];
++  sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
++  sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename);
+ 
+-  /* The main DB, main journal, WAL file and master journal are never
+-  ** automatically deleted. Nor are they ever temporary files.  */
+-  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB );
+-  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL );
+-  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL );
+-  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL );
++  /* Look to see if there is an existing winShmNode that can be used.
++  ** If no matching winShmNode currently exists, create a new one.
++  */
++  winShmEnterMutex();
++  for(pShmNode = winShmNodeList; pShmNode; pShmNode=pShmNode->pNext){
++    /* TBD need to come up with better match here.  Perhaps
++    ** use FILE_ID_BOTH_DIR_INFO Structure.
++    */
++    if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break;
++  }
++  if( pShmNode ){
++    sqlite3_free(pNew);
++  }else{
++    pShmNode = pNew;
++    pNew = 0;
++    ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE;
++    pShmNode->pNext = winShmNodeList;
++    winShmNodeList = pShmNode;
+ 
+-  /* Assert that the upper layer has set one of the "file-type" flags. */
+-  assert( eType==SQLITE_OPEN_MAIN_DB      || eType==SQLITE_OPEN_TEMP_DB
+-       || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL
+-       || eType==SQLITE_OPEN_SUBJOURNAL   || eType==SQLITE_OPEN_MASTER_JOURNAL
+-       || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
+-  );
++    pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
++    if( pShmNode->mutex==0 ){
++      rc = SQLITE_IOERR_NOMEM;
++      goto shm_open_err;
++    }
+ 
+-  assert( pFile!=0 );
+-  memset(pFile, 0, sizeof(winFile));
+-  pFile->h = INVALID_HANDLE_VALUE;
++    rc = winOpen(pDbFd->pVfs,
++                 pShmNode->zFilename,             /* Name of the file (UTF-8) */
++                 (sqlite3_file*)&pShmNode->hFile,  /* File handle here */
++                 SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
++                 0);
++    if( SQLITE_OK!=rc ){
++      goto shm_open_err;
++    }
+ 
+-#if SQLITE_OS_WINRT
+-  if( !zUtf8Name && !sqlite3_temp_directory ){
+-    sqlite3_log(SQLITE_ERROR,
+-        "sqlite3_temp_directory variable should be set for WinRT");
++    /* Check to see if another process is holding the dead-man switch.
++    ** If not, truncate the file to zero length.
++    */
++    if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
++      rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
++      if( rc!=SQLITE_OK ){
++        rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(),
++                         "winOpenShm", pDbFd->zPath);
++      }
++    }
++    if( rc==SQLITE_OK ){
++      winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
++      rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
++    }
++    if( rc ) goto shm_open_err;
+   }
++
++  /* Make the new connection a child of the winShmNode */
++  p->pShmNode = pShmNode;
++#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
++  p->id = pShmNode->nextShmId++;
+ #endif
++  pShmNode->nRef++;
++  pDbFd->pShm = p;
++  winShmLeaveMutex();
+ 
+-  /* If the second argument to this function is NULL, generate a
+-  ** temporary file name to use
++  /* The reference count on pShmNode has already been incremented under
++  ** the cover of the winShmEnterMutex() mutex and the pointer from the
++  ** new (struct winShm) object to the pShmNode has been set. All that is
++  ** left to do is to link the new object into the linked list starting
++  ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex
++  ** mutex.
+   */
+-  if( !zUtf8Name ){
+-    assert( isDelete && !isOpenJournal );
+-    rc = winGetTempname(pVfs, &zTmpname);
+-    if( rc!=SQLITE_OK ){
+-      OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc)));
+-      return rc;
+-    }
+-    zUtf8Name = zTmpname;
+-  }
++  sqlite3_mutex_enter(pShmNode->mutex);
++  p->pNext = pShmNode->pFirst;
++  pShmNode->pFirst = p;
++  sqlite3_mutex_leave(pShmNode->mutex);
++  return SQLITE_OK;
+ 
+-  /* Database filenames are double-zero terminated if they are not
+-  ** URIs with parameters.  Hence, they can always be passed into
+-  ** sqlite3_uri_parameter().
+-  */
+-  assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) ||
+-       zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 );
++  /* Jump here on any error */
++shm_open_err:
++  winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
++  winShmPurge(pDbFd->pVfs, 0);      /* This call frees pShmNode if required */
++  sqlite3_free(p);
++  sqlite3_free(pNew);
++  winShmLeaveMutex();
++  return rc;
++}
+ 
+-  /* Convert the filename to the system encoding. */
+-  zConverted = winConvertFromUtf8Filename(zUtf8Name);
+-  if( zConverted==0 ){
+-    sqlite3_free(zTmpname);
+-    OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name));
+-    return SQLITE_IOERR_NOMEM;
+-  }
++/*
++** Close a connection to shared-memory.  Delete the underlying
++** storage if deleteFlag is true.
++*/
++static int winShmUnmap(
++  sqlite3_file *fd,          /* Database holding shared memory */
++  int deleteFlag             /* Delete after closing if true */
++){
++  winFile *pDbFd;       /* Database holding shared-memory */
++  winShm *p;            /* The connection to be closed */
++  winShmNode *pShmNode; /* The underlying shared-memory file */
++  winShm **pp;          /* For looping over sibling connections */
+ 
+-  if( winIsDir(zConverted) ){
+-    sqlite3_free(zConverted);
+-    sqlite3_free(zTmpname);
+-    OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name));
+-    return SQLITE_CANTOPEN_ISDIR;
+-  }
++  pDbFd = (winFile*)fd;
++  p = pDbFd->pShm;
++  if( p==0 ) return SQLITE_OK;
++  pShmNode = p->pShmNode;
+ 
+-  if( isReadWrite ){
+-    dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
+-  }else{
+-    dwDesiredAccess = GENERIC_READ;
+-  }
++  /* Remove connection p from the set of connections associated
++  ** with pShmNode */
++  sqlite3_mutex_enter(pShmNode->mutex);
++  for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
++  *pp = p->pNext;
+ 
+-  /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is
+-  ** created. SQLite doesn't use it to indicate "exclusive access"
+-  ** as it is usually understood.
+-  */
+-  if( isExclusive ){
+-    /* Creates a new file, only if it does not already exist. */
+-    /* If the file exists, it fails. */
+-    dwCreationDisposition = CREATE_NEW;
+-  }else if( isCreate ){
+-    /* Open existing file, or create if it doesn't exist */
+-    dwCreationDisposition = OPEN_ALWAYS;
+-  }else{
+-    /* Opens a file, only if it exists. */
+-    dwCreationDisposition = OPEN_EXISTING;
++  /* Free the connection p */
++  sqlite3_free(p);
++  pDbFd->pShm = 0;
++  sqlite3_mutex_leave(pShmNode->mutex);
++
++  /* If pShmNode->nRef has reached 0, then close the underlying
++  ** shared-memory file, too */
++  winShmEnterMutex();
++  assert( pShmNode->nRef>0 );
++  pShmNode->nRef--;
++  if( pShmNode->nRef==0 ){
++    winShmPurge(pDbFd->pVfs, deleteFlag);
+   }
++  winShmLeaveMutex();
+ 
+-  dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
++  return SQLITE_OK;
++}
+ 
+-  if( isDelete ){
+-#if SQLITE_OS_WINCE
+-    dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN;
+-    isTemp = 1;
+-#else
+-    dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY
+-                               | FILE_ATTRIBUTE_HIDDEN
+-                               | FILE_FLAG_DELETE_ON_CLOSE;
+-#endif
+-  }else{
+-    dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
+-  }
+-  /* Reports from the internet are that performance is always
+-  ** better if FILE_FLAG_RANDOM_ACCESS is used.  Ticket #2699. */
+-#if SQLITE_OS_WINCE
+-  dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
+-#endif
++/*
++** Change the lock state for a shared-memory segment.
++*/
++static int winShmLock(
++  sqlite3_file *fd,          /* Database file holding the shared memory */
++  int ofst,                  /* First lock to acquire or release */
++  int n,                     /* Number of locks to acquire or release */
++  int flags                  /* What to do with the lock */
++){
++  winFile *pDbFd = (winFile*)fd;        /* Connection holding shared memory */
++  winShm *p = pDbFd->pShm;              /* The shared memory being locked */
++  winShm *pX;                           /* For looping over all siblings */
++  winShmNode *pShmNode = p->pShmNode;
++  int rc = SQLITE_OK;                   /* Result code */
++  u16 mask;                             /* Mask of locks to take or release */
+ 
+-  if( osIsNT() ){
+-#if SQLITE_OS_WINRT
+-    CREATEFILE2_EXTENDED_PARAMETERS extendedParameters;
+-    extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
+-    extendedParameters.dwFileAttributes =
+-            dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK;
+-    extendedParameters.dwFileFlags = dwFlagsAndAttributes & FILE_FLAG_MASK;
+-    extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS;
+-    extendedParameters.lpSecurityAttributes = NULL;
+-    extendedParameters.hTemplateFile = NULL;
+-    while( (h = osCreateFile2((LPCWSTR)zConverted,
+-                              dwDesiredAccess,
+-                              dwShareMode,
+-                              dwCreationDisposition,
+-                              &extendedParameters))==INVALID_HANDLE_VALUE &&
+-                              winRetryIoerr(&cnt, &lastErrno) ){
+-               /* Noop */
+-    }
+-#else
+-    while( (h = osCreateFileW((LPCWSTR)zConverted,
+-                              dwDesiredAccess,
+-                              dwShareMode, NULL,
+-                              dwCreationDisposition,
+-                              dwFlagsAndAttributes,
+-                              NULL))==INVALID_HANDLE_VALUE &&
+-                              winRetryIoerr(&cnt, &lastErrno) ){
+-               /* Noop */
+-    }
+-#endif
+-  }
+-#ifdef SQLITE_WIN32_HAS_ANSI
+-  else{
+-    while( (h = osCreateFileA((LPCSTR)zConverted,
+-                              dwDesiredAccess,
+-                              dwShareMode, NULL,
+-                              dwCreationDisposition,
+-                              dwFlagsAndAttributes,
+-                              NULL))==INVALID_HANDLE_VALUE &&
+-                              winRetryIoerr(&cnt, &lastErrno) ){
+-               /* Noop */
+-    }
+-  }
+-#endif
+-  winLogIoerr(cnt, __LINE__);
++  assert( ofst>=0 && ofst+n<=SQLITE_SHM_NLOCK );
++  assert( n>=1 );
++  assert( flags==(SQLITE_SHM_LOCK | SQLITE_SHM_SHARED)
++       || flags==(SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE)
++       || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED)
++       || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
++  assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
+ 
+-  OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name,
+-           dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));
++  mask = (u16)((1U<<(ofst+n)) - (1U<<ofst));
++  assert( n>1 || mask==(1<<ofst) );
++  sqlite3_mutex_enter(pShmNode->mutex);
++  if( flags & SQLITE_SHM_UNLOCK ){
++    u16 allMask = 0; /* Mask of locks held by siblings */
+ 
+-  if( h==INVALID_HANDLE_VALUE ){
+-    pFile->lastErrno = lastErrno;
+-    winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
+-    sqlite3_free(zConverted);
+-    sqlite3_free(zTmpname);
+-    if( isReadWrite && !isExclusive ){
+-      return winOpen(pVfs, zName, id,
+-         ((flags|SQLITE_OPEN_READONLY) &
+-                     ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
+-         pOutFlags);
+-    }else{
+-      return SQLITE_CANTOPEN_BKPT;
++    /* See if any siblings hold this same lock */
++    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
++      if( pX==p ) continue;
++      assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 );
++      allMask |= pX->sharedMask;
+     }
+-  }
+ 
+-  if( pOutFlags ){
+-    if( isReadWrite ){
+-      *pOutFlags = SQLITE_OPEN_READWRITE;
++    /* Unlock the system-level locks */
++    if( (mask & allMask)==0 ){
++      rc = winShmSystemLock(pShmNode, _SHM_UNLCK, ofst+WIN_SHM_BASE, n);
+     }else{
+-      *pOutFlags = SQLITE_OPEN_READONLY;
++      rc = SQLITE_OK;
+     }
+-  }
+ 
+-  OSTRACE(("OPEN file=%p, name=%s, access=%lx, pOutFlags=%p, *pOutFlags=%d, "
+-           "rc=%s\n", h, zUtf8Name, dwDesiredAccess, pOutFlags, pOutFlags ?
+-           *pOutFlags : 0, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));
++    /* Undo the local locks */
++    if( rc==SQLITE_OK ){
++      p->exclMask &= ~mask;
++      p->sharedMask &= ~mask;
++    }
++  }else if( flags & SQLITE_SHM_SHARED ){
++    u16 allShared = 0;  /* Union of locks held by connections other than "p" */
+ 
+-#if SQLITE_OS_WINCE
+-  if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
+-       && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK
+-  ){
+-    osCloseHandle(h);
+-    sqlite3_free(zConverted);
+-    sqlite3_free(zTmpname);
+-    OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc)));
+-    return rc;
+-  }
+-  if( isTemp ){
+-    pFile->zDeleteOnClose = zConverted;
+-  }else
+-#endif
+-  {
+-    sqlite3_free(zConverted);
+-  }
++    /* Find out which shared locks are already held by sibling connections.
++    ** If any sibling already holds an exclusive lock, go ahead and return
++    ** SQLITE_BUSY.
++    */
++    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
++      if( (pX->exclMask & mask)!=0 ){
++        rc = SQLITE_BUSY;
++        break;
++      }
++      allShared |= pX->sharedMask;
++    }
++
++    /* Get shared locks at the system level, if necessary */
++    if( rc==SQLITE_OK ){
++      if( (allShared & mask)==0 ){
++        rc = winShmSystemLock(pShmNode, _SHM_RDLCK, ofst+WIN_SHM_BASE, n);
++      }else{
++        rc = SQLITE_OK;
++      }
++    }
+ 
+-  sqlite3_free(zTmpname);
+-  pFile->pMethod = &winIoMethod;
+-  pFile->pVfs = pVfs;
+-  pFile->h = h;
+-  if( isReadonly ){
+-    pFile->ctrlFlags |= WINFILE_RDONLY;
+-  }
+-  if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
+-    pFile->ctrlFlags |= WINFILE_PSOW;
+-  }
+-  pFile->lastErrno = NO_ERROR;
+-  pFile->zPath = zName;
+-#if SQLITE_MAX_MMAP_SIZE>0
+-  pFile->hMap = NULL;
+-  pFile->pMapRegion = 0;
+-  pFile->mmapSize = 0;
+-  pFile->mmapSizeActual = 0;
+-  pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap;
+-#endif
++    /* Get the local shared locks */
++    if( rc==SQLITE_OK ){
++      p->sharedMask |= mask;
++    }
++  }else{
++    /* Make sure no sibling connections hold locks that will block this
++    ** lock.  If any do, return SQLITE_BUSY right away.
++    */
++    for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
++      if( (pX->exclMask & mask)!=0 || (pX->sharedMask & mask)!=0 ){
++        rc = SQLITE_BUSY;
++        break;
++      }
++    }
+ 
+-  OpenCounter(+1);
++    /* Get the exclusive locks at the system level.  Then if successful
++    ** also mark the local connection as being locked.
++    */
++    if( rc==SQLITE_OK ){
++      rc = winShmSystemLock(pShmNode, _SHM_WRLCK, ofst+WIN_SHM_BASE, n);
++      if( rc==SQLITE_OK ){
++        assert( (p->sharedMask & mask)==0 );
++        p->exclMask |= mask;
++      }
++    }
++  }
++  sqlite3_mutex_leave(pShmNode->mutex);
++  OSTRACE(("SHM-LOCK pid=%lu, id=%d, sharedMask=%03x, exclMask=%03x, rc=%s\n",
++           osGetCurrentProcessId(), p->id, p->sharedMask, p->exclMask,
++           sqlite3ErrName(rc)));
+   return rc;
+ }
+ 
+ /*
+-** Delete the named file.
++** Implement a memory barrier or memory fence on shared memory.
+ **
+-** Note that Windows does not allow a file to be deleted if some other
+-** process has it open.  Sometimes a virus scanner or indexing program
+-** will open a journal file shortly after it is created in order to do
+-** whatever it does.  While this other process is holding the
+-** file open, we will be unable to delete it.  To work around this
+-** problem, we delay 100 milliseconds and try to delete again.  Up
+-** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
+-** up and returning an error.
++** All loads and stores begun before the barrier must complete before
++** any load or store begun after the barrier.
+ */
+-static int winDelete(
+-  sqlite3_vfs *pVfs,          /* Not used on win32 */
+-  const char *zFilename,      /* Name of file to delete */
+-  int syncDir                 /* Not used on win32 */
++static void winShmBarrier(
++  sqlite3_file *fd          /* Database holding the shared memory */
+ ){
+-  int cnt = 0;
+-  int rc;
+-  DWORD attr;
+-  DWORD lastErrno = 0;
+-  void *zConverted;
+-  UNUSED_PARAMETER(pVfs);
+-  UNUSED_PARAMETER(syncDir);
++  UNUSED_PARAMETER(fd);
++  /* MemoryBarrier(); // does not work -- do not know why not */
++  winShmEnterMutex();
++  winShmLeaveMutex();
++}
+ 
+-  SimulateIOError(return SQLITE_IOERR_DELETE);
+-  OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir));
++/*
++** This function is called to obtain a pointer to region iRegion of the
++** shared-memory associated with the database file fd. Shared-memory regions
++** are numbered starting from zero. Each shared-memory region is szRegion
++** bytes in size.
++**
++** If an error occurs, an error code is returned and *pp is set to NULL.
++**
++** Otherwise, if the isWrite parameter is 0 and the requested shared-memory
++** region has not been allocated (by any client, including one running in a
++** separate process), then *pp is set to NULL and SQLITE_OK returned. If
++** isWrite is non-zero and the requested shared-memory region has not yet
++** been allocated, it is allocated by this function.
++**
++** If the shared-memory region has already been allocated or is allocated by
++** this call as described above, then it is mapped into this processes
++** address space (if it is not already), *pp is set to point to the mapped
++** memory and SQLITE_OK returned.
++*/
++static int winShmMap(
++  sqlite3_file *fd,               /* Handle open on database file */
++  int iRegion,                    /* Region to retrieve */
++  int szRegion,                   /* Size of regions */
++  int isWrite,                    /* True to extend file if necessary */
++  void volatile **pp              /* OUT: Mapped memory */
++){
++  winFile *pDbFd = (winFile*)fd;
++  winShm *pShm = pDbFd->pShm;
++  winShmNode *pShmNode;
++  int rc = SQLITE_OK;
+ 
+-  zConverted = winConvertFromUtf8Filename(zFilename);
+-  if( zConverted==0 ){
+-    OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
+-    return SQLITE_IOERR_NOMEM;
++  if( !pShm ){
++    rc = winOpenSharedMemory(pDbFd);
++    if( rc!=SQLITE_OK ) return rc;
++    pShm = pDbFd->pShm;
+   }
+-  if( osIsNT() ){
+-    do {
+-#if SQLITE_OS_WINRT
+-      WIN32_FILE_ATTRIBUTE_DATA sAttrData;
+-      memset(&sAttrData, 0, sizeof(sAttrData));
+-      if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard,
+-                                  &sAttrData) ){
+-        attr = sAttrData.dwFileAttributes;
+-      }else{
+-        lastErrno = osGetLastError();
+-        if( lastErrno==ERROR_FILE_NOT_FOUND
+-         || lastErrno==ERROR_PATH_NOT_FOUND ){
+-          rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
+-        }else{
+-          rc = SQLITE_ERROR;
+-        }
+-        break;
++  pShmNode = pShm->pShmNode;
++
++  sqlite3_mutex_enter(pShmNode->mutex);
++  assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
++
++  if( pShmNode->nRegion<=iRegion ){
++    struct ShmRegion *apNew;           /* New aRegion[] array */
++    int nByte = (iRegion+1)*szRegion;  /* Minimum required file size */
++    sqlite3_int64 sz;                  /* Current size of wal-index file */
++
++    pShmNode->szRegion = szRegion;
++
++    /* The requested region is not mapped into this processes address space.
++    ** Check to see if it has been allocated (i.e. if the wal-index file is
++    ** large enough to contain the requested region).
++    */
++    rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz);
++    if( rc!=SQLITE_OK ){
++      rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
++                       "winShmMap1", pDbFd->zPath);
++      goto shmpage_out;
++    }
++
++    if( sz<nByte ){
++      /* The requested memory region does not exist. If isWrite is set to
++      ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned.
++      **
++      ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate
++      ** the requested memory region.
++      */
++      if( !isWrite ) goto shmpage_out;
++      rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte);
++      if( rc!=SQLITE_OK ){
++        rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(),
++                         "winShmMap2", pDbFd->zPath);
++        goto shmpage_out;
+       }
++    }
++
++    /* Map the requested memory region into this processes address space. */
++    apNew = (struct ShmRegion *)sqlite3_realloc64(
++        pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0])
++    );
++    if( !apNew ){
++      rc = SQLITE_IOERR_NOMEM;
++      goto shmpage_out;
++    }
++    pShmNode->aRegion = apNew;
++
++    while( pShmNode->nRegion<=iRegion ){
++      HANDLE hMap = NULL;         /* file-mapping handle */
++      void *pMap = 0;             /* Mapped memory region */
++
++#if SQLITE_OS_WINRT
++      hMap = osCreateFileMappingFromApp(pShmNode->hFile.h,
++          NULL, PAGE_READWRITE, nByte, NULL
++      );
++#elif defined(SQLITE_WIN32_HAS_WIDE)
++      hMap = osCreateFileMappingW(pShmNode->hFile.h,
++          NULL, PAGE_READWRITE, 0, nByte, NULL
++      );
++#elif defined(SQLITE_WIN32_HAS_ANSI)
++      hMap = osCreateFileMappingA(pShmNode->hFile.h,
++          NULL, PAGE_READWRITE, 0, nByte, NULL
++      );
++#endif
++      OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n",
++               osGetCurrentProcessId(), pShmNode->nRegion, nByte,
++               hMap ? "ok" : "failed"));
++      if( hMap ){
++        int iOffset = pShmNode->nRegion*szRegion;
++        int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
++#if SQLITE_OS_WINRT
++        pMap = osMapViewOfFileFromApp(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
++            iOffset - iOffsetShift, szRegion + iOffsetShift
++        );
+ #else
+-      attr = osGetFileAttributesW(zConverted);
++        pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ,
++            0, iOffset - iOffsetShift, szRegion + iOffsetShift
++        );
+ #endif
+-      if ( attr==INVALID_FILE_ATTRIBUTES ){
+-        lastErrno = osGetLastError();
+-        if( lastErrno==ERROR_FILE_NOT_FOUND
+-         || lastErrno==ERROR_PATH_NOT_FOUND ){
+-          rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
+-        }else{
+-          rc = SQLITE_ERROR;
+-        }
+-        break;
+-      }
+-      if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
+-        rc = SQLITE_ERROR; /* Files only. */
+-        break;
+-      }
+-      if ( osDeleteFileW(zConverted) ){
+-        rc = SQLITE_OK; /* Deleted OK. */
+-        break;
+-      }
+-      if ( !winRetryIoerr(&cnt, &lastErrno) ){
+-        rc = SQLITE_ERROR; /* No more retries. */
+-        break;
+-      }
+-    } while(1);
+-  }
+-#ifdef SQLITE_WIN32_HAS_ANSI
+-  else{
+-    do {
+-      attr = osGetFileAttributesA(zConverted);
+-      if ( attr==INVALID_FILE_ATTRIBUTES ){
+-        lastErrno = osGetLastError();
+-        if( lastErrno==ERROR_FILE_NOT_FOUND
+-         || lastErrno==ERROR_PATH_NOT_FOUND ){
+-          rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
+-        }else{
+-          rc = SQLITE_ERROR;
+-        }
+-        break;
+-      }
+-      if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
+-        rc = SQLITE_ERROR; /* Files only. */
+-        break;
+-      }
+-      if ( osDeleteFileA(zConverted) ){
+-        rc = SQLITE_OK; /* Deleted OK. */
+-        break;
++        OSTRACE(("SHM-MAP-MAP pid=%lu, region=%d, offset=%d, size=%d, rc=%s\n",
++                 osGetCurrentProcessId(), pShmNode->nRegion, iOffset,
++                 szRegion, pMap ? "ok" : "failed"));
+       }
+-      if ( !winRetryIoerr(&cnt, &lastErrno) ){
+-        rc = SQLITE_ERROR; /* No more retries. */
+-        break;
++      if( !pMap ){
++        pShmNode->lastErrno = osGetLastError();
++        rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno,
++                         "winShmMap3", pDbFd->zPath);
++        if( hMap ) osCloseHandle(hMap);
++        goto shmpage_out;
+       }
+-    } while(1);
++
++      pShmNode->aRegion[pShmNode->nRegion].pMap = pMap;
++      pShmNode->aRegion[pShmNode->nRegion].hMap = hMap;
++      pShmNode->nRegion++;
++    }
+   }
+-#endif
+-  if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
+-    rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename);
++
++shmpage_out:
++  if( pShmNode->nRegion>iRegion ){
++    int iOffset = iRegion*szRegion;
++    int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity;
++    char *p = (char *)pShmNode->aRegion[iRegion].pMap;
++    *pp = (void *)&p[iOffsetShift];
+   }else{
+-    winLogIoerr(cnt, __LINE__);
++    *pp = 0;
+   }
+-  sqlite3_free(zConverted);
+-  OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc)));
++  sqlite3_mutex_leave(pShmNode->mutex);
+   return rc;
+ }
+ 
++#else
++# define winShmMap     0
++# define winShmLock    0
++# define winShmBarrier 0
++# define winShmUnmap   0
++#endif /* #ifndef SQLITE_OMIT_WAL */
++
+ /*
+-** Check the existence and status of a file.
++** Cleans up the mapped region of the specified file, if any.
+ */
+-static int winAccess(
+-  sqlite3_vfs *pVfs,         /* Not used on win32 */
+-  const char *zFilename,     /* Name of file to check */
+-  int flags,                 /* Type of test to make on this file */
+-  int *pResOut               /* OUT: Result */
+-){
+-  DWORD attr;
+-  int rc = 0;
+-  DWORD lastErrno = 0;
+-  void *zConverted;
+-  UNUSED_PARAMETER(pVfs);
+-
+-  SimulateIOError( return SQLITE_IOERR_ACCESS; );
+-  OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n",
+-           zFilename, flags, pResOut));
+-
+-  zConverted = winConvertFromUtf8Filename(zFilename);
+-  if( zConverted==0 ){
+-    OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
+-    return SQLITE_IOERR_NOMEM;
+-  }
+-  if( osIsNT() ){
+-    int cnt = 0;
+-    WIN32_FILE_ATTRIBUTE_DATA sAttrData;
+-    memset(&sAttrData, 0, sizeof(sAttrData));
+-    while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
+-                             GetFileExInfoStandard,
+-                             &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){}
+-    if( rc ){
+-      /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file
+-      ** as if it does not exist.
+-      */
+-      if(    flags==SQLITE_ACCESS_EXISTS
+-          && sAttrData.nFileSizeHigh==0
+-          && sAttrData.nFileSizeLow==0 ){
+-        attr = INVALID_FILE_ATTRIBUTES;
+-      }else{
+-        attr = sAttrData.dwFileAttributes;
+-      }
+-    }else{
+-      winLogIoerr(cnt, __LINE__);
+-      if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){
+-        sqlite3_free(zConverted);
+-        return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess",
+-                           zFilename);
+-      }else{
+-        attr = INVALID_FILE_ATTRIBUTES;
+-      }
++#if SQLITE_MAX_MMAP_SIZE>0
++static int winUnmapfile(winFile *pFile){
++  assert( pFile!=0 );
++  OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, "
++           "mmapSize=%lld, mmapSizeActual=%lld, mmapSizeMax=%lld\n",
++           osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion,
++           pFile->mmapSize, pFile->mmapSizeActual, pFile->mmapSizeMax));
++  if( pFile->pMapRegion ){
++    if( !osUnmapViewOfFile(pFile->pMapRegion) ){
++      pFile->lastErrno = osGetLastError();
++      OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, "
++               "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile,
++               pFile->pMapRegion));
++      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
++                         "winUnmapfile1", pFile->zPath);
+     }
++    pFile->pMapRegion = 0;
++    pFile->mmapSize = 0;
++    pFile->mmapSizeActual = 0;
+   }
+-#ifdef SQLITE_WIN32_HAS_ANSI
+-  else{
+-    attr = osGetFileAttributesA((char*)zConverted);
+-  }
+-#endif
+-  sqlite3_free(zConverted);
+-  switch( flags ){
+-    case SQLITE_ACCESS_READ:
+-    case SQLITE_ACCESS_EXISTS:
+-      rc = attr!=INVALID_FILE_ATTRIBUTES;
+-      break;
+-    case SQLITE_ACCESS_READWRITE:
+-      rc = attr!=INVALID_FILE_ATTRIBUTES &&
+-             (attr & FILE_ATTRIBUTE_READONLY)==0;
+-      break;
+-    default:
+-      assert(!"Invalid flags argument");
++  if( pFile->hMap!=NULL ){
++    if( !osCloseHandle(pFile->hMap) ){
++      pFile->lastErrno = osGetLastError();
++      OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n",
++               osGetCurrentProcessId(), pFile, pFile->hMap));
++      return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno,
++                         "winUnmapfile2", pFile->zPath);
++    }
++    pFile->hMap = NULL;
+   }
+-  *pResOut = rc;
+-  OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
+-           zFilename, pResOut, *pResOut));
++  OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
++           osGetCurrentProcessId(), pFile));
+   return SQLITE_OK;
+ }
+ 
+ /*
+-** Returns non-zero if the specified path name starts with a drive letter
+-** followed by a colon character.
++** Memory map or remap the file opened by file-descriptor pFd (if the file
++** is already mapped, the existing mapping is replaced by the new). Or, if
++** there already exists a mapping for this file, and there are still
++** outstanding xFetch() references to it, this function is a no-op.
++**
++** If parameter nByte is non-negative, then it is the requested size of
++** the mapping to create. Otherwise, if nByte is less than zero, then the
++** requested size is the size of the file on disk. The actual size of the
++** created mapping is either the requested size or the value configured
++** using SQLITE_FCNTL_MMAP_SIZE, whichever is smaller.
++**
++** SQLITE_OK is returned if no error occurs (even if the mapping is not
++** recreated as a result of outstanding references) or an SQLite error
++** code otherwise.
+ */
+-static BOOL winIsDriveLetterAndColon(
+-  const char *zPathname
+-){
+-  return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' );
+-}
++static int winMapfile(winFile *pFd, sqlite3_int64 nByte){
++  sqlite3_int64 nMap = nByte;
++  int rc;
+ 
+-/*
+-** Returns non-zero if the specified path name should be used verbatim.  If
+-** non-zero is returned from this function, the calling function must simply
+-** use the provided path name verbatim -OR- resolve it into a full path name
+-** using the GetFullPathName Win32 API function (if available).
+-*/
+-static BOOL winIsVerbatimPathname(
+-  const char *zPathname
+-){
+-  /*
+-  ** If the path name starts with a forward slash or a backslash, it is either
+-  ** a legal UNC name, a volume relative path, or an absolute path name in the
+-  ** "Unix" format on Windows.  There is no easy way to differentiate between
+-  ** the final two cases; therefore, we return the safer return value of TRUE
+-  ** so that callers of this function will simply use it verbatim.
+-  */
+-  if ( winIsDirSep(zPathname[0]) ){
+-    return TRUE;
++  assert( nMap>=0 || pFd->nFetchOut==0 );
++  OSTRACE(("MAP-FILE pid=%lu, pFile=%p, size=%lld\n",
++           osGetCurrentProcessId(), pFd, nByte));
++
++  if( pFd->nFetchOut>0 ) return SQLITE_OK;
++
++  if( nMap<0 ){
++    rc = winFileSize((sqlite3_file*)pFd, &nMap);
++    if( rc ){
++      OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_IOERR_FSTAT\n",
++               osGetCurrentProcessId(), pFd));
++      return SQLITE_IOERR_FSTAT;
++    }
++  }
++  if( nMap>pFd->mmapSizeMax ){
++    nMap = pFd->mmapSizeMax;
+   }
++  nMap &= ~(sqlite3_int64)(winSysInfo.dwPageSize - 1);
+ 
+-  /*
+-  ** If the path name starts with a letter and a colon it is either a volume
+-  ** relative path or an absolute path.  Callers of this function must not
+-  ** attempt to treat it as a relative path name (i.e. they should simply use
+-  ** it verbatim).
+-  */
+-  if ( winIsDriveLetterAndColon(zPathname) ){
+-    return TRUE;
++  if( nMap==0 && pFd->mmapSize>0 ){
++    winUnmapfile(pFd);
++  }
++  if( nMap!=pFd->mmapSize ){
++    void *pNew = 0;
++    DWORD protect = PAGE_READONLY;
++    DWORD flags = FILE_MAP_READ;
++
++    winUnmapfile(pFd);
++    if( (pFd->ctrlFlags & WINFILE_RDONLY)==0 ){
++      protect = PAGE_READWRITE;
++      flags |= FILE_MAP_WRITE;
++    }
++#if SQLITE_OS_WINRT
++    pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL);
++#elif defined(SQLITE_WIN32_HAS_WIDE)
++    pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect,
++                                (DWORD)((nMap>>32) & 0xffffffff),
++                                (DWORD)(nMap & 0xffffffff), NULL);
++#elif defined(SQLITE_WIN32_HAS_ANSI)
++    pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect,
++                                (DWORD)((nMap>>32) & 0xffffffff),
++                                (DWORD)(nMap & 0xffffffff), NULL);
++#endif
++    if( pFd->hMap==NULL ){
++      pFd->lastErrno = osGetLastError();
++      rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
++                       "winMapfile1", pFd->zPath);
++      /* Log the error, but continue normal operation using xRead/xWrite */
++      OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=%s\n",
++               osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
++      return SQLITE_OK;
++    }
++    assert( (nMap % winSysInfo.dwPageSize)==0 );
++    assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff );
++#if SQLITE_OS_WINRT
++    pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap);
++#else
++    pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap);
++#endif
++    if( pNew==NULL ){
++      osCloseHandle(pFd->hMap);
++      pFd->hMap = NULL;
++      pFd->lastErrno = osGetLastError();
++      rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,
++                       "winMapfile2", pFd->zPath);
++      /* Log the error, but continue normal operation using xRead/xWrite */
++      OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=%s\n",
++               osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
++      return SQLITE_OK;
++    }
++    pFd->pMapRegion = pNew;
++    pFd->mmapSize = nMap;
++    pFd->mmapSizeActual = nMap;
+   }
+ 
+-  /*
+-  ** If we get to this point, the path name should almost certainly be a purely
+-  ** relative one (i.e. not a UNC name, not absolute, and not volume relative).
+-  */
+-  return FALSE;
++  OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n",
++           osGetCurrentProcessId(), pFd));
++  return SQLITE_OK;
+ }
++#endif /* SQLITE_MAX_MMAP_SIZE>0 */
+ 
+ /*
+-** Turn a relative pathname into a full pathname.  Write the full
+-** pathname into zOut[].  zOut[] will be at least pVfs->mxPathname
+-** bytes in size.
++** If possible, return a pointer to a mapping of file fd starting at offset
++** iOff. The mapping must be valid for at least nAmt bytes.
++**
++** If such a pointer can be obtained, store it in *pp and return SQLITE_OK.
++** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK.
++** Finally, if an error does occur, return an SQLite error code. The final
++** value of *pp is undefined in this case.
++**
++** If this function does return a pointer, the caller must eventually
++** release the reference by calling winUnfetch().
+ */
+-static int winFullPathname(
+-  sqlite3_vfs *pVfs,            /* Pointer to vfs object */
+-  const char *zRelative,        /* Possibly relative input path */
+-  int nFull,                    /* Size of output buffer in bytes */
+-  char *zFull                   /* Output buffer */
+-){
++static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
++#if SQLITE_MAX_MMAP_SIZE>0
++  winFile *pFd = (winFile*)fd;   /* The underlying database file */
++#endif
++  *pp = 0;
+ 
+-#if defined(__CYGWIN__)
+-  SimulateIOError( return SQLITE_ERROR );
+-  UNUSED_PARAMETER(nFull);
+-  assert( nFull>=pVfs->mxPathname );
+-  if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
+-    /*
+-    ** NOTE: We are dealing with a relative path name and the data
+-    **       directory has been set.  Therefore, use it as the basis
+-    **       for converting the relative path name to an absolute
+-    **       one by prepending the data directory and a slash.
+-    */
+-    char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
+-    if( !zOut ){
+-      return SQLITE_IOERR_NOMEM;
+-    }
+-    if( cygwin_conv_path(
+-            (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) |
+-            CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){
+-      sqlite3_free(zOut);
+-      return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
+-                         "winFullPathname1", zRelative);
+-    }else{
+-      char *zUtf8 = winConvertToUtf8Filename(zOut);
+-      if( !zUtf8 ){
+-        sqlite3_free(zOut);
+-        return SQLITE_IOERR_NOMEM;
++  OSTRACE(("FETCH pid=%lu, pFile=%p, offset=%lld, amount=%d, pp=%p\n",
++           osGetCurrentProcessId(), fd, iOff, nAmt, pp));
++
++#if SQLITE_MAX_MMAP_SIZE>0
++  if( pFd->mmapSizeMax>0 ){
++    if( pFd->pMapRegion==0 ){
++      int rc = winMapfile(pFd, -1);
++      if( rc!=SQLITE_OK ){
++        OSTRACE(("FETCH pid=%lu, pFile=%p, rc=%s\n",
++                 osGetCurrentProcessId(), pFd, sqlite3ErrName(rc)));
++        return rc;
+       }
+-      sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
+-                       sqlite3_data_directory, winGetDirSep(), zUtf8);
+-      sqlite3_free(zUtf8);
+-      sqlite3_free(zOut);
+-    }
+-  }else{
+-    char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
+-    if( !zOut ){
+-      return SQLITE_IOERR_NOMEM;
+     }
+-    if( cygwin_conv_path(
+-            (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A),
+-            zRelative, zOut, pVfs->mxPathname+1)<0 ){
+-      sqlite3_free(zOut);
+-      return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
+-                         "winFullPathname2", zRelative);
+-    }else{
+-      char *zUtf8 = winConvertToUtf8Filename(zOut);
+-      if( !zUtf8 ){
+-        sqlite3_free(zOut);
+-        return SQLITE_IOERR_NOMEM;
+-      }
+-      sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8);
+-      sqlite3_free(zUtf8);
+-      sqlite3_free(zOut);
++    if( pFd->mmapSize >= iOff+nAmt ){
++      *pp = &((u8 *)pFd->pMapRegion)[iOff];
++      pFd->nFetchOut++;
+     }
+   }
+-  return SQLITE_OK;
+ #endif
+ 
+-#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__)
+-  SimulateIOError( return SQLITE_ERROR );
+-  /* WinCE has no concept of a relative pathname, or so I am told. */
+-  /* WinRT has no way to convert a relative path to an absolute one. */
+-  if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
+-    /*
+-    ** NOTE: We are dealing with a relative path name and the data
+-    **       directory has been set.  Therefore, use it as the basis
+-    **       for converting the relative path name to an absolute
+-    **       one by prepending the data directory and a backslash.
+-    */
+-    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
+-                     sqlite3_data_directory, winGetDirSep(), zRelative);
++  OSTRACE(("FETCH pid=%lu, pFile=%p, pp=%p, *pp=%p, rc=SQLITE_OK\n",
++           osGetCurrentProcessId(), fd, pp, *pp));
++  return SQLITE_OK;
++}
++
++/*
++** If the third argument is non-NULL, then this function releases a
++** reference obtained by an earlier call to winFetch(). The second
++** argument passed to this function must be the same as the corresponding
++** argument that was passed to the winFetch() invocation.
++**
++** Or, if the third argument is NULL, then this function is being called
++** to inform the VFS layer that, according to POSIX, any existing mapping
++** may now be invalid and should be unmapped.
++*/
++static int winUnfetch(sqlite3_file *fd, i64 iOff, void *p){
++#if SQLITE_MAX_MMAP_SIZE>0
++  winFile *pFd = (winFile*)fd;   /* The underlying database file */
++
++  /* If p==0 (unmap the entire file) then there must be no outstanding
++  ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference),
++  ** then there must be at least one outstanding.  */
++  assert( (p==0)==(pFd->nFetchOut==0) );
++
++  /* If p!=0, it must match the iOff value. */
++  assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] );
++
++  OSTRACE(("UNFETCH pid=%lu, pFile=%p, offset=%lld, p=%p\n",
++           osGetCurrentProcessId(), pFd, iOff, p));
++
++  if( p ){
++    pFd->nFetchOut--;
+   }else{
+-    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative);
++    /* FIXME:  If Windows truly always prevents truncating or deleting a
++    ** file while a mapping is held, then the following winUnmapfile() call
++    ** is unnecessary can be omitted - potentially improving
++    ** performance.  */
++    winUnmapfile(pFd);
+   }
+-  return SQLITE_OK;
++
++  assert( pFd->nFetchOut>=0 );
+ #endif
+ 
+-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
+-  DWORD nByte;
+-  void *zConverted;
+-  char *zOut;
++  OSTRACE(("UNFETCH pid=%lu, pFile=%p, rc=SQLITE_OK\n",
++           osGetCurrentProcessId(), fd));
++  return SQLITE_OK;
++}
+ 
+-  /* If this path name begins with "/X:", where "X" is any alphabetic
+-  ** character, discard the initial "/" from the pathname.
+-  */
+-  if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){
+-    zRelative++;
+-  }
++/*
++** Here ends the implementation of all sqlite3_file methods.
++**
++********************** End sqlite3_file Methods *******************************
++******************************************************************************/
+ 
+-  /* It's odd to simulate an io-error here, but really this is just
+-  ** using the io-error infrastructure to test that SQLite handles this
+-  ** function failing. This function could fail if, for example, the
+-  ** current working directory has been unlinked.
+-  */
+-  SimulateIOError( return SQLITE_ERROR );
+-  if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
+-    /*
+-    ** NOTE: We are dealing with a relative path name and the data
+-    **       directory has been set.  Therefore, use it as the basis
+-    **       for converting the relative path name to an absolute
+-    **       one by prepending the data directory and a backslash.
+-    */
+-    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
+-                     sqlite3_data_directory, winGetDirSep(), zRelative);
+-    return SQLITE_OK;
+-  }
+-  zConverted = winConvertFromUtf8Filename(zRelative);
+-  if( zConverted==0 ){
+-    return SQLITE_IOERR_NOMEM;
+-  }
++/*
++** This vector defines all the methods that can operate on an
++** sqlite3_file for win32.
++*/
++static const sqlite3_io_methods winIoMethod = {
++  3,                              /* iVersion */
++  winClose,                       /* xClose */
++  winRead,                        /* xRead */
++  winWrite,                       /* xWrite */
++  winTruncate,                    /* xTruncate */
++  winSync,                        /* xSync */
++  winFileSize,                    /* xFileSize */
++  winLock,                        /* xLock */
++  winUnlock,                      /* xUnlock */
++  winCheckReservedLock,           /* xCheckReservedLock */
++  winFileControl,                 /* xFileControl */
++  winSectorSize,                  /* xSectorSize */
++  winDeviceCharacteristics,       /* xDeviceCharacteristics */
++  winShmMap,                      /* xShmMap */
++  winShmLock,                     /* xShmLock */
++  winShmBarrier,                  /* xShmBarrier */
++  winShmUnmap,                    /* xShmUnmap */
++  winFetch,                       /* xFetch */
++  winUnfetch                      /* xUnfetch */
++};
++
++/****************************************************************************
++**************************** sqlite3_vfs methods ****************************
++**
++** This division contains the implementation of methods on the
++** sqlite3_vfs object.
++*/
++
++#if defined(__CYGWIN__)
++/*
++** Convert a filename from whatever the underlying operating system
++** supports for filenames into UTF-8.  Space to hold the result is
++** obtained from malloc and must be freed by the calling function.
++*/
++static char *winConvertToUtf8Filename(const void *zFilename){
++  char *zConverted = 0;
+   if( osIsNT() ){
+-    LPWSTR zTemp;
+-    nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0);
+-    if( nByte==0 ){
+-      sqlite3_free(zConverted);
+-      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
+-                         "winFullPathname1", zRelative);
+-    }
+-    nByte += 3;
+-    zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
+-    if( zTemp==0 ){
+-      sqlite3_free(zConverted);
+-      return SQLITE_IOERR_NOMEM;
+-    }
+-    nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
+-    if( nByte==0 ){
+-      sqlite3_free(zConverted);
+-      sqlite3_free(zTemp);
+-      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
+-                         "winFullPathname2", zRelative);
+-    }
+-    sqlite3_free(zConverted);
+-    zOut = winUnicodeToUtf8(zTemp);
+-    sqlite3_free(zTemp);
++    zConverted = winUnicodeToUtf8(zFilename);
+   }
+ #ifdef SQLITE_WIN32_HAS_ANSI
+   else{
+-    char *zTemp;
+-    nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0);
+-    if( nByte==0 ){
+-      sqlite3_free(zConverted);
+-      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
+-                         "winFullPathname3", zRelative);
+-    }
+-    nByte += 3;
+-    zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
+-    if( zTemp==0 ){
+-      sqlite3_free(zConverted);
+-      return SQLITE_IOERR_NOMEM;
+-    }
+-    nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
+-    if( nByte==0 ){
+-      sqlite3_free(zConverted);
+-      sqlite3_free(zTemp);
+-      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
+-                         "winFullPathname4", zRelative);
+-    }
+-    sqlite3_free(zConverted);
+-    zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
+-    sqlite3_free(zTemp);
+-  }
+-#endif
+-  if( zOut ){
+-    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut);
+-    sqlite3_free(zOut);
+-    return SQLITE_OK;
+-  }else{
+-    return SQLITE_IOERR_NOMEM;
++    zConverted = sqlite3_win32_mbcs_to_utf8(zFilename);
+   }
+ #endif
++  /* caller will handle out of memory */
++  return zConverted;
+ }
++#endif
+ 
+-#ifndef SQLITE_OMIT_LOAD_EXTENSION
+ /*
+-** Interfaces for opening a shared library, finding entry points
+-** within the shared library, and closing the shared library.
++** Convert a UTF-8 filename into whatever form the underlying
++** operating system wants filenames in.  Space to hold the result
++** is obtained from malloc and must be freed by the calling
++** function.
+ */
+-static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
+-  HANDLE h;
+-#if defined(__CYGWIN__)
+-  int nFull = pVfs->mxPathname+1;
+-  char *zFull = sqlite3MallocZero( nFull );
++static void *winConvertFromUtf8Filename(const char *zFilename){
+   void *zConverted = 0;
+-  if( zFull==0 ){
+-    OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
+-    return 0;
+-  }
+-  if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){
+-    sqlite3_free(zFull);
+-    OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
+-    return 0;
+-  }
+-  zConverted = winConvertFromUtf8Filename(zFull);
+-  sqlite3_free(zFull);
+-#else
+-  void *zConverted = winConvertFromUtf8Filename(zFilename);
+-  UNUSED_PARAMETER(pVfs);
+-#endif
+-  if( zConverted==0 ){
+-    OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
+-    return 0;
+-  }
+   if( osIsNT() ){
+-#if SQLITE_OS_WINRT
+-    h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0);
+-#else
+-    h = osLoadLibraryW((LPCWSTR)zConverted);
+-#endif
++    zConverted = winUtf8ToUnicode(zFilename);
+   }
+ #ifdef SQLITE_WIN32_HAS_ANSI
+   else{
+-    h = osLoadLibraryA((char*)zConverted);
++    zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);
+   }
+ #endif
+-  OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)h));
+-  sqlite3_free(zConverted);
+-  return (void*)h;
+-}
+-static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
+-  UNUSED_PARAMETER(pVfs);
+-  winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut);
+-}
+-static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){
+-  FARPROC proc;
+-  UNUSED_PARAMETER(pVfs);
+-  proc = osGetProcAddressA((HANDLE)pH, zSym);
+-  OSTRACE(("DLSYM handle=%p, symbol=%s, address=%p\n",
+-           (void*)pH, zSym, (void*)proc));
+-  return (void(*)(void))proc;
+-}
+-static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
+-  UNUSED_PARAMETER(pVfs);
+-  osFreeLibrary((HANDLE)pHandle);
+-  OSTRACE(("DLCLOSE handle=%p\n", (void*)pHandle));
++  /* caller will handle out of memory */
++  return zConverted;
+ }
+-#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
+-  #define winDlOpen  0
+-  #define winDlError 0
+-  #define winDlSym   0
+-  #define winDlClose 0
+-#endif
+-
+ 
+ /*
+-** Write up to nBuf bytes of randomness into zBuf.
++** This function returns non-zero if the specified UTF-8 string buffer
++** ends with a directory separator character or one was successfully
++** added to it.
+ */
+-static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
+-  int n = 0;
+-  UNUSED_PARAMETER(pVfs);
+-#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS)
+-  n = nBuf;
+-  memset(zBuf, 0, nBuf);
+-#else
+-  if( sizeof(SYSTEMTIME)<=nBuf-n ){
+-    SYSTEMTIME x;
+-    osGetSystemTime(&x);
+-    memcpy(&zBuf[n], &x, sizeof(x));
+-    n += sizeof(x);
+-  }
+-  if( sizeof(DWORD)<=nBuf-n ){
+-    DWORD pid = osGetCurrentProcessId();
+-    memcpy(&zBuf[n], &pid, sizeof(pid));
+-    n += sizeof(pid);
++static int winMakeEndInDirSep(int nBuf, char *zBuf){
++  if( zBuf ){
++    int nLen = sqlite3Strlen30(zBuf);
++    if( nLen>0 ){
++      if( winIsDirSep(zBuf[nLen-1]) ){
++        return 1;
++      }else if( nLen+1<nBuf ){
++        zBuf[nLen] = winGetDirSep();
++        zBuf[nLen+1] = '\0';
++        return 1;
++      }
++    }
+   }
+-#if SQLITE_OS_WINRT
+-  if( sizeof(ULONGLONG)<=nBuf-n ){
+-    ULONGLONG cnt = osGetTickCount64();
+-    memcpy(&zBuf[n], &cnt, sizeof(cnt));
+-    n += sizeof(cnt);
++  return 0;
++}
++
++/*
++** Create a temporary file name and store the resulting pointer into pzBuf.
++** The pointer returned in pzBuf must be freed via sqlite3_free().
++*/
++static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){
++  static char zChars[] =
++    "abcdefghijklmnopqrstuvwxyz"
++    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
++    "0123456789";
++  size_t i, j;
++  int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX);
++  int nMax, nBuf, nDir, nLen;
++  char *zBuf;
++
++  /* It's odd to simulate an io-error here, but really this is just
++  ** using the io-error infrastructure to test that SQLite handles this
++  ** function failing.
++  */
++  SimulateIOError( return SQLITE_IOERR );
++
++  /* Allocate a temporary buffer to store the fully qualified file
++  ** name for the temporary file.  If this fails, we cannot continue.
++  */
++  nMax = pVfs->mxPathname; nBuf = nMax + 2;
++  zBuf = sqlite3MallocZero( nBuf );
++  if( !zBuf ){
++    OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
++    return SQLITE_IOERR_NOMEM;
+   }
+-#else
+-  if( sizeof(DWORD)<=nBuf-n ){
+-    DWORD cnt = osGetTickCount();
+-    memcpy(&zBuf[n], &cnt, sizeof(cnt));
+-    n += sizeof(cnt);
++
++  /* Figure out the effective temporary directory.  First, check if one
++  ** has been explicitly set by the application; otherwise, use the one
++  ** configured by the operating system.
++  */
++  nDir = nMax - (nPre + 15);
++  assert( nDir>0 );
++  if( sqlite3_temp_directory ){
++    int nDirLen = sqlite3Strlen30(sqlite3_temp_directory);
++    if( nDirLen>0 ){
++      if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){
++        nDirLen++;
++      }
++      if( nDirLen>nDir ){
++        sqlite3_free(zBuf);
++        OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
++        return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0);
++      }
++      sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory);
++    }
+   }
+-#endif
+-  if( sizeof(LARGE_INTEGER)<=nBuf-n ){
+-    LARGE_INTEGER i;
+-    osQueryPerformanceCounter(&i);
+-    memcpy(&zBuf[n], &i, sizeof(i));
+-    n += sizeof(i);
++#if defined(__CYGWIN__)
++  else{
++    static const char *azDirs[] = {
++       0, /* getenv("SQLITE_TMPDIR") */
++       0, /* getenv("TMPDIR") */
++       0, /* getenv("TMP") */
++       0, /* getenv("TEMP") */
++       0, /* getenv("USERPROFILE") */
++       "/var/tmp",
++       "/usr/tmp",
++       "/tmp",
++       ".",
++       0        /* List terminator */
++    };
++    unsigned int i;
++    const char *zDir = 0;
++
++    if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR");
++    if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
++    if( !azDirs[2] ) azDirs[2] = getenv("TMP");
++    if( !azDirs[3] ) azDirs[3] = getenv("TEMP");
++    if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE");
++    for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){
++      void *zConverted;
++      if( zDir==0 ) continue;
++      /* If the path starts with a drive letter followed by the colon
++      ** character, assume it is already a native Win32 path; otherwise,
++      ** it must be converted to a native Win32 path via the Cygwin API
++      ** prior to using it.
++      */
++      if( winIsDriveLetterAndColon(zDir) ){
++        zConverted = winConvertFromUtf8Filename(zDir);
++        if( !zConverted ){
++          sqlite3_free(zBuf);
++          OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
++          return SQLITE_IOERR_NOMEM;
++        }
++        if( winIsDir(zConverted) ){
++          sqlite3_snprintf(nMax, zBuf, "%s", zDir);
++          sqlite3_free(zConverted);
++          break;
++        }
++        sqlite3_free(zConverted);
++      }else{
++        zConverted = sqlite3MallocZero( nMax+1 );
++        if( !zConverted ){
++          sqlite3_free(zBuf);
++          OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
++          return SQLITE_IOERR_NOMEM;
++        }
++        if( cygwin_conv_path(
++                osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir,
++                zConverted, nMax+1)<0 ){
++          sqlite3_free(zConverted);
++          sqlite3_free(zBuf);
++          OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n"));
++          return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno,
++                             "winGetTempname2", zDir);
++        }
++        if( winIsDir(zConverted) ){
++          /* At this point, we know the candidate directory exists and should
++          ** be used.  However, we may need to convert the string containing
++          ** its name into UTF-8 (i.e. if it is UTF-16 right now).
++          */
++          char *zUtf8 = winConvertToUtf8Filename(zConverted);
++          if( !zUtf8 ){
++            sqlite3_free(zConverted);
++            sqlite3_free(zBuf);
++            OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
++            return SQLITE_IOERR_NOMEM;
++          }
++          sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
++          sqlite3_free(zUtf8);
++          sqlite3_free(zConverted);
++          break;
++        }
++        sqlite3_free(zConverted);
++      }
++    }
+   }
+-#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
+-  if( sizeof(UUID)<=nBuf-n ){
+-    UUID id;
+-    memset(&id, 0, sizeof(UUID));
+-    osUuidCreate(&id);
+-    memcpy(zBuf, &id, sizeof(UUID));
+-    n += sizeof(UUID);
++#elif !SQLITE_OS_WINRT && !defined(__CYGWIN__)
++  else if( osIsNT() ){
++    char *zMulti;
++    LPWSTR zWidePath = sqlite3MallocZero( nMax*sizeof(WCHAR) );
++    if( !zWidePath ){
++      sqlite3_free(zBuf);
++      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
++      return SQLITE_IOERR_NOMEM;
++    }
++    if( osGetTempPathW(nMax, zWidePath)==0 ){
++      sqlite3_free(zWidePath);
++      sqlite3_free(zBuf);
++      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
++      return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
++                         "winGetTempname2", 0);
++    }
++    zMulti = winUnicodeToUtf8(zWidePath);
++    if( zMulti ){
++      sqlite3_snprintf(nMax, zBuf, "%s", zMulti);
++      sqlite3_free(zMulti);
++      sqlite3_free(zWidePath);
++    }else{
++      sqlite3_free(zWidePath);
++      sqlite3_free(zBuf);
++      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
++      return SQLITE_IOERR_NOMEM;
++    }
+   }
+-  if( sizeof(UUID)<=nBuf-n ){
+-    UUID id;
+-    memset(&id, 0, sizeof(UUID));
+-    osUuidCreateSequential(&id);
+-    memcpy(zBuf, &id, sizeof(UUID));
+-    n += sizeof(UUID);
++#ifdef SQLITE_WIN32_HAS_ANSI
++  else{
++    char *zUtf8;
++    char *zMbcsPath = sqlite3MallocZero( nMax );
++    if( !zMbcsPath ){
++      sqlite3_free(zBuf);
++      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
++      return SQLITE_IOERR_NOMEM;
++    }
++    if( osGetTempPathA(nMax, zMbcsPath)==0 ){
++      sqlite3_free(zBuf);
++      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
++      return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(),
++                         "winGetTempname3", 0);
++    }
++    zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
++    if( zUtf8 ){
++      sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
++      sqlite3_free(zUtf8);
++    }else{
++      sqlite3_free(zBuf);
++      OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
++      return SQLITE_IOERR_NOMEM;
++    }
+   }
+-#endif
+-#endif /* defined(SQLITE_TEST) || defined(SQLITE_ZERO_PRNG_SEED) */
+-  return n;
+-}
+-
+-
+-/*
+-** Sleep for a little while.  Return the amount of time slept.
+-*/
+-static int winSleep(sqlite3_vfs *pVfs, int microsec){
+-  sqlite3_win32_sleep((microsec+999)/1000);
+-  UNUSED_PARAMETER(pVfs);
+-  return ((microsec+999)/1000)*1000;
+-}
+-
+-/*
+-** The following variable, if set to a non-zero value, is interpreted as
+-** the number of seconds since 1970 and is used to set the result of
+-** sqlite3OsCurrentTime() during testing.
+-*/
+-#ifdef SQLITE_TEST
+-SQLITE_API int sqlite3_current_time = 0;  /* Fake system time in seconds since 1970. */
+-#endif
++#endif /* SQLITE_WIN32_HAS_ANSI */
++#endif /* !SQLITE_OS_WINRT */
+ 
+-/*
+-** Find the current time (in Universal Coordinated Time).  Write into *piNow
+-** the current time and date as a Julian Day number times 86_400_000.  In
+-** other words, write into *piNow the number of milliseconds since the Julian
+-** epoch of noon in Greenwich on November 24, 4714 B.C according to the
+-** proleptic Gregorian calendar.
+-**
+-** On success, return SQLITE_OK.  Return SQLITE_ERROR if the time and date
+-** cannot be found.
+-*/
+-static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
+-  /* FILETIME structure is a 64-bit value representing the number of
+-     100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
++  /*
++  ** Check to make sure the temporary directory ends with an appropriate
++  ** separator.  If it does not and there is not enough space left to add
++  ** one, fail.
+   */
+-  FILETIME ft;
+-  static const sqlite3_int64 winFiletimeEpoch = 23058135*(sqlite3_int64)8640000;
+-#ifdef SQLITE_TEST
+-  static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
+-#endif
+-  /* 2^32 - to avoid use of LL and warnings in gcc */
+-  static const sqlite3_int64 max32BitValue =
+-      (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 +
+-      (sqlite3_int64)294967296;
++  if( !winMakeEndInDirSep(nDir+1, zBuf) ){
++    sqlite3_free(zBuf);
++    OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
++    return winLogError(SQLITE_ERROR, 0, "winGetTempname4", 0);
++  }
+ 
+-#if SQLITE_OS_WINCE
+-  SYSTEMTIME time;
+-  osGetSystemTime(&time);
+-  /* if SystemTimeToFileTime() fails, it returns zero. */
+-  if (!osSystemTimeToFileTime(&time,&ft)){
+-    return SQLITE_ERROR;
++  /*
++  ** Check that the output buffer is large enough for the temporary file
++  ** name in the following format:
++  **
++  **   "<temporary_directory>/etilqs_XXXXXXXXXXXXXXX\0\0"
++  **
++  ** If not, return SQLITE_ERROR.  The number 17 is used here in order to
++  ** account for the space used by the 15 character random suffix and the
++  ** two trailing NUL characters.  The final directory separator character
++  ** has already added if it was not already present.
++  */
++  nLen = sqlite3Strlen30(zBuf);
++  if( (nLen + nPre + 17) > nBuf ){
++    sqlite3_free(zBuf);
++    OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n"));
++    return winLogError(SQLITE_ERROR, 0, "winGetTempname5", 0);
+   }
+-#else
+-  osGetSystemTimeAsFileTime( &ft );
+-#endif
+ 
+-  *piNow = winFiletimeEpoch +
+-            ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) +
+-               (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000;
++  sqlite3_snprintf(nBuf-16-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX);
+ 
+-#ifdef SQLITE_TEST
+-  if( sqlite3_current_time ){
+-    *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
++  j = sqlite3Strlen30(zBuf);
++  sqlite3_randomness(15, &zBuf[j]);
++  for(i=0; i<15; i++, j++){
++    zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
+   }
+-#endif
+-  UNUSED_PARAMETER(pVfs);
++  zBuf[j] = 0;
++  zBuf[j+1] = 0;
++  *pzBuf = zBuf;
++
++  OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf));
+   return SQLITE_OK;
+ }
+ 
+ /*
+-** Find the current time (in Universal Coordinated Time).  Write the
+-** current time and date as a Julian Day number into *prNow and
+-** return 0.  Return 1 if the time and date cannot be found.
++** Return TRUE if the named file is really a directory.  Return false if
++** it is something other than a directory, or if there is any kind of memory
++** allocation failure.
+ */
+-static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
+-  int rc;
+-  sqlite3_int64 i;
+-  rc = winCurrentTimeInt64(pVfs, &i);
+-  if( !rc ){
+-    *prNow = i/86400000.0;
+-  }
+-  return rc;
+-}
++static int winIsDir(const void *zConverted){
++  DWORD attr;
++  int rc = 0;
++  DWORD lastErrno;
+ 
+-/*
+-** The idea is that this function works like a combination of
+-** GetLastError() and FormatMessage() on Windows (or errno and
+-** strerror_r() on Unix). After an error is returned by an OS
+-** function, SQLite calls this function with zBuf pointing to
+-** a buffer of nBuf bytes. The OS layer should populate the
+-** buffer with a nul-terminated UTF-8 encoded error message
+-** describing the last IO error to have occurred within the calling
+-** thread.
+-**
+-** If the error message is too large for the supplied buffer,
+-** it should be truncated. The return value of xGetLastError
+-** is zero if the error message fits in the buffer, or non-zero
+-** otherwise (if the message was truncated). If non-zero is returned,
+-** then it is not necessary to include the nul-terminator character
+-** in the output buffer.
+-**
+-** Not supplying an error message will have no adverse effect
+-** on SQLite. It is fine to have an implementation that never
+-** returns an error message:
+-**
+-**   int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
+-**     assert(zBuf[0]=='\0');
+-**     return 0;
+-**   }
+-**
+-** However if an error message is supplied, it will be incorporated
+-** by sqlite into the error message available to the user using
+-** sqlite3_errmsg(), possibly making IO errors easier to debug.
+-*/
+-static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
+-  UNUSED_PARAMETER(pVfs);
+-  return winGetLastErrorMsg(osGetLastError(), nBuf, zBuf);
++  if( osIsNT() ){
++    int cnt = 0;
++    WIN32_FILE_ATTRIBUTE_DATA sAttrData;
++    memset(&sAttrData, 0, sizeof(sAttrData));
++    while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
++                             GetFileExInfoStandard,
++                             &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){}
++    if( !rc ){
++      return 0; /* Invalid name? */
++    }
++    attr = sAttrData.dwFileAttributes;
++#if SQLITE_OS_WINCE==0
++  }else{
++    attr = osGetFileAttributesA((char*)zConverted);
++#endif
++  }
++  return (attr!=INVALID_FILE_ATTRIBUTES) && (attr&FILE_ATTRIBUTE_DIRECTORY);
+ }
+ 
+ /*
+-** Initialize and deinitialize the operating system interface.
++** Open a file.
+ */
+-SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){
+-  static sqlite3_vfs winVfs = {
+-    3,                   /* iVersion */
+-    sizeof(winFile),     /* szOsFile */
+-    SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */
+-    0,                   /* pNext */
+-    "win32",             /* zName */
+-    0,                   /* pAppData */
+-    winOpen,             /* xOpen */
+-    winDelete,           /* xDelete */
+-    winAccess,           /* xAccess */
+-    winFullPathname,     /* xFullPathname */
+-    winDlOpen,           /* xDlOpen */
+-    winDlError,          /* xDlError */
+-    winDlSym,            /* xDlSym */
+-    winDlClose,          /* xDlClose */
+-    winRandomness,       /* xRandomness */
+-    winSleep,            /* xSleep */
+-    winCurrentTime,      /* xCurrentTime */
+-    winGetLastError,     /* xGetLastError */
+-    winCurrentTimeInt64, /* xCurrentTimeInt64 */
+-    winSetSystemCall,    /* xSetSystemCall */
+-    winGetSystemCall,    /* xGetSystemCall */
+-    winNextSystemCall,   /* xNextSystemCall */
+-  };
+-#if defined(SQLITE_WIN32_HAS_WIDE)
+-  static sqlite3_vfs winLongPathVfs = {
+-    3,                   /* iVersion */
+-    sizeof(winFile),     /* szOsFile */
+-    SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */
+-    0,                   /* pNext */
+-    "win32-longpath",    /* zName */
+-    0,                   /* pAppData */
+-    winOpen,             /* xOpen */
+-    winDelete,           /* xDelete */
+-    winAccess,           /* xAccess */
+-    winFullPathname,     /* xFullPathname */
+-    winDlOpen,           /* xDlOpen */
+-    winDlError,          /* xDlError */
+-    winDlSym,            /* xDlSym */
+-    winDlClose,          /* xDlClose */
+-    winRandomness,       /* xRandomness */
+-    winSleep,            /* xSleep */
+-    winCurrentTime,      /* xCurrentTime */
+-    winGetLastError,     /* xGetLastError */
+-    winCurrentTimeInt64, /* xCurrentTimeInt64 */
+-    winSetSystemCall,    /* xSetSystemCall */
+-    winGetSystemCall,    /* xGetSystemCall */
+-    winNextSystemCall,   /* xNextSystemCall */
+-  };
++static int winOpen(
++  sqlite3_vfs *pVfs,        /* Used to get maximum path name length */
++  const char *zName,        /* Name of the file (UTF-8) */
++  sqlite3_file *id,         /* Write the SQLite file handle here */
++  int flags,                /* Open mode flags */
++  int *pOutFlags            /* Status return flags */
++){
++  HANDLE h;
++  DWORD lastErrno = 0;
++  DWORD dwDesiredAccess;
++  DWORD dwShareMode;
++  DWORD dwCreationDisposition;
++  DWORD dwFlagsAndAttributes = 0;
++#if SQLITE_OS_WINCE
++  int isTemp = 0;
+ #endif
++  winFile *pFile = (winFile*)id;
++  void *zConverted;              /* Filename in OS encoding */
++  const char *zUtf8Name = zName; /* Filename in UTF-8 encoding */
++  int cnt = 0;
+ 
+-  /* Double-check that the aSyscall[] array has been constructed
+-  ** correctly.  See ticket [bb3a86e890c8e96ab] */
+-  assert( ArraySize(aSyscall)==80 );
++  /* If argument zPath is a NULL pointer, this function is required to open
++  ** a temporary file. Use this buffer to store the file name in.
++  */
++  char *zTmpname = 0; /* For temporary filename, if necessary. */
+ 
+-  /* get memory map allocation granularity */
+-  memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
+-#if SQLITE_OS_WINRT
+-  osGetNativeSystemInfo(&winSysInfo);
+-#else
+-  osGetSystemInfo(&winSysInfo);
++  int rc = SQLITE_OK;            /* Function Return Code */
++#if !defined(NDEBUG) || SQLITE_OS_WINCE
++  int eType = flags&0xFFFFFF00;  /* Type of file to open */
+ #endif
+-  assert( winSysInfo.dwAllocationGranularity>0 );
+-  assert( winSysInfo.dwPageSize>0 );
+ 
+-  sqlite3_vfs_register(&winVfs, 1);
++  int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);
++  int isDelete     = (flags & SQLITE_OPEN_DELETEONCLOSE);
++  int isCreate     = (flags & SQLITE_OPEN_CREATE);
++  int isReadonly   = (flags & SQLITE_OPEN_READONLY);
++  int isReadWrite  = (flags & SQLITE_OPEN_READWRITE);
+ 
+-#if defined(SQLITE_WIN32_HAS_WIDE)
+-  sqlite3_vfs_register(&winLongPathVfs, 0);
++#ifndef NDEBUG
++  int isOpenJournal = (isCreate && (
++        eType==SQLITE_OPEN_MASTER_JOURNAL
++     || eType==SQLITE_OPEN_MAIN_JOURNAL
++     || eType==SQLITE_OPEN_WAL
++  ));
+ #endif
+ 
+-  return SQLITE_OK;
+-}
++  OSTRACE(("OPEN name=%s, pFile=%p, flags=%x, pOutFlags=%p\n",
++           zUtf8Name, id, flags, pOutFlags));
++
++  /* Check the following statements are true:
++  **
++  **   (a) Exactly one of the READWRITE and READONLY flags must be set, and
++  **   (b) if CREATE is set, then READWRITE must also be set, and
++  **   (c) if EXCLUSIVE is set, then CREATE must also be set.
++  **   (d) if DELETEONCLOSE is set, then CREATE must also be set.
++  */
++  assert((isReadonly==0 || isReadWrite==0) && (isReadWrite || isReadonly));
++  assert(isCreate==0 || isReadWrite);
++  assert(isExclusive==0 || isCreate);
++  assert(isDelete==0 || isCreate);
++
++  /* The main DB, main journal, WAL file and master journal are never
++  ** automatically deleted. Nor are they ever temporary files.  */
++  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB );
++  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL );
++  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL );
++  assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL );
++
++  /* Assert that the upper layer has set one of the "file-type" flags. */
++  assert( eType==SQLITE_OPEN_MAIN_DB      || eType==SQLITE_OPEN_TEMP_DB
++       || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL
++       || eType==SQLITE_OPEN_SUBJOURNAL   || eType==SQLITE_OPEN_MASTER_JOURNAL
++       || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
++  );
++
++  assert( pFile!=0 );
++  memset(pFile, 0, sizeof(winFile));
++  pFile->h = INVALID_HANDLE_VALUE;
+ 
+-SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void){
+ #if SQLITE_OS_WINRT
+-  if( sleepObj!=NULL ){
+-    osCloseHandle(sleepObj);
+-    sleepObj = NULL;
++  if( !zUtf8Name && !sqlite3_temp_directory ){
++    sqlite3_log(SQLITE_ERROR,
++        "sqlite3_temp_directory variable should be set for WinRT");
+   }
+ #endif
+-  return SQLITE_OK;
+-}
+-
+-#endif /* SQLITE_OS_WIN */
+-
+-/************** End of os_win.c **********************************************/
+-/************** Begin file bitvec.c ******************************************/
+-/*
+-** 2008 February 16
+-**
+-** The author disclaims copyright to this source code.  In place of
+-** a legal notice, here is a blessing:
+-**
+-**    May you do good and not evil.
+-**    May you find forgiveness for yourself and forgive others.
+-**    May you share freely, never taking more than you give.
+-**
+-*************************************************************************
+-** This file implements an object that represents a fixed-length
+-** bitmap.  Bits are numbered starting with 1.
+-**
+-** A bitmap is used to record which pages of a database file have been
+-** journalled during a transaction, or which pages have the "dont-write"
+-** property.  Usually only a few pages are meet either condition.
+-** So the bitmap is usually sparse and has low cardinality.
+-** But sometimes (for example when during a DROP of a large table) most
+-** or all of the pages in a database can get journalled.  In those cases, 
+-** the bitmap becomes dense with high cardinality.  The algorithm needs 
+-** to handle both cases well.
+-**
+-** The size of the bitmap is fixed when the object is created.
+-**
+-** All bits are clear when the bitmap is created.  Individual bits
+-** may be set or cleared one at a time.
+-**
+-** Test operations are about 100 times more common that set operations.
+-** Clear operations are exceedingly rare.  There are usually between
+-** 5 and 500 set operations per Bitvec object, though the number of sets can
+-** sometimes grow into tens of thousands or larger.  The size of the
+-** Bitvec object is the number of pages in the database file at the
+-** start of a transaction, and is thus usually less than a few thousand,
+-** but can be as large as 2 billion for a really big database.
+-*/
+ 
+-/* Size of the Bitvec structure in bytes. */
+-#define BITVEC_SZ        512
++  /* If the second argument to this function is NULL, generate a
++  ** temporary file name to use
++  */
++  if( !zUtf8Name ){
++    assert( isDelete && !isOpenJournal );
++    rc = winGetTempname(pVfs, &zTmpname);
++    if( rc!=SQLITE_OK ){
++      OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc)));
++      return rc;
++    }
++    zUtf8Name = zTmpname;
++  }
+ 
+-/* Round the union size down to the nearest pointer boundary, since that's how 
+-** it will be aligned within the Bitvec struct. */
+-#define BITVEC_USIZE     (((BITVEC_SZ-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*))
++  /* Database filenames are double-zero terminated if they are not
++  ** URIs with parameters.  Hence, they can always be passed into
++  ** sqlite3_uri_parameter().
++  */
++  assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) ||
++       zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 );
+ 
+-/* Type of the array "element" for the bitmap representation. 
+-** Should be a power of 2, and ideally, evenly divide into BITVEC_USIZE. 
+-** Setting this to the "natural word" size of your CPU may improve
+-** performance. */
+-#define BITVEC_TELEM     u8
+-/* Size, in bits, of the bitmap element. */
+-#define BITVEC_SZELEM    8
+-/* Number of elements in a bitmap array. */
+-#define BITVEC_NELEM     (BITVEC_USIZE/sizeof(BITVEC_TELEM))
+-/* Number of bits in the bitmap array. */
+-#define BITVEC_NBIT      (BITVEC_NELEM*BITVEC_SZELEM)
++  /* Convert the filename to the system encoding. */
++  zConverted = winConvertFromUtf8Filename(zUtf8Name);
++  if( zConverted==0 ){
++    sqlite3_free(zTmpname);
++    OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name));
++    return SQLITE_IOERR_NOMEM;
++  }
+ 
+-/* Number of u32 values in hash table. */
+-#define BITVEC_NINT      (BITVEC_USIZE/sizeof(u32))
+-/* Maximum number of entries in hash table before 
+-** sub-dividing and re-hashing. */
+-#define BITVEC_MXHASH    (BITVEC_NINT/2)
+-/* Hashing function for the aHash representation.
+-** Empirical testing showed that the *37 multiplier 
+-** (an arbitrary prime)in the hash function provided 
+-** no fewer collisions than the no-op *1. */
+-#define BITVEC_HASH(X)   (((X)*1)%BITVEC_NINT)
++  if( winIsDir(zConverted) ){
++    sqlite3_free(zConverted);
++    sqlite3_free(zTmpname);
++    OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name));
++    return SQLITE_CANTOPEN_ISDIR;
++  }
+ 
+-#define BITVEC_NPTR      (BITVEC_USIZE/sizeof(Bitvec *))
++  if( isReadWrite ){
++    dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
++  }else{
++    dwDesiredAccess = GENERIC_READ;
++  }
+ 
++  /* SQLITE_OPEN_EXCLUSIVE is used to make sure that a new file is
++  ** created. SQLite doesn't use it to indicate "exclusive access"
++  ** as it is usually understood.
++  */
++  if( isExclusive ){
++    /* Creates a new file, only if it does not already exist. */
++    /* If the file exists, it fails. */
++    dwCreationDisposition = CREATE_NEW;
++  }else if( isCreate ){
++    /* Open existing file, or create if it doesn't exist */
++    dwCreationDisposition = OPEN_ALWAYS;
++  }else{
++    /* Opens a file, only if it exists. */
++    dwCreationDisposition = OPEN_EXISTING;
++  }
+ 
+-/*
+-** A bitmap is an instance of the following structure.
+-**
+-** This bitmap records the existence of zero or more bits
+-** with values between 1 and iSize, inclusive.
+-**
+-** There are three possible representations of the bitmap.
+-** If iSize<=BITVEC_NBIT, then Bitvec.u.aBitmap[] is a straight
+-** bitmap.  The least significant bit is bit 1.
+-**
+-** If iSize>BITVEC_NBIT and iDivisor==0 then Bitvec.u.aHash[] is
+-** a hash table that will hold up to BITVEC_MXHASH distinct values.
+-**
+-** Otherwise, the value i is redirected into one of BITVEC_NPTR
+-** sub-bitmaps pointed to by Bitvec.u.apSub[].  Each subbitmap
+-** handles up to iDivisor separate values of i.  apSub[0] holds
+-** values between 1 and iDivisor.  apSub[1] holds values between
+-** iDivisor+1 and 2*iDivisor.  apSub[N] holds values between
+-** N*iDivisor+1 and (N+1)*iDivisor.  Each subbitmap is normalized
+-** to hold deal with values between 1 and iDivisor.
+-*/
+-struct Bitvec {
+-  u32 iSize;      /* Maximum bit index.  Max iSize is 4,294,967,296. */
+-  u32 nSet;       /* Number of bits that are set - only valid for aHash
+-                  ** element.  Max is BITVEC_NINT.  For BITVEC_SZ of 512,
+-                  ** this would be 125. */
+-  u32 iDivisor;   /* Number of bits handled by each apSub[] entry. */
+-                  /* Should >=0 for apSub element. */
+-                  /* Max iDivisor is max(u32) / BITVEC_NPTR + 1.  */
+-                  /* For a BITVEC_SZ of 512, this would be 34,359,739. */
+-  union {
+-    BITVEC_TELEM aBitmap[BITVEC_NELEM];    /* Bitmap representation */
+-    u32 aHash[BITVEC_NINT];      /* Hash table representation */
+-    Bitvec *apSub[BITVEC_NPTR];  /* Recursive representation */
+-  } u;
+-};
++  dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
+ 
+-/*
+-** Create a new bitmap object able to handle bits between 0 and iSize,
+-** inclusive.  Return a pointer to the new object.  Return NULL if 
+-** malloc fails.
+-*/
+-SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32 iSize){
+-  Bitvec *p;
+-  assert( sizeof(*p)==BITVEC_SZ );
+-  p = sqlite3MallocZero( sizeof(*p) );
+-  if( p ){
+-    p->iSize = iSize;
++  if( isDelete ){
++#if SQLITE_OS_WINCE
++    dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN;
++    isTemp = 1;
++#else
++    dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY
++                               | FILE_ATTRIBUTE_HIDDEN
++                               | FILE_FLAG_DELETE_ON_CLOSE;
++#endif
++  }else{
++    dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
+   }
+-  return p;
+-}
++  /* Reports from the internet are that performance is always
++  ** better if FILE_FLAG_RANDOM_ACCESS is used.  Ticket #2699. */
++#if SQLITE_OS_WINCE
++  dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS;
++#endif
+ 
+-/*
+-** Check to see if the i-th bit is set.  Return true or false.
+-** If p is NULL (if the bitmap has not been created) or if
+-** i is out of range, then return false.
+-*/
+-SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec *p, u32 i){
+-  if( p==0 ) return 0;
+-  if( i>p->iSize || i==0 ) return 0;
+-  i--;
+-  while( p->iDivisor ){
+-    u32 bin = i/p->iDivisor;
+-    i = i%p->iDivisor;
+-    p = p->u.apSub[bin];
+-    if (!p) {
+-      return 0;
++  if( osIsNT() ){
++#if SQLITE_OS_WINRT
++    CREATEFILE2_EXTENDED_PARAMETERS extendedParameters;
++    extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
++    extendedParameters.dwFileAttributes =
++            dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK;
++    extendedParameters.dwFileFlags = dwFlagsAndAttributes & FILE_FLAG_MASK;
++    extendedParameters.dwSecurityQosFlags = SECURITY_ANONYMOUS;
++    extendedParameters.lpSecurityAttributes = NULL;
++    extendedParameters.hTemplateFile = NULL;
++    while( (h = osCreateFile2((LPCWSTR)zConverted,
++                              dwDesiredAccess,
++                              dwShareMode,
++                              dwCreationDisposition,
++                              &extendedParameters))==INVALID_HANDLE_VALUE &&
++                              winRetryIoerr(&cnt, &lastErrno) ){
++               /* Noop */
+     }
+-  }
+-  if( p->iSize<=BITVEC_NBIT ){
+-    return (p->u.aBitmap[i/BITVEC_SZELEM] & (1<<(i&(BITVEC_SZELEM-1))))!=0;
+-  } else{
+-    u32 h = BITVEC_HASH(i++);
+-    while( p->u.aHash[h] ){
+-      if( p->u.aHash[h]==i ) return 1;
+-      h = (h+1) % BITVEC_NINT;
++#else
++    while( (h = osCreateFileW((LPCWSTR)zConverted,
++                              dwDesiredAccess,
++                              dwShareMode, NULL,
++                              dwCreationDisposition,
++                              dwFlagsAndAttributes,
++                              NULL))==INVALID_HANDLE_VALUE &&
++                              winRetryIoerr(&cnt, &lastErrno) ){
++               /* Noop */
+     }
+-    return 0;
++#endif
+   }
+-}
+-
+-/*
+-** Set the i-th bit.  Return 0 on success and an error code if
+-** anything goes wrong.
+-**
+-** This routine might cause sub-bitmaps to be allocated.  Failing
+-** to get the memory needed to hold the sub-bitmap is the only
+-** that can go wrong with an insert, assuming p and i are valid.
+-**
+-** The calling function must ensure that p is a valid Bitvec object
+-** and that the value for "i" is within range of the Bitvec object.
+-** Otherwise the behavior is undefined.
+-*/
+-SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec *p, u32 i){
+-  u32 h;
+-  if( p==0 ) return SQLITE_OK;
+-  assert( i>0 );
+-  assert( i<=p->iSize );
+-  i--;
+-  while((p->iSize > BITVEC_NBIT) && p->iDivisor) {
+-    u32 bin = i/p->iDivisor;
+-    i = i%p->iDivisor;
+-    if( p->u.apSub[bin]==0 ){
+-      p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor );
+-      if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM;
++#ifdef SQLITE_WIN32_HAS_ANSI
++  else{
++    while( (h = osCreateFileA((LPCSTR)zConverted,
++                              dwDesiredAccess,
++                              dwShareMode, NULL,
++                              dwCreationDisposition,
++                              dwFlagsAndAttributes,
++                              NULL))==INVALID_HANDLE_VALUE &&
++                              winRetryIoerr(&cnt, &lastErrno) ){
++               /* Noop */
+     }
+-    p = p->u.apSub[bin];
+   }
+-  if( p->iSize<=BITVEC_NBIT ){
+-    p->u.aBitmap[i/BITVEC_SZELEM] |= 1 << (i&(BITVEC_SZELEM-1));
+-    return SQLITE_OK;
+-  }
+-  h = BITVEC_HASH(i++);
+-  /* if there wasn't a hash collision, and this doesn't */
+-  /* completely fill the hash, then just add it without */
+-  /* worring about sub-dividing and re-hashing. */
+-  if( !p->u.aHash[h] ){
+-    if (p->nSet<(BITVEC_NINT-1)) {
+-      goto bitvec_set_end;
+-    } else {
+-      goto bitvec_set_rehash;
++#endif
++  winLogIoerr(cnt, __LINE__);
++
++  OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name,
++           dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));
++
++  if( h==INVALID_HANDLE_VALUE ){
++    pFile->lastErrno = lastErrno;
++    winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name);
++    sqlite3_free(zConverted);
++    sqlite3_free(zTmpname);
++    if( isReadWrite && !isExclusive ){
++      return winOpen(pVfs, zName, id,
++         ((flags|SQLITE_OPEN_READONLY) &
++                     ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
++         pOutFlags);
++    }else{
++      return SQLITE_CANTOPEN_BKPT;
+     }
+   }
+-  /* there was a collision, check to see if it's already */
+-  /* in hash, if not, try to find a spot for it */
+-  do {
+-    if( p->u.aHash[h]==i ) return SQLITE_OK;
+-    h++;
+-    if( h>=BITVEC_NINT ) h = 0;
+-  } while( p->u.aHash[h] );
+-  /* we didn't find it in the hash.  h points to the first */
+-  /* available free spot. check to see if this is going to */
+-  /* make our hash too "full".  */
+-bitvec_set_rehash:
+-  if( p->nSet>=BITVEC_MXHASH ){
+-    unsigned int j;
+-    int rc;
+-    u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash));
+-    if( aiValues==0 ){
+-      return SQLITE_NOMEM;
++
++  if( pOutFlags ){
++    if( isReadWrite ){
++      *pOutFlags = SQLITE_OPEN_READWRITE;
+     }else{
+-      memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
+-      memset(p->u.apSub, 0, sizeof(p->u.apSub));
+-      p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR;
+-      rc = sqlite3BitvecSet(p, i);
+-      for(j=0; j<BITVEC_NINT; j++){
+-        if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]);
+-      }
+-      sqlite3StackFree(0, aiValues);
+-      return rc;
++      *pOutFlags = SQLITE_OPEN_READONLY;
+     }
+   }
+-bitvec_set_end:
+-  p->nSet++;
+-  p->u.aHash[h] = i;
+-  return SQLITE_OK;
+-}
+ 
+-/*
+-** Clear the i-th bit.
+-**
+-** pBuf must be a pointer to at least BITVEC_SZ bytes of temporary storage
+-** that BitvecClear can use to rebuilt its hash table.
+-*/
+-SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec *p, u32 i, void *pBuf){
+-  if( p==0 ) return;
+-  assert( i>0 );
+-  i--;
+-  while( p->iDivisor ){
+-    u32 bin = i/p->iDivisor;
+-    i = i%p->iDivisor;
+-    p = p->u.apSub[bin];
+-    if (!p) {
+-      return;
+-    }
++  OSTRACE(("OPEN file=%p, name=%s, access=%lx, pOutFlags=%p, *pOutFlags=%d, "
++           "rc=%s\n", h, zUtf8Name, dwDesiredAccess, pOutFlags, pOutFlags ?
++           *pOutFlags : 0, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok"));
++
++#if SQLITE_OS_WINCE
++  if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
++       && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK
++  ){
++    osCloseHandle(h);
++    sqlite3_free(zConverted);
++    sqlite3_free(zTmpname);
++    OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc)));
++    return rc;
+   }
+-  if( p->iSize<=BITVEC_NBIT ){
+-    p->u.aBitmap[i/BITVEC_SZELEM] &= ~(1 << (i&(BITVEC_SZELEM-1)));
+-  }else{
+-    unsigned int j;
+-    u32 *aiValues = pBuf;
+-    memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
+-    memset(p->u.aHash, 0, sizeof(p->u.aHash));
+-    p->nSet = 0;
+-    for(j=0; j<BITVEC_NINT; j++){
+-      if( aiValues[j] && aiValues[j]!=(i+1) ){
+-        u32 h = BITVEC_HASH(aiValues[j]-1);
+-        p->nSet++;
+-        while( p->u.aHash[h] ){
+-          h++;
+-          if( h>=BITVEC_NINT ) h = 0;
+-        }
+-        p->u.aHash[h] = aiValues[j];
+-      }
+-    }
++  if( isTemp ){
++    pFile->zDeleteOnClose = zConverted;
++  }else
++#endif
++  {
++    sqlite3_free(zConverted);
+   }
+-}
+ 
+-/*
+-** Destroy a bitmap object.  Reclaim all memory used.
+-*/
+-SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec *p){
+-  if( p==0 ) return;
+-  if( p->iDivisor ){
+-    unsigned int i;
+-    for(i=0; i<BITVEC_NPTR; i++){
+-      sqlite3BitvecDestroy(p->u.apSub[i]);
+-    }
++  sqlite3_free(zTmpname);
++  pFile->pMethod = &winIoMethod;
++  pFile->pVfs = pVfs;
++  pFile->h = h;
++  if( isReadonly ){
++    pFile->ctrlFlags |= WINFILE_RDONLY;
+   }
+-  sqlite3_free(p);
+-}
++  if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
++    pFile->ctrlFlags |= WINFILE_PSOW;
++  }
++  pFile->lastErrno = NO_ERROR;
++  pFile->zPath = zName;
++#if SQLITE_MAX_MMAP_SIZE>0
++  pFile->hMap = NULL;
++  pFile->pMapRegion = 0;
++  pFile->mmapSize = 0;
++  pFile->mmapSizeActual = 0;
++  pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap;
++#endif
+ 
+-/*
+-** Return the value of the iSize parameter specified when Bitvec *p
+-** was created.
+-*/
+-SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){
+-  return p->iSize;
++  OpenCounter(+1);
++  return rc;
+ }
+ 
+-#ifndef SQLITE_OMIT_BUILTIN_TEST
+-/*
+-** Let V[] be an array of unsigned characters sufficient to hold
+-** up to N bits.  Let I be an integer between 0 and N.  0<=I<N.
+-** Then the following macros can be used to set, clear, or test
+-** individual bits within V.
+-*/
+-#define SETBIT(V,I)      V[I>>3] |= (1<<(I&7))
+-#define CLEARBIT(V,I)    V[I>>3] &= ~(1<<(I&7))
+-#define TESTBIT(V,I)     (V[I>>3]&(1<<(I&7)))!=0
+-
+ /*
+-** This routine runs an extensive test of the Bitvec code.
+-**
+-** The input is an array of integers that acts as a program
+-** to test the Bitvec.  The integers are opcodes followed
+-** by 0, 1, or 3 operands, depending on the opcode.  Another
+-** opcode follows immediately after the last operand.
+-**
+-** There are 6 opcodes numbered from 0 through 5.  0 is the
+-** "halt" opcode and causes the test to end.
+-**
+-**    0          Halt and return the number of errors
+-**    1 N S X    Set N bits beginning with S and incrementing by X
+-**    2 N S X    Clear N bits beginning with S and incrementing by X
+-**    3 N        Set N randomly chosen bits
+-**    4 N        Clear N randomly chosen bits
+-**    5 N S X    Set N bits from S increment X in array only, not in bitvec
+-**
+-** The opcodes 1 through 4 perform set and clear operations are performed
+-** on both a Bitvec object and on a linear array of bits obtained from malloc.
+-** Opcode 5 works on the linear array only, not on the Bitvec.
+-** Opcode 5 is used to deliberately induce a fault in order to
+-** confirm that error detection works.
+-**
+-** At the conclusion of the test the linear array is compared
+-** against the Bitvec object.  If there are any differences,
+-** an error is returned.  If they are the same, zero is returned.
++** Delete the named file.
+ **
+-** If a memory allocation error occurs, return -1.
++** Note that Windows does not allow a file to be deleted if some other
++** process has it open.  Sometimes a virus scanner or indexing program
++** will open a journal file shortly after it is created in order to do
++** whatever it does.  While this other process is holding the
++** file open, we will be unable to delete it.  To work around this
++** problem, we delay 100 milliseconds and try to delete again.  Up
++** to MX_DELETION_ATTEMPTs deletion attempts are run before giving
++** up and returning an error.
+ */
+-SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){
+-  Bitvec *pBitvec = 0;
+-  unsigned char *pV = 0;
+-  int rc = -1;
+-  int i, nx, pc, op;
+-  void *pTmpSpace;
+-
+-  /* Allocate the Bitvec to be tested and a linear array of
+-  ** bits to act as the reference */
+-  pBitvec = sqlite3BitvecCreate( sz );
+-  pV = sqlite3MallocZero( (sz+7)/8 + 1 );
+-  pTmpSpace = sqlite3_malloc64(BITVEC_SZ);
+-  if( pBitvec==0 || pV==0 || pTmpSpace==0  ) goto bitvec_end;
++static int winDelete(
++  sqlite3_vfs *pVfs,          /* Not used on win32 */
++  const char *zFilename,      /* Name of file to delete */
++  int syncDir                 /* Not used on win32 */
++){
++  int cnt = 0;
++  int rc;
++  DWORD attr;
++  DWORD lastErrno = 0;
++  void *zConverted;
++  UNUSED_PARAMETER(pVfs);
++  UNUSED_PARAMETER(syncDir);
+ 
+-  /* NULL pBitvec tests */
+-  sqlite3BitvecSet(0, 1);
+-  sqlite3BitvecClear(0, 1, pTmpSpace);
++  SimulateIOError(return SQLITE_IOERR_DELETE);
++  OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir));
+ 
+-  /* Run the program */
+-  pc = 0;
+-  while( (op = aOp[pc])!=0 ){
+-    switch( op ){
+-      case 1:
+-      case 2:
+-      case 5: {
+-        nx = 4;
+-        i = aOp[pc+2] - 1;
+-        aOp[pc+2] += aOp[pc+3];
++  zConverted = winConvertFromUtf8Filename(zFilename);
++  if( zConverted==0 ){
++    OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
++    return SQLITE_IOERR_NOMEM;
++  }
++  if( osIsNT() ){
++    do {
++#if SQLITE_OS_WINRT
++      WIN32_FILE_ATTRIBUTE_DATA sAttrData;
++      memset(&sAttrData, 0, sizeof(sAttrData));
++      if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard,
++                                  &sAttrData) ){
++        attr = sAttrData.dwFileAttributes;
++      }else{
++        lastErrno = osGetLastError();
++        if( lastErrno==ERROR_FILE_NOT_FOUND
++         || lastErrno==ERROR_PATH_NOT_FOUND ){
++          rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
++        }else{
++          rc = SQLITE_ERROR;
++        }
+         break;
+       }
+-      case 3:
+-      case 4: 
+-      default: {
+-        nx = 2;
+-        sqlite3_randomness(sizeof(i), &i);
++#else
++      attr = osGetFileAttributesW(zConverted);
++#endif
++      if ( attr==INVALID_FILE_ATTRIBUTES ){
++        lastErrno = osGetLastError();
++        if( lastErrno==ERROR_FILE_NOT_FOUND
++         || lastErrno==ERROR_PATH_NOT_FOUND ){
++          rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
++        }else{
++          rc = SQLITE_ERROR;
++        }
+         break;
+       }
+-    }
+-    if( (--aOp[pc+1]) > 0 ) nx = 0;
+-    pc += nx;
+-    i = (i & 0x7fffffff)%sz;
+-    if( (op & 1)!=0 ){
+-      SETBIT(pV, (i+1));
+-      if( op!=5 ){
+-        if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end;
++      if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
++        rc = SQLITE_ERROR; /* Files only. */
++        break;
+       }
+-    }else{
+-      CLEARBIT(pV, (i+1));
+-      sqlite3BitvecClear(pBitvec, i+1, pTmpSpace);
+-    }
++      if ( osDeleteFileW(zConverted) ){
++        rc = SQLITE_OK; /* Deleted OK. */
++        break;
++      }
++      if ( !winRetryIoerr(&cnt, &lastErrno) ){
++        rc = SQLITE_ERROR; /* No more retries. */
++        break;
++      }
++    } while(1);
++  }
++#ifdef SQLITE_WIN32_HAS_ANSI
++  else{
++    do {
++      attr = osGetFileAttributesA(zConverted);
++      if ( attr==INVALID_FILE_ATTRIBUTES ){
++        lastErrno = osGetLastError();
++        if( lastErrno==ERROR_FILE_NOT_FOUND
++         || lastErrno==ERROR_PATH_NOT_FOUND ){
++          rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
++        }else{
++          rc = SQLITE_ERROR;
++        }
++        break;
++      }
++      if ( attr&FILE_ATTRIBUTE_DIRECTORY ){
++        rc = SQLITE_ERROR; /* Files only. */
++        break;
++      }
++      if ( osDeleteFileA(zConverted) ){
++        rc = SQLITE_OK; /* Deleted OK. */
++        break;
++      }
++      if ( !winRetryIoerr(&cnt, &lastErrno) ){
++        rc = SQLITE_ERROR; /* No more retries. */
++        break;
++      }
++    } while(1);
+   }
+-
+-  /* Test to make sure the linear array exactly matches the
+-  ** Bitvec object.  Start with the assumption that they do
+-  ** match (rc==0).  Change rc to non-zero if a discrepancy
+-  ** is found.
+-  */
+-  rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1)
+-          + sqlite3BitvecTest(pBitvec, 0)
+-          + (sqlite3BitvecSize(pBitvec) - sz);
+-  for(i=1; i<=sz; i++){
+-    if(  (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){
+-      rc = i;
+-      break;
+-    }
++#endif
++  if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){
++    rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename);
++  }else{
++    winLogIoerr(cnt, __LINE__);
+   }
+-
+-  /* Free allocated structure */
+-bitvec_end:
+-  sqlite3_free(pTmpSpace);
+-  sqlite3_free(pV);
+-  sqlite3BitvecDestroy(pBitvec);
++  sqlite3_free(zConverted);
++  OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc)));
+   return rc;
+ }
+-#endif /* SQLITE_OMIT_BUILTIN_TEST */
+-
+-/************** End of bitvec.c **********************************************/
+-/************** Begin file pcache.c ******************************************/
+-/*
+-** 2008 August 05
+-**
+-** The author disclaims copyright to this source code.  In place of
+-** a legal notice, here is a blessing:
+-**
+-**    May you do good and not evil.
+-**    May you find forgiveness for yourself and forgive others.
+-**    May you share freely, never taking more than you give.
+-**
+-*************************************************************************
+-** This file implements that page cache.
+-*/
+ 
+ /*
+-** A complete page cache is an instance of this structure.
++** Check the existence and status of a file.
+ */
+-struct PCache {
+-  PgHdr *pDirty, *pDirtyTail;         /* List of dirty pages in LRU order */
+-  PgHdr *pSynced;                     /* Last synced page in dirty page list */
+-  int nRef;                           /* Number of referenced pages */
+-  int szCache;                        /* Configured cache size */
+-  int szPage;                         /* Size of every page in this cache */
+-  int szExtra;                        /* Size of extra space for each page */
+-  u8 bPurgeable;                      /* True if pages are on backing store */
+-  u8 eCreate;                         /* eCreate value for for xFetch() */
+-  int (*xStress)(void*,PgHdr*);       /* Call to try make a page clean */
+-  void *pStress;                      /* Argument to xStress */
+-  sqlite3_pcache *pCache;             /* Pluggable cache module */
+-  PgHdr *pPage1;                      /* Reference to page 1 */
+-};
+-
+-/********************************** Linked List Management ********************/
+-
+-/* Allowed values for second argument to pcacheManageDirtyList() */
+-#define PCACHE_DIRTYLIST_REMOVE   1    /* Remove pPage from dirty list */
+-#define PCACHE_DIRTYLIST_ADD      2    /* Add pPage to the dirty list */
+-#define PCACHE_DIRTYLIST_FRONT    3    /* Move pPage to the front of the list */
++static int winAccess(
++  sqlite3_vfs *pVfs,         /* Not used on win32 */
++  const char *zFilename,     /* Name of file to check */
++  int flags,                 /* Type of test to make on this file */
++  int *pResOut               /* OUT: Result */
++){
++  DWORD attr;
++  int rc = 0;
++  DWORD lastErrno = 0;
++  void *zConverted;
++  UNUSED_PARAMETER(pVfs);
+ 
+-/*
+-** Manage pPage's participation on the dirty list.  Bits of the addRemove
+-** argument determines what operation to do.  The 0x01 bit means first
+-** remove pPage from the dirty list.  The 0x02 means add pPage back to
+-** the dirty list.  Doing both moves pPage to the front of the dirty list.
+-*/
+-static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){
+-  PCache *p = pPage->pCache;
++  SimulateIOError( return SQLITE_IOERR_ACCESS; );
++  OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n",
++           zFilename, flags, pResOut));
+ 
+-  if( addRemove & PCACHE_DIRTYLIST_REMOVE ){
+-    assert( pPage->pDirtyNext || pPage==p->pDirtyTail );
+-    assert( pPage->pDirtyPrev || pPage==p->pDirty );
+-  
+-    /* Update the PCache1.pSynced variable if necessary. */
+-    if( p->pSynced==pPage ){
+-      PgHdr *pSynced = pPage->pDirtyPrev;
+-      while( pSynced && (pSynced->flags&PGHDR_NEED_SYNC) ){
+-        pSynced = pSynced->pDirtyPrev;
+-      }
+-      p->pSynced = pSynced;
+-    }
+-  
+-    if( pPage->pDirtyNext ){
+-      pPage->pDirtyNext->pDirtyPrev = pPage->pDirtyPrev;
+-    }else{
+-      assert( pPage==p->pDirtyTail );
+-      p->pDirtyTail = pPage->pDirtyPrev;
+-    }
+-    if( pPage->pDirtyPrev ){
+-      pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext;
+-    }else{
+-      assert( pPage==p->pDirty );
+-      p->pDirty = pPage->pDirtyNext;
+-      if( p->pDirty==0 && p->bPurgeable ){
+-        assert( p->eCreate==1 );
+-        p->eCreate = 2;
+-      }
+-    }
+-    pPage->pDirtyNext = 0;
+-    pPage->pDirtyPrev = 0;
++  zConverted = winConvertFromUtf8Filename(zFilename);
++  if( zConverted==0 ){
++    OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename));
++    return SQLITE_IOERR_NOMEM;
+   }
+-  if( addRemove & PCACHE_DIRTYLIST_ADD ){
+-    assert( pPage->pDirtyNext==0 && pPage->pDirtyPrev==0 && p->pDirty!=pPage );
+-  
+-    pPage->pDirtyNext = p->pDirty;
+-    if( pPage->pDirtyNext ){
+-      assert( pPage->pDirtyNext->pDirtyPrev==0 );
+-      pPage->pDirtyNext->pDirtyPrev = pPage;
++  if( osIsNT() ){
++    int cnt = 0;
++    WIN32_FILE_ATTRIBUTE_DATA sAttrData;
++    memset(&sAttrData, 0, sizeof(sAttrData));
++    while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted,
++                             GetFileExInfoStandard,
++                             &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){}
++    if( rc ){
++      /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file
++      ** as if it does not exist.
++      */
++      if(    flags==SQLITE_ACCESS_EXISTS
++          && sAttrData.nFileSizeHigh==0
++          && sAttrData.nFileSizeLow==0 ){
++        attr = INVALID_FILE_ATTRIBUTES;
++      }else{
++        attr = sAttrData.dwFileAttributes;
++      }
+     }else{
+-      p->pDirtyTail = pPage;
+-      if( p->bPurgeable ){
+-        assert( p->eCreate==2 );
+-        p->eCreate = 1;
++      winLogIoerr(cnt, __LINE__);
++      if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){
++        sqlite3_free(zConverted);
++        return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess",
++                           zFilename);
++      }else{
++        attr = INVALID_FILE_ATTRIBUTES;
+       }
+     }
+-    p->pDirty = pPage;
+-    if( !p->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) ){
+-      p->pSynced = pPage;
+-    }
+-  }
+-}
+-
+-/*
+-** Wrapper around the pluggable caches xUnpin method. If the cache is
+-** being used for an in-memory database, this function is a no-op.
+-*/
+-static void pcacheUnpin(PgHdr *p){
+-  if( p->pCache->bPurgeable ){
+-    if( p->pgno==1 ){
+-      p->pCache->pPage1 = 0;
+-    }
+-    sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0);
+-  }
+-}
+-
+-/*
+-** Compute the number of pages of cache requested.  p->szCache is the
+-** cache size requested by the "PRAGMA cache_size" statement.
+-**
+-**
+-*/
+-static int numberOfCachePages(PCache *p){
+-  if( p->szCache>=0 ){
+-    /* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the
+-    ** suggested cache size is set to N. */
+-    return p->szCache;
+-  }else{
+-    /* IMPLEMENTATION-OF: R-61436-13639 If the argument N is negative, then
+-    ** the number of cache pages is adjusted to use approximately abs(N*1024)
+-    ** bytes of memory. */
+-    return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
+   }
+-}
+-
+-/*************************************************** General Interfaces ******
+-**
+-** Initialize and shutdown the page cache subsystem. Neither of these 
+-** functions are threadsafe.
+-*/
+-SQLITE_PRIVATE int sqlite3PcacheInitialize(void){
+-  if( sqlite3GlobalConfig.pcache2.xInit==0 ){
+-    /* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the
+-    ** built-in default page cache is used instead of the application defined
+-    ** page cache. */
+-    sqlite3PCacheSetDefault();
++#ifdef SQLITE_WIN32_HAS_ANSI
++  else{
++    attr = osGetFileAttributesA((char*)zConverted);
+   }
+-  return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg);
+-}
+-SQLITE_PRIVATE void sqlite3PcacheShutdown(void){
+-  if( sqlite3GlobalConfig.pcache2.xShutdown ){
+-    /* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */
+-    sqlite3GlobalConfig.pcache2.xShutdown(sqlite3GlobalConfig.pcache2.pArg);
++#endif
++  sqlite3_free(zConverted);
++  switch( flags ){
++    case SQLITE_ACCESS_READ:
++    case SQLITE_ACCESS_EXISTS:
++      rc = attr!=INVALID_FILE_ATTRIBUTES;
++      break;
++    case SQLITE_ACCESS_READWRITE:
++      rc = attr!=INVALID_FILE_ATTRIBUTES &&
++             (attr & FILE_ATTRIBUTE_READONLY)==0;
++      break;
++    default:
++      assert(!"Invalid flags argument");
+   }
++  *pResOut = rc;
++  OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n",
++           zFilename, pResOut, *pResOut));
++  return SQLITE_OK;
+ }
+ 
+ /*
+-** Return the size in bytes of a PCache object.
+-*/
+-SQLITE_PRIVATE int sqlite3PcacheSize(void){ return sizeof(PCache); }
+-
+-/*
+-** Create a new PCache object. Storage space to hold the object
+-** has already been allocated and is passed in as the p pointer. 
+-** The caller discovers how much space needs to be allocated by 
+-** calling sqlite3PcacheSize().
++** Returns non-zero if the specified path name starts with a drive letter
++** followed by a colon character.
+ */
+-SQLITE_PRIVATE int sqlite3PcacheOpen(
+-  int szPage,                  /* Size of every page */
+-  int szExtra,                 /* Extra space associated with each page */
+-  int bPurgeable,              /* True if pages are on backing store */
+-  int (*xStress)(void*,PgHdr*),/* Call to try to make pages clean */
+-  void *pStress,               /* Argument to xStress */
+-  PCache *p                    /* Preallocated space for the PCache */
++static BOOL winIsDriveLetterAndColon(
++  const char *zPathname
+ ){
+-  memset(p, 0, sizeof(PCache));
+-  p->szPage = 1;
+-  p->szExtra = szExtra;
+-  p->bPurgeable = bPurgeable;
+-  p->eCreate = 2;
+-  p->xStress = xStress;
+-  p->pStress = pStress;
+-  p->szCache = 100;
+-  return sqlite3PcacheSetPageSize(p, szPage);
+-}
+-
+-/*
+-** Change the page size for PCache object. The caller must ensure that there
+-** are no outstanding page references when this function is called.
+-*/
+-SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
+-  assert( pCache->nRef==0 && pCache->pDirty==0 );
+-  if( pCache->szPage ){
+-    sqlite3_pcache *pNew;
+-    pNew = sqlite3GlobalConfig.pcache2.xCreate(
+-                szPage, pCache->szExtra + ROUND8(sizeof(PgHdr)),
+-                pCache->bPurgeable
+-    );
+-    if( pNew==0 ) return SQLITE_NOMEM;
+-    sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache));
+-    if( pCache->pCache ){
+-      sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
+-    }
+-    pCache->pCache = pNew;
+-    pCache->pPage1 = 0;
+-    pCache->szPage = szPage;
+-  }
+-  return SQLITE_OK;
++  return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' );
+ }
+ 
+ /*
+-** Try to obtain a page from the cache.
+-**
+-** This routine returns a pointer to an sqlite3_pcache_page object if
+-** such an object is already in cache, or if a new one is created.
+-** This routine returns a NULL pointer if the object was not in cache
+-** and could not be created.
+-**
+-** The createFlags should be 0 to check for existing pages and should
+-** be 3 (not 1, but 3) to try to create a new page.
+-**
+-** If the createFlag is 0, then NULL is always returned if the page
+-** is not already in the cache.  If createFlag is 1, then a new page
+-** is created only if that can be done without spilling dirty pages
+-** and without exceeding the cache size limit.
+-**
+-** The caller needs to invoke sqlite3PcacheFetchFinish() to properly
+-** initialize the sqlite3_pcache_page object and convert it into a
+-** PgHdr object.  The sqlite3PcacheFetch() and sqlite3PcacheFetchFinish()
+-** routines are split this way for performance reasons. When separated
+-** they can both (usually) operate without having to push values to
+-** the stack on entry and pop them back off on exit, which saves a
+-** lot of pushing and popping.
++** Returns non-zero if the specified path name should be used verbatim.  If
++** non-zero is returned from this function, the calling function must simply
++** use the provided path name verbatim -OR- resolve it into a full path name
++** using the GetFullPathName Win32 API function (if available).
+ */
+-SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch(
+-  PCache *pCache,       /* Obtain the page from this cache */
+-  Pgno pgno,            /* Page number to obtain */
+-  int createFlag        /* If true, create page if it does not exist already */
++static BOOL winIsVerbatimPathname(
++  const char *zPathname
+ ){
+-  int eCreate;
++  /*
++  ** If the path name starts with a forward slash or a backslash, it is either
++  ** a legal UNC name, a volume relative path, or an absolute path name in the
++  ** "Unix" format on Windows.  There is no easy way to differentiate between
++  ** the final two cases; therefore, we return the safer return value of TRUE
++  ** so that callers of this function will simply use it verbatim.
++  */
++  if ( winIsDirSep(zPathname[0]) ){
++    return TRUE;
++  }
+ 
+-  assert( pCache!=0 );
+-  assert( pCache->pCache!=0 );
+-  assert( createFlag==3 || createFlag==0 );
+-  assert( pgno>0 );
++  /*
++  ** If the path name starts with a letter and a colon it is either a volume
++  ** relative path or an absolute path.  Callers of this function must not
++  ** attempt to treat it as a relative path name (i.e. they should simply use
++  ** it verbatim).
++  */
++  if ( winIsDriveLetterAndColon(zPathname) ){
++    return TRUE;
++  }
+ 
+-  /* eCreate defines what to do if the page does not exist.
+-  **    0     Do not allocate a new page.  (createFlag==0)
+-  **    1     Allocate a new page if doing so is inexpensive.
+-  **          (createFlag==1 AND bPurgeable AND pDirty)
+-  **    2     Allocate a new page even it doing so is difficult.
+-  **          (createFlag==1 AND !(bPurgeable AND pDirty)
++  /*
++  ** If we get to this point, the path name should almost certainly be a purely
++  ** relative one (i.e. not a UNC name, not absolute, and not volume relative).
+   */
+-  eCreate = createFlag & pCache->eCreate;
+-  assert( eCreate==0 || eCreate==1 || eCreate==2 );
+-  assert( createFlag==0 || pCache->eCreate==eCreate );
+-  assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) );
+-  return sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
++  return FALSE;
+ }
+ 
+ /*
+-** If the sqlite3PcacheFetch() routine is unable to allocate a new
+-** page because new clean pages are available for reuse and the cache
+-** size limit has been reached, then this routine can be invoked to 
+-** try harder to allocate a page.  This routine might invoke the stress
+-** callback to spill dirty pages to the journal.  It will then try to
+-** allocate the new page and will only fail to allocate a new page on
+-** an OOM error.
+-**
+-** This routine should be invoked only after sqlite3PcacheFetch() fails.
++** Turn a relative pathname into a full pathname.  Write the full
++** pathname into zOut[].  zOut[] will be at least pVfs->mxPathname
++** bytes in size.
+ */
+-SQLITE_PRIVATE int sqlite3PcacheFetchStress(
+-  PCache *pCache,                 /* Obtain the page from this cache */
+-  Pgno pgno,                      /* Page number to obtain */
+-  sqlite3_pcache_page **ppPage    /* Write result here */
++static int winFullPathname(
++  sqlite3_vfs *pVfs,            /* Pointer to vfs object */
++  const char *zRelative,        /* Possibly relative input path */
++  int nFull,                    /* Size of output buffer in bytes */
++  char *zFull                   /* Output buffer */
+ ){
+-  PgHdr *pPg;
+-  if( pCache->eCreate==2 ) return 0;
+ 
+-
+-  /* Find a dirty page to write-out and recycle. First try to find a 
+-  ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC
+-  ** cleared), but if that is not possible settle for any other 
+-  ** unreferenced dirty page.
+-  */
+-  for(pPg=pCache->pSynced; 
+-      pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); 
+-      pPg=pPg->pDirtyPrev
+-  );
+-  pCache->pSynced = pPg;
+-  if( !pPg ){
+-    for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev);
+-  }
+-  if( pPg ){
+-    int rc;
+-#ifdef SQLITE_LOG_CACHE_SPILL
+-    sqlite3_log(SQLITE_FULL, 
+-                "spill page %d making room for %d - cache used: %d/%d",
+-                pPg->pgno, pgno,
+-                sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache),
+-                numberOfCachePages(pCache));
+-#endif
+-    rc = pCache->xStress(pCache->pStress, pPg);
+-    if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
+-      return rc;
++#if defined(__CYGWIN__)
++  SimulateIOError( return SQLITE_ERROR );
++  UNUSED_PARAMETER(nFull);
++  assert( nFull>=pVfs->mxPathname );
++  if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
++    /*
++    ** NOTE: We are dealing with a relative path name and the data
++    **       directory has been set.  Therefore, use it as the basis
++    **       for converting the relative path name to an absolute
++    **       one by prepending the data directory and a slash.
++    */
++    char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
++    if( !zOut ){
++      return SQLITE_IOERR_NOMEM;
++    }
++    if( cygwin_conv_path(
++            (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) |
++            CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){
++      sqlite3_free(zOut);
++      return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
++                         "winFullPathname1", zRelative);
++    }else{
++      char *zUtf8 = winConvertToUtf8Filename(zOut);
++      if( !zUtf8 ){
++        sqlite3_free(zOut);
++        return SQLITE_IOERR_NOMEM;
++      }
++      sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
++                       sqlite3_data_directory, winGetDirSep(), zUtf8);
++      sqlite3_free(zUtf8);
++      sqlite3_free(zOut);
++    }
++  }else{
++    char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
++    if( !zOut ){
++      return SQLITE_IOERR_NOMEM;
++    }
++    if( cygwin_conv_path(
++            (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A),
++            zRelative, zOut, pVfs->mxPathname+1)<0 ){
++      sqlite3_free(zOut);
++      return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
++                         "winFullPathname2", zRelative);
++    }else{
++      char *zUtf8 = winConvertToUtf8Filename(zOut);
++      if( !zUtf8 ){
++        sqlite3_free(zOut);
++        return SQLITE_IOERR_NOMEM;
++      }
++      sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8);
++      sqlite3_free(zUtf8);
++      sqlite3_free(zOut);
+     }
+   }
+-  *ppPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2);
+-  return *ppPage==0 ? SQLITE_NOMEM : SQLITE_OK;
+-}
++  return SQLITE_OK;
++#endif
+ 
+-/*
+-** This is a helper routine for sqlite3PcacheFetchFinish()
+-**
+-** In the uncommon case where the page being fetched has not been
+-** initialized, this routine is invoked to do the initialization.
+-** This routine is broken out into a separate function since it
+-** requires extra stack manipulation that can be avoided in the common
+-** case.
+-*/
+-static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit(
+-  PCache *pCache,             /* Obtain the page from this cache */
+-  Pgno pgno,                  /* Page number obtained */
+-  sqlite3_pcache_page *pPage  /* Page obtained by prior PcacheFetch() call */
+-){
+-  PgHdr *pPgHdr;
+-  assert( pPage!=0 );
+-  pPgHdr = (PgHdr*)pPage->pExtra;
+-  assert( pPgHdr->pPage==0 );
+- memset(pPgHdr, 0, sizeof(PgHdr));
+-  pPgHdr->pPage = pPage;
+-  pPgHdr->pData = pPage->pBuf;
+-  pPgHdr->pExtra = (void *)&pPgHdr[1];
+-  memset(pPgHdr->pExtra, 0, pCache->szExtra);
+-  pPgHdr->pCache = pCache;
+-  pPgHdr->pgno = pgno;
+-  return sqlite3PcacheFetchFinish(pCache,pgno,pPage);
+-}
++#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__)
++  SimulateIOError( return SQLITE_ERROR );
++  /* WinCE has no concept of a relative pathname, or so I am told. */
++  /* WinRT has no way to convert a relative path to an absolute one. */
++  if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
++    /*
++    ** NOTE: We are dealing with a relative path name and the data
++    **       directory has been set.  Therefore, use it as the basis
++    **       for converting the relative path name to an absolute
++    **       one by prepending the data directory and a backslash.
++    */
++    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
++                     sqlite3_data_directory, winGetDirSep(), zRelative);
++  }else{
++    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative);
++  }
++  return SQLITE_OK;
++#endif
+ 
+-/*
+-** This routine converts the sqlite3_pcache_page object returned by
+-** sqlite3PcacheFetch() into an initialized PgHdr object.  This routine
+-** must be called after sqlite3PcacheFetch() in order to get a usable
+-** result.
+-*/
+-SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish(
+-  PCache *pCache,             /* Obtain the page from this cache */
+-  Pgno pgno,                  /* Page number obtained */
+-  sqlite3_pcache_page *pPage  /* Page obtained by prior PcacheFetch() call */
+-){
+-  PgHdr *pPgHdr;
++#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(__CYGWIN__)
++  DWORD nByte;
++  void *zConverted;
++  char *zOut;
+ 
+-  if( pPage==0 ) return 0;
+-  pPgHdr = (PgHdr *)pPage->pExtra;
++  /* If this path name begins with "/X:", where "X" is any alphabetic
++  ** character, discard the initial "/" from the pathname.
++  */
++  if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){
++    zRelative++;
++  }
+ 
+-  if( !pPgHdr->pPage ){
+-    return pcacheFetchFinishWithInit(pCache, pgno, pPage);
++  /* It's odd to simulate an io-error here, but really this is just
++  ** using the io-error infrastructure to test that SQLite handles this
++  ** function failing. This function could fail if, for example, the
++  ** current working directory has been unlinked.
++  */
++  SimulateIOError( return SQLITE_ERROR );
++  if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
++    /*
++    ** NOTE: We are dealing with a relative path name and the data
++    **       directory has been set.  Therefore, use it as the basis
++    **       for converting the relative path name to an absolute
++    **       one by prepending the data directory and a backslash.
++    */
++    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
++                     sqlite3_data_directory, winGetDirSep(), zRelative);
++    return SQLITE_OK;
+   }
+-  if( 0==pPgHdr->nRef ){
+-    pCache->nRef++;
++  zConverted = winConvertFromUtf8Filename(zRelative);
++  if( zConverted==0 ){
++    return SQLITE_IOERR_NOMEM;
+   }
+-  pPgHdr->nRef++;
+-  if( pgno==1 ){
+-    pCache->pPage1 = pPgHdr;
++  if( osIsNT() ){
++    LPWSTR zTemp;
++    nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0);
++    if( nByte==0 ){
++      sqlite3_free(zConverted);
++      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
++                         "winFullPathname1", zRelative);
++    }
++    nByte += 3;
++    zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
++    if( zTemp==0 ){
++      sqlite3_free(zConverted);
++      return SQLITE_IOERR_NOMEM;
++    }
++    nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0);
++    if( nByte==0 ){
++      sqlite3_free(zConverted);
++      sqlite3_free(zTemp);
++      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
++                         "winFullPathname2", zRelative);
++    }
++    sqlite3_free(zConverted);
++    zOut = winUnicodeToUtf8(zTemp);
++    sqlite3_free(zTemp);
+   }
+-  return pPgHdr;
+-}
+-
+-/*
+-** Decrement the reference count on a page. If the page is clean and the
+-** reference count drops to 0, then it is made eligible for recycling.
+-*/
+-SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){
+-  assert( p->nRef>0 );
+-  p->nRef--;
+-  if( p->nRef==0 ){
+-    p->pCache->nRef--;
+-    if( (p->flags&PGHDR_DIRTY)==0 ){
+-      pcacheUnpin(p);
+-    }else if( p->pDirtyPrev!=0 ){
+-      /* Move the page to the head of the dirty list. */
+-      pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
++#ifdef SQLITE_WIN32_HAS_ANSI
++  else{
++    char *zTemp;
++    nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0);
++    if( nByte==0 ){
++      sqlite3_free(zConverted);
++      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
++                         "winFullPathname3", zRelative);
++    }
++    nByte += 3;
++    zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) );
++    if( zTemp==0 ){
++      sqlite3_free(zConverted);
++      return SQLITE_IOERR_NOMEM;
++    }
++    nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0);
++    if( nByte==0 ){
++      sqlite3_free(zConverted);
++      sqlite3_free(zTemp);
++      return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(),
++                         "winFullPathname4", zRelative);
+     }
++    sqlite3_free(zConverted);
++    zOut = sqlite3_win32_mbcs_to_utf8(zTemp);
++    sqlite3_free(zTemp);
+   }
++#endif
++  if( zOut ){
++    sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut);
++    sqlite3_free(zOut);
++    return SQLITE_OK;
++  }else{
++    return SQLITE_IOERR_NOMEM;
++  }
++#endif
+ }
+ 
++#ifndef SQLITE_OMIT_LOAD_EXTENSION
+ /*
+-** Increase the reference count of a supplied page by 1.
+-*/
+-SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr *p){
+-  assert(p->nRef>0);
+-  p->nRef++;
+-}
+-
+-/*
+-** Drop a page from the cache. There must be exactly one reference to the
+-** page. This function deletes that reference, so after it returns the
+-** page pointed to by p is invalid.
++** Interfaces for opening a shared library, finding entry points
++** within the shared library, and closing the shared library.
+ */
+-SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){
+-  assert( p->nRef==1 );
+-  if( p->flags&PGHDR_DIRTY ){
+-    pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
++static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){
++  HANDLE h;
++#if defined(__CYGWIN__)
++  int nFull = pVfs->mxPathname+1;
++  char *zFull = sqlite3MallocZero( nFull );
++  void *zConverted = 0;
++  if( zFull==0 ){
++    OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
++    return 0;
+   }
+-  p->pCache->nRef--;
+-  if( p->pgno==1 ){
+-    p->pCache->pPage1 = 0;
++  if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){
++    sqlite3_free(zFull);
++    OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
++    return 0;
+   }
+-  sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 1);
+-}
+-
+-/*
+-** Make sure the page is marked as dirty. If it isn't dirty already,
+-** make it so.
+-*/
+-SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){
+-  p->flags &= ~PGHDR_DONT_WRITE;
+-  assert( p->nRef>0 );
+-  if( 0==(p->flags & PGHDR_DIRTY) ){
+-    p->flags |= PGHDR_DIRTY;
+-    pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD);
++  zConverted = winConvertFromUtf8Filename(zFull);
++  sqlite3_free(zFull);
++#else
++  void *zConverted = winConvertFromUtf8Filename(zFilename);
++  UNUSED_PARAMETER(pVfs);
++#endif
++  if( zConverted==0 ){
++    OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0));
++    return 0;
+   }
+-}
+-
+-/*
+-** Make sure the page is marked as clean. If it isn't clean already,
+-** make it so.
+-*/
+-SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){
+-  if( (p->flags & PGHDR_DIRTY) ){
+-    pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
+-    p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC);
+-    if( p->nRef==0 ){
+-      pcacheUnpin(p);
+-    }
++  if( osIsNT() ){
++#if SQLITE_OS_WINRT
++    h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0);
++#else
++    h = osLoadLibraryW((LPCWSTR)zConverted);
++#endif
+   }
+-}
+-
+-/*
+-** Make every page in the cache clean.
+-*/
+-SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache *pCache){
+-  PgHdr *p;
+-  while( (p = pCache->pDirty)!=0 ){
+-    sqlite3PcacheMakeClean(p);
++#ifdef SQLITE_WIN32_HAS_ANSI
++  else{
++    h = osLoadLibraryA((char*)zConverted);
+   }
++#endif
++  OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)h));
++  sqlite3_free(zConverted);
++  return (void*)h;
+ }
+-
+-/*
+-** Clear the PGHDR_NEED_SYNC flag from all dirty pages.
+-*/
+-SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *pCache){
+-  PgHdr *p;
+-  for(p=pCache->pDirty; p; p=p->pDirtyNext){
+-    p->flags &= ~PGHDR_NEED_SYNC;
+-  }
+-  pCache->pSynced = pCache->pDirtyTail;
++static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
++  UNUSED_PARAMETER(pVfs);
++  winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut);
+ }
+-
+-/*
+-** Change the page number of page p to newPgno. 
+-*/
+-SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){
+-  PCache *pCache = p->pCache;
+-  assert( p->nRef>0 );
+-  assert( newPgno>0 );
+-  sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
+-  p->pgno = newPgno;
+-  if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
+-    pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
+-  }
++static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){
++  FARPROC proc;
++  UNUSED_PARAMETER(pVfs);
++  proc = osGetProcAddressA((HANDLE)pH, zSym);
++  OSTRACE(("DLSYM handle=%p, symbol=%s, address=%p\n",
++           (void*)pH, zSym, (void*)proc));
++  return (void(*)(void))proc;
+ }
++static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
++  UNUSED_PARAMETER(pVfs);
++  osFreeLibrary((HANDLE)pHandle);
++  OSTRACE(("DLCLOSE handle=%p\n", (void*)pHandle));
++}
++#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
++  #define winDlOpen  0
++  #define winDlError 0
++  #define winDlSym   0
++  #define winDlClose 0
++#endif
++
+ 
+ /*
+-** Drop every cache entry whose page number is greater than "pgno". The
+-** caller must ensure that there are no outstanding references to any pages
+-** other than page 1 with a page number greater than pgno.
+-**
+-** If there is a reference to page 1 and the pgno parameter passed to this
+-** function is 0, then the data area associated with page 1 is zeroed, but
+-** the page object is not dropped.
++** Write up to nBuf bytes of randomness into zBuf.
+ */
+-SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
+-  if( pCache->pCache ){
+-    PgHdr *p;
+-    PgHdr *pNext;
+-    for(p=pCache->pDirty; p; p=pNext){
+-      pNext = p->pDirtyNext;
+-      /* This routine never gets call with a positive pgno except right
+-      ** after sqlite3PcacheCleanAll().  So if there are dirty pages,
+-      ** it must be that pgno==0.
+-      */
+-      assert( p->pgno>0 );
+-      if( ALWAYS(p->pgno>pgno) ){
+-        assert( p->flags&PGHDR_DIRTY );
+-        sqlite3PcacheMakeClean(p);
+-      }
+-    }
+-    if( pgno==0 && pCache->pPage1 ){
+-      memset(pCache->pPage1->pData, 0, pCache->szPage);
+-      pgno = 1;
+-    }
+-    sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1);
++static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
++  int n = 0;
++  UNUSED_PARAMETER(pVfs);
++#if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS)
++  n = nBuf;
++  memset(zBuf, 0, nBuf);
++#else
++  if( sizeof(SYSTEMTIME)<=nBuf-n ){
++    SYSTEMTIME x;
++    osGetSystemTime(&x);
++    memcpy(&zBuf[n], &x, sizeof(x));
++    n += sizeof(x);
++  }
++  if( sizeof(DWORD)<=nBuf-n ){
++    DWORD pid = osGetCurrentProcessId();
++    memcpy(&zBuf[n], &pid, sizeof(pid));
++    n += sizeof(pid);
++  }
++#if SQLITE_OS_WINRT
++  if( sizeof(ULONGLONG)<=nBuf-n ){
++    ULONGLONG cnt = osGetTickCount64();
++    memcpy(&zBuf[n], &cnt, sizeof(cnt));
++    n += sizeof(cnt);
++  }
++#else
++  if( sizeof(DWORD)<=nBuf-n ){
++    DWORD cnt = osGetTickCount();
++    memcpy(&zBuf[n], &cnt, sizeof(cnt));
++    n += sizeof(cnt);
++  }
++#endif
++  if( sizeof(LARGE_INTEGER)<=nBuf-n ){
++    LARGE_INTEGER i;
++    osQueryPerformanceCounter(&i);
++    memcpy(&zBuf[n], &i, sizeof(i));
++    n += sizeof(i);
++  }
++#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
++  if( sizeof(UUID)<=nBuf-n ){
++    UUID id;
++    memset(&id, 0, sizeof(UUID));
++    osUuidCreate(&id);
++    memcpy(zBuf, &id, sizeof(UUID));
++    n += sizeof(UUID);
++  }
++  if( sizeof(UUID)<=nBuf-n ){
++    UUID id;
++    memset(&id, 0, sizeof(UUID));
++    osUuidCreateSequential(&id);
++    memcpy(zBuf, &id, sizeof(UUID));
++    n += sizeof(UUID);
+   }
++#endif
++#endif /* defined(SQLITE_TEST) || defined(SQLITE_ZERO_PRNG_SEED) */
++  return n;
+ }
+ 
+-/*
+-** Close a cache.
+-*/
+-SQLITE_PRIVATE void sqlite3PcacheClose(PCache *pCache){
+-  assert( pCache->pCache!=0 );
+-  sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
+-}
+ 
+-/* 
+-** Discard the contents of the cache.
++/*
++** Sleep for a little while.  Return the amount of time slept.
+ */
+-SQLITE_PRIVATE void sqlite3PcacheClear(PCache *pCache){
+-  sqlite3PcacheTruncate(pCache, 0);
++static int winSleep(sqlite3_vfs *pVfs, int microsec){
++  sqlite3_win32_sleep((microsec+999)/1000);
++  UNUSED_PARAMETER(pVfs);
++  return ((microsec+999)/1000)*1000;
+ }
+ 
+ /*
+-** Merge two lists of pages connected by pDirty and in pgno order.
+-** Do not both fixing the pDirtyPrev pointers.
++** The following variable, if set to a non-zero value, is interpreted as
++** the number of seconds since 1970 and is used to set the result of
++** sqlite3OsCurrentTime() during testing.
+ */
+-static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){
+-  PgHdr result, *pTail;
+-  pTail = &result;
+-  while( pA && pB ){
+-    if( pA->pgno<pB->pgno ){
+-      pTail->pDirty = pA;
+-      pTail = pA;
+-      pA = pA->pDirty;
+-    }else{
+-      pTail->pDirty = pB;
+-      pTail = pB;
+-      pB = pB->pDirty;
+-    }
+-  }
+-  if( pA ){
+-    pTail->pDirty = pA;
+-  }else if( pB ){
+-    pTail->pDirty = pB;
+-  }else{
+-    pTail->pDirty = 0;
+-  }
+-  return result.pDirty;
+-}
++#ifdef SQLITE_TEST
++SQLITE_API int sqlite3_current_time = 0;  /* Fake system time in seconds since 1970. */
++#endif
+ 
+ /*
+-** Sort the list of pages in accending order by pgno.  Pages are
+-** connected by pDirty pointers.  The pDirtyPrev pointers are
+-** corrupted by this sort.
++** Find the current time (in Universal Coordinated Time).  Write into *piNow
++** the current time and date as a Julian Day number times 86_400_000.  In
++** other words, write into *piNow the number of milliseconds since the Julian
++** epoch of noon in Greenwich on November 24, 4714 B.C according to the
++** proleptic Gregorian calendar.
+ **
+-** Since there cannot be more than 2^31 distinct pages in a database,
+-** there cannot be more than 31 buckets required by the merge sorter.
+-** One extra bucket is added to catch overflow in case something
+-** ever changes to make the previous sentence incorrect.
++** On success, return SQLITE_OK.  Return SQLITE_ERROR if the time and date
++** cannot be found.
+ */
+-#define N_SORT_BUCKET  32
+-static PgHdr *pcacheSortDirtyList(PgHdr *pIn){
+-  PgHdr *a[N_SORT_BUCKET], *p;
+-  int i;
+-  memset(a, 0, sizeof(a));
+-  while( pIn ){
+-    p = pIn;
+-    pIn = p->pDirty;
+-    p->pDirty = 0;
+-    for(i=0; ALWAYS(i<N_SORT_BUCKET-1); i++){
+-      if( a[i]==0 ){
+-        a[i] = p;
+-        break;
+-      }else{
+-        p = pcacheMergeDirtyList(a[i], p);
+-        a[i] = 0;
+-      }
+-    }
+-    if( NEVER(i==N_SORT_BUCKET-1) ){
+-      /* To get here, there need to be 2^(N_SORT_BUCKET) elements in
+-      ** the input list.  But that is impossible.
+-      */
+-      a[i] = pcacheMergeDirtyList(a[i], p);
+-    }
++static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
++  /* FILETIME structure is a 64-bit value representing the number of
++     100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
++  */
++  FILETIME ft;
++  static const sqlite3_int64 winFiletimeEpoch = 23058135*(sqlite3_int64)8640000;
++#ifdef SQLITE_TEST
++  static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
++#endif
++  /* 2^32 - to avoid use of LL and warnings in gcc */
++  static const sqlite3_int64 max32BitValue =
++      (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 +
++      (sqlite3_int64)294967296;
++
++#if SQLITE_OS_WINCE
++  SYSTEMTIME time;
++  osGetSystemTime(&time);
++  /* if SystemTimeToFileTime() fails, it returns zero. */
++  if (!osSystemTimeToFileTime(&time,&ft)){
++    return SQLITE_ERROR;
+   }
+-  p = a[0];
+-  for(i=1; i<N_SORT_BUCKET; i++){
+-    p = pcacheMergeDirtyList(p, a[i]);
++#else
++  osGetSystemTimeAsFileTime( &ft );
++#endif
++
++  *piNow = winFiletimeEpoch +
++            ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) +
++               (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000;
++
++#ifdef SQLITE_TEST
++  if( sqlite3_current_time ){
++    *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
+   }
+-  return p;
++#endif
++  UNUSED_PARAMETER(pVfs);
++  return SQLITE_OK;
+ }
+ 
+ /*
+-** Return a list of all dirty pages in the cache, sorted by page number.
++** Find the current time (in Universal Coordinated Time).  Write the
++** current time and date as a Julian Day number into *prNow and
++** return 0.  Return 1 if the time and date cannot be found.
+ */
+-SQLITE_PRIVATE PgHdr *sqlite3PcacheDirtyList(PCache *pCache){
+-  PgHdr *p;
+-  for(p=pCache->pDirty; p; p=p->pDirtyNext){
+-    p->pDirty = p->pDirtyNext;
++static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
++  int rc;
++  sqlite3_int64 i;
++  rc = winCurrentTimeInt64(pVfs, &i);
++  if( !rc ){
++    *prNow = i/86400000.0;
+   }
+-  return pcacheSortDirtyList(pCache->pDirty);
++  return rc;
+ }
+ 
+-/* 
+-** Return the total number of referenced pages held by the cache.
++/*
++** The idea is that this function works like a combination of
++** GetLastError() and FormatMessage() on Windows (or errno and
++** strerror_r() on Unix). After an error is returned by an OS
++** function, SQLite calls this function with zBuf pointing to
++** a buffer of nBuf bytes. The OS layer should populate the
++** buffer with a nul-terminated UTF-8 encoded error message
++** describing the last IO error to have occurred within the calling
++** thread.
++**
++** If the error message is too large for the supplied buffer,
++** it should be truncated. The return value of xGetLastError
++** is zero if the error message fits in the buffer, or non-zero
++** otherwise (if the message was truncated). If non-zero is returned,
++** then it is not necessary to include the nul-terminator character
++** in the output buffer.
++**
++** Not supplying an error message will have no adverse effect
++** on SQLite. It is fine to have an implementation that never
++** returns an error message:
++**
++**   int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
++**     assert(zBuf[0]=='\0');
++**     return 0;
++**   }
++**
++** However if an error message is supplied, it will be incorporated
++** by sqlite into the error message available to the user using
++** sqlite3_errmsg(), possibly making IO errors easier to debug.
+ */
+-SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache *pCache){
+-  return pCache->nRef;
++static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
++  UNUSED_PARAMETER(pVfs);
++  return winGetLastErrorMsg(osGetLastError(), nBuf, zBuf);
+ }
+ 
+ /*
+-** Return the number of references to the page supplied as an argument.
++** Initialize and deinitialize the operating system interface.
+ */
+-SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr *p){
+-  return p->nRef;
+-}
++SQLITE_API int SQLITE_STDCALL sqlite3_os_init(void){
++  static sqlite3_vfs winVfs = {
++    3,                   /* iVersion */
++    sizeof(winFile),     /* szOsFile */
++    SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */
++    0,                   /* pNext */
++    "win32",             /* zName */
++    0,                   /* pAppData */
++    winOpen,             /* xOpen */
++    winDelete,           /* xDelete */
++    winAccess,           /* xAccess */
++    winFullPathname,     /* xFullPathname */
++    winDlOpen,           /* xDlOpen */
++    winDlError,          /* xDlError */
++    winDlSym,            /* xDlSym */
++    winDlClose,          /* xDlClose */
++    winRandomness,       /* xRandomness */
++    winSleep,            /* xSleep */
++    winCurrentTime,      /* xCurrentTime */
++    winGetLastError,     /* xGetLastError */
++    winCurrentTimeInt64, /* xCurrentTimeInt64 */
++    winSetSystemCall,    /* xSetSystemCall */
++    winGetSystemCall,    /* xGetSystemCall */
++    winNextSystemCall,   /* xNextSystemCall */
++  };
++#if defined(SQLITE_WIN32_HAS_WIDE)
++  static sqlite3_vfs winLongPathVfs = {
++    3,                   /* iVersion */
++    sizeof(winFile),     /* szOsFile */
++    SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */
++    0,                   /* pNext */
++    "win32-longpath",    /* zName */
++    0,                   /* pAppData */
++    winOpen,             /* xOpen */
++    winDelete,           /* xDelete */
++    winAccess,           /* xAccess */
++    winFullPathname,     /* xFullPathname */
++    winDlOpen,           /* xDlOpen */
++    winDlError,          /* xDlError */
++    winDlSym,            /* xDlSym */
++    winDlClose,          /* xDlClose */
++    winRandomness,       /* xRandomness */
++    winSleep,            /* xSleep */
++    winCurrentTime,      /* xCurrentTime */
++    winGetLastError,     /* xGetLastError */
++    winCurrentTimeInt64, /* xCurrentTimeInt64 */
++    winSetSystemCall,    /* xSetSystemCall */
++    winGetSystemCall,    /* xGetSystemCall */
++    winNextSystemCall,   /* xNextSystemCall */
++  };
++#endif
+ 
+-/* 
+-** Return the total number of pages in the cache.
+-*/
+-SQLITE_PRIVATE int sqlite3PcachePagecount(PCache *pCache){
+-  assert( pCache->pCache!=0 );
+-  return sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache);
+-}
++  /* Double-check that the aSyscall[] array has been constructed
++  ** correctly.  See ticket [bb3a86e890c8e96ab] */
++  assert( ArraySize(aSyscall)==80 );
+ 
+-#ifdef SQLITE_TEST
+-/*
+-** Get the suggested cache-size value.
+-*/
+-SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *pCache){
+-  return numberOfCachePages(pCache);
+-}
++  /* get memory map allocation granularity */
++  memset(&winSysInfo, 0, sizeof(SYSTEM_INFO));
++#if SQLITE_OS_WINRT
++  osGetNativeSystemInfo(&winSysInfo);
++#else
++  osGetSystemInfo(&winSysInfo);
+ #endif
++  assert( winSysInfo.dwAllocationGranularity>0 );
++  assert( winSysInfo.dwPageSize>0 );
+ 
+-/*
+-** Set the suggested cache-size value.
+-*/
+-SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){
+-  assert( pCache->pCache!=0 );
+-  pCache->szCache = mxPage;
+-  sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache,
+-                                         numberOfCachePages(pCache));
+-}
+-
+-/*
+-** Free up as much memory as possible from the page cache.
+-*/
+-SQLITE_PRIVATE void sqlite3PcacheShrink(PCache *pCache){
+-  assert( pCache->pCache!=0 );
+-  sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache);
+-}
++  sqlite3_vfs_register(&winVfs, 1);
+ 
+-/*
+-** Return the size of the header added by this middleware layer
+-** in the page-cache hierarchy.
+-*/
+-SQLITE_PRIVATE int sqlite3HeaderSizePcache(void){ return ROUND8(sizeof(PgHdr)); }
++#if defined(SQLITE_WIN32_HAS_WIDE)
++  sqlite3_vfs_register(&winLongPathVfs, 0);
++#endif
+ 
++  return SQLITE_OK;
++}
+ 
+-#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
+-/*
+-** For all dirty pages currently in the cache, invoke the specified
+-** callback. This is only used if the SQLITE_CHECK_PAGES macro is
+-** defined.
+-*/
+-SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)){
+-  PgHdr *pDirty;
+-  for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext){
+-    xIter(pDirty);
++SQLITE_API int SQLITE_STDCALL sqlite3_os_end(void){
++#if SQLITE_OS_WINRT
++  if( sleepObj!=NULL ){
++    osCloseHandle(sleepObj);
++    sleepObj = NULL;
+   }
+-}
+ #endif
++  return SQLITE_OK;
++}
+ 
+-/************** End of pcache.c **********************************************/
+-/************** Begin file pcache1.c *****************************************/
++#endif /* SQLITE_OS_WIN */
++
++/************** End of os_win.c **********************************************/
++/************** Begin file bitvec.c ******************************************/
+ /*
+-** 2008 November 05
++** 2008 February 16
+ **
+ ** The author disclaims copyright to this source code.  In place of
+ ** a legal notice, here is a blessing:
+@@ -39935,1052 +42486,1078 @@
+ **    May you share freely, never taking more than you give.
+ **
+ *************************************************************************
++** This file implements an object that represents a fixed-length
++** bitmap.  Bits are numbered starting with 1.
+ **
+-** This file implements the default page cache implementation (the
+-** sqlite3_pcache interface). It also contains part of the implementation
+-** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features.
+-** If the default page cache implementation is overridden, then neither of
+-** these two features are available.
+-*/
+-
+-
+-typedef struct PCache1 PCache1;
+-typedef struct PgHdr1 PgHdr1;
+-typedef struct PgFreeslot PgFreeslot;
+-typedef struct PGroup PGroup;
+-
+-/* Each page cache (or PCache) belongs to a PGroup.  A PGroup is a set 
+-** of one or more PCaches that are able to recycle each other's unpinned
+-** pages when they are under memory pressure.  A PGroup is an instance of
+-** the following object.
+-**
+-** This page cache implementation works in one of two modes:
+-**
+-**   (1)  Every PCache is the sole member of its own PGroup.  There is
+-**        one PGroup per PCache.
+-**
+-**   (2)  There is a single global PGroup that all PCaches are a member
+-**        of.
++** A bitmap is used to record which pages of a database file have been
++** journalled during a transaction, or which pages have the "dont-write"
++** property.  Usually only a few pages are meet either condition.
++** So the bitmap is usually sparse and has low cardinality.
++** But sometimes (for example when during a DROP of a large table) most
++** or all of the pages in a database can get journalled.  In those cases, 
++** the bitmap becomes dense with high cardinality.  The algorithm needs 
++** to handle both cases well.
+ **
+-** Mode 1 uses more memory (since PCache instances are not able to rob
+-** unused pages from other PCaches) but it also operates without a mutex,
+-** and is therefore often faster.  Mode 2 requires a mutex in order to be
+-** threadsafe, but recycles pages more efficiently.
++** The size of the bitmap is fixed when the object is created.
+ **
+-** For mode (1), PGroup.mutex is NULL.  For mode (2) there is only a single
+-** PGroup which is the pcache1.grp global variable and its mutex is
+-** SQLITE_MUTEX_STATIC_LRU.
+-*/
+-struct PGroup {
+-  sqlite3_mutex *mutex;          /* MUTEX_STATIC_LRU or NULL */
+-  unsigned int nMaxPage;         /* Sum of nMax for purgeable caches */
+-  unsigned int nMinPage;         /* Sum of nMin for purgeable caches */
+-  unsigned int mxPinned;         /* nMaxpage + 10 - nMinPage */
+-  unsigned int nCurrentPage;     /* Number of purgeable pages allocated */
+-  PgHdr1 *pLruHead, *pLruTail;   /* LRU list of unpinned pages */
+-};
+-
+-/* Each page cache is an instance of the following object.  Every
+-** open database file (including each in-memory database and each
+-** temporary or transient database) has a single page cache which
+-** is an instance of this object.
++** All bits are clear when the bitmap is created.  Individual bits
++** may be set or cleared one at a time.
+ **
+-** Pointers to structures of this type are cast and returned as 
+-** opaque sqlite3_pcache* handles.
++** Test operations are about 100 times more common that set operations.
++** Clear operations are exceedingly rare.  There are usually between
++** 5 and 500 set operations per Bitvec object, though the number of sets can
++** sometimes grow into tens of thousands or larger.  The size of the
++** Bitvec object is the number of pages in the database file at the
++** start of a transaction, and is thus usually less than a few thousand,
++** but can be as large as 2 billion for a really big database.
+ */
+-struct PCache1 {
+-  /* Cache configuration parameters. Page size (szPage) and the purgeable
+-  ** flag (bPurgeable) are set when the cache is created. nMax may be 
+-  ** modified at any time by a call to the pcache1Cachesize() method.
+-  ** The PGroup mutex must be held when accessing nMax.
+-  */
+-  PGroup *pGroup;                     /* PGroup this cache belongs to */
+-  int szPage;                         /* Size of allocated pages in bytes */
+-  int szExtra;                        /* Size of extra space in bytes */
+-  int bPurgeable;                     /* True if cache is purgeable */
+-  unsigned int nMin;                  /* Minimum number of pages reserved */
+-  unsigned int nMax;                  /* Configured "cache_size" value */
+-  unsigned int n90pct;                /* nMax*9/10 */
+-  unsigned int iMaxKey;               /* Largest key seen since xTruncate() */
+ 
+-  /* Hash table of all pages. The following variables may only be accessed
+-  ** when the accessor is holding the PGroup mutex.
+-  */
+-  unsigned int nRecyclable;           /* Number of pages in the LRU list */
+-  unsigned int nPage;                 /* Total number of pages in apHash */
+-  unsigned int nHash;                 /* Number of slots in apHash[] */
+-  PgHdr1 **apHash;                    /* Hash table for fast lookup by key */
+-};
++/* Size of the Bitvec structure in bytes. */
++#define BITVEC_SZ        512
+ 
+-/*
+-** Each cache entry is represented by an instance of the following 
+-** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of
+-** PgHdr1.pCache->szPage bytes is allocated directly before this structure 
+-** in memory.
+-*/
+-struct PgHdr1 {
+-  sqlite3_pcache_page page;
+-  unsigned int iKey;             /* Key value (page number) */
+-  u8 isPinned;                   /* Page in use, not on the LRU list */
+-  PgHdr1 *pNext;                 /* Next in hash table chain */
+-  PCache1 *pCache;               /* Cache that currently owns this page */
+-  PgHdr1 *pLruNext;              /* Next in LRU list of unpinned pages */
+-  PgHdr1 *pLruPrev;              /* Previous in LRU list of unpinned pages */
+-};
++/* Round the union size down to the nearest pointer boundary, since that's how 
++** it will be aligned within the Bitvec struct. */
++#define BITVEC_USIZE     (((BITVEC_SZ-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*))
+ 
+-/*
+-** Free slots in the allocator used to divide up the buffer provided using
+-** the SQLITE_CONFIG_PAGECACHE mechanism.
+-*/
+-struct PgFreeslot {
+-  PgFreeslot *pNext;  /* Next free slot */
+-};
++/* Type of the array "element" for the bitmap representation. 
++** Should be a power of 2, and ideally, evenly divide into BITVEC_USIZE. 
++** Setting this to the "natural word" size of your CPU may improve
++** performance. */
++#define BITVEC_TELEM     u8
++/* Size, in bits, of the bitmap element. */
++#define BITVEC_SZELEM    8
++/* Number of elements in a bitmap array. */
++#define BITVEC_NELEM     (BITVEC_USIZE/sizeof(BITVEC_TELEM))
++/* Number of bits in the bitmap array. */
++#define BITVEC_NBIT      (BITVEC_NELEM*BITVEC_SZELEM)
+ 
+-/*
+-** Global data used by this cache.
+-*/
+-static SQLITE_WSD struct PCacheGlobal {
+-  PGroup grp;                    /* The global PGroup for mode (2) */
++/* Number of u32 values in hash table. */
++#define BITVEC_NINT      (BITVEC_USIZE/sizeof(u32))
++/* Maximum number of entries in hash table before 
++** sub-dividing and re-hashing. */
++#define BITVEC_MXHASH    (BITVEC_NINT/2)
++/* Hashing function for the aHash representation.
++** Empirical testing showed that the *37 multiplier 
++** (an arbitrary prime)in the hash function provided 
++** no fewer collisions than the no-op *1. */
++#define BITVEC_HASH(X)   (((X)*1)%BITVEC_NINT)
+ 
+-  /* Variables related to SQLITE_CONFIG_PAGECACHE settings.  The
+-  ** szSlot, nSlot, pStart, pEnd, nReserve, and isInit values are all
+-  ** fixed at sqlite3_initialize() time and do not require mutex protection.
+-  ** The nFreeSlot and pFree values do require mutex protection.
+-  */
+-  int isInit;                    /* True if initialized */
+-  int szSlot;                    /* Size of each free slot */
+-  int nSlot;                     /* The number of pcache slots */
+-  int nReserve;                  /* Try to keep nFreeSlot above this */
+-  void *pStart, *pEnd;           /* Bounds of pagecache malloc range */
+-  /* Above requires no mutex.  Use mutex below for variable that follow. */
+-  sqlite3_mutex *mutex;          /* Mutex for accessing the following: */
+-  PgFreeslot *pFree;             /* Free page blocks */
+-  int nFreeSlot;                 /* Number of unused pcache slots */
+-  /* The following value requires a mutex to change.  We skip the mutex on
+-  ** reading because (1) most platforms read a 32-bit integer atomically and
+-  ** (2) even if an incorrect value is read, no great harm is done since this
+-  ** is really just an optimization. */
+-  int bUnderPressure;            /* True if low on PAGECACHE memory */
+-} pcache1_g;
++#define BITVEC_NPTR      (BITVEC_USIZE/sizeof(Bitvec *))
+ 
+-/*
+-** All code in this file should access the global structure above via the
+-** alias "pcache1". This ensures that the WSD emulation is used when
+-** compiling for systems that do not support real WSD.
+-*/
+-#define pcache1 (GLOBAL(struct PCacheGlobal, pcache1_g))
+ 
+ /*
+-** Macros to enter and leave the PCache LRU mutex.
++** A bitmap is an instance of the following structure.
++**
++** This bitmap records the existence of zero or more bits
++** with values between 1 and iSize, inclusive.
++**
++** There are three possible representations of the bitmap.
++** If iSize<=BITVEC_NBIT, then Bitvec.u.aBitmap[] is a straight
++** bitmap.  The least significant bit is bit 1.
++**
++** If iSize>BITVEC_NBIT and iDivisor==0 then Bitvec.u.aHash[] is
++** a hash table that will hold up to BITVEC_MXHASH distinct values.
++**
++** Otherwise, the value i is redirected into one of BITVEC_NPTR
++** sub-bitmaps pointed to by Bitvec.u.apSub[].  Each subbitmap
++** handles up to iDivisor separate values of i.  apSub[0] holds
++** values between 1 and iDivisor.  apSub[1] holds values between
++** iDivisor+1 and 2*iDivisor.  apSub[N] holds values between
++** N*iDivisor+1 and (N+1)*iDivisor.  Each subbitmap is normalized
++** to hold deal with values between 1 and iDivisor.
+ */
+-#define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex)
+-#define pcache1LeaveMutex(X) sqlite3_mutex_leave((X)->mutex)
+-
+-/******************************************************************************/
+-/******** Page Allocation/SQLITE_CONFIG_PCACHE Related Functions **************/
++struct Bitvec {
++  u32 iSize;      /* Maximum bit index.  Max iSize is 4,294,967,296. */
++  u32 nSet;       /* Number of bits that are set - only valid for aHash
++                  ** element.  Max is BITVEC_NINT.  For BITVEC_SZ of 512,
++                  ** this would be 125. */
++  u32 iDivisor;   /* Number of bits handled by each apSub[] entry. */
++                  /* Should >=0 for apSub element. */
++                  /* Max iDivisor is max(u32) / BITVEC_NPTR + 1.  */
++                  /* For a BITVEC_SZ of 512, this would be 34,359,739. */
++  union {
++    BITVEC_TELEM aBitmap[BITVEC_NELEM];    /* Bitmap representation */
++    u32 aHash[BITVEC_NINT];      /* Hash table representation */
++    Bitvec *apSub[BITVEC_NPTR];  /* Recursive representation */
++  } u;
++};
+ 
+ /*
+-** This function is called during initialization if a static buffer is 
+-** supplied to use for the page-cache by passing the SQLITE_CONFIG_PAGECACHE
+-** verb to sqlite3_config(). Parameter pBuf points to an allocation large
+-** enough to contain 'n' buffers of 'sz' bytes each.
+-**
+-** This routine is called from sqlite3_initialize() and so it is guaranteed
+-** to be serialized already.  There is no need for further mutexing.
++** Create a new bitmap object able to handle bits between 0 and iSize,
++** inclusive.  Return a pointer to the new object.  Return NULL if 
++** malloc fails.
+ */
+-SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
+-  if( pcache1.isInit ){
+-    PgFreeslot *p;
+-    sz = ROUNDDOWN8(sz);
+-    pcache1.szSlot = sz;
+-    pcache1.nSlot = pcache1.nFreeSlot = n;
+-    pcache1.nReserve = n>90 ? 10 : (n/10 + 1);
+-    pcache1.pStart = pBuf;
+-    pcache1.pFree = 0;
+-    pcache1.bUnderPressure = 0;
+-    while( n-- ){
+-      p = (PgFreeslot*)pBuf;
+-      p->pNext = pcache1.pFree;
+-      pcache1.pFree = p;
+-      pBuf = (void*)&((char*)pBuf)[sz];
+-    }
+-    pcache1.pEnd = pBuf;
++SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32 iSize){
++  Bitvec *p;
++  assert( sizeof(*p)==BITVEC_SZ );
++  p = sqlite3MallocZero( sizeof(*p) );
++  if( p ){
++    p->iSize = iSize;
+   }
++  return p;
+ }
+ 
+ /*
+-** Malloc function used within this file to allocate space from the buffer
+-** configured using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no 
+-** such buffer exists or there is no space left in it, this function falls 
+-** back to sqlite3Malloc().
+-**
+-** Multiple threads can run this routine at the same time.  Global variables
+-** in pcache1 need to be protected via mutex.
++** Check to see if the i-th bit is set.  Return true or false.
++** If p is NULL (if the bitmap has not been created) or if
++** i is out of range, then return false.
+ */
+-static void *pcache1Alloc(int nByte){
+-  void *p = 0;
+-  assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
+-  if( nByte<=pcache1.szSlot ){
+-    sqlite3_mutex_enter(pcache1.mutex);
+-    p = (PgHdr1 *)pcache1.pFree;
+-    if( p ){
+-      pcache1.pFree = pcache1.pFree->pNext;
+-      pcache1.nFreeSlot--;
+-      pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
+-      assert( pcache1.nFreeSlot>=0 );
+-      sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
+-      sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1);
++SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec *p, u32 i){
++  if( p==0 ) return 0;
++  if( i>p->iSize || i==0 ) return 0;
++  i--;
++  while( p->iDivisor ){
++    u32 bin = i/p->iDivisor;
++    i = i%p->iDivisor;
++    p = p->u.apSub[bin];
++    if (!p) {
++      return 0;
+     }
+-    sqlite3_mutex_leave(pcache1.mutex);
+   }
+-  if( p==0 ){
+-    /* Memory is not available in the SQLITE_CONFIG_PAGECACHE pool.  Get
+-    ** it from sqlite3Malloc instead.
+-    */
+-    p = sqlite3Malloc(nByte);
+-#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
+-    if( p ){
+-      int sz = sqlite3MallocSize(p);
+-      sqlite3_mutex_enter(pcache1.mutex);
+-      sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
+-      sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
+-      sqlite3_mutex_leave(pcache1.mutex);
++  if( p->iSize<=BITVEC_NBIT ){
++    return (p->u.aBitmap[i/BITVEC_SZELEM] & (1<<(i&(BITVEC_SZELEM-1))))!=0;
++  } else{
++    u32 h = BITVEC_HASH(i++);
++    while( p->u.aHash[h] ){
++      if( p->u.aHash[h]==i ) return 1;
++      h = (h+1) % BITVEC_NINT;
+     }
+-#endif
+-    sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
++    return 0;
+   }
+-  return p;
+ }
+ 
+ /*
+-** Free an allocated buffer obtained from pcache1Alloc().
++** Set the i-th bit.  Return 0 on success and an error code if
++** anything goes wrong.
++**
++** This routine might cause sub-bitmaps to be allocated.  Failing
++** to get the memory needed to hold the sub-bitmap is the only
++** that can go wrong with an insert, assuming p and i are valid.
++**
++** The calling function must ensure that p is a valid Bitvec object
++** and that the value for "i" is within range of the Bitvec object.
++** Otherwise the behavior is undefined.
+ */
+-static int pcache1Free(void *p){
+-  int nFreed = 0;
+-  if( p==0 ) return 0;
+-  if( p>=pcache1.pStart && p<pcache1.pEnd ){
+-    PgFreeslot *pSlot;
+-    sqlite3_mutex_enter(pcache1.mutex);
+-    sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_USED, 1);
+-    pSlot = (PgFreeslot*)p;
+-    pSlot->pNext = pcache1.pFree;
+-    pcache1.pFree = pSlot;
+-    pcache1.nFreeSlot++;
+-    pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
+-    assert( pcache1.nFreeSlot<=pcache1.nSlot );
+-    sqlite3_mutex_leave(pcache1.mutex);
+-  }else{
+-    assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
+-    sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
+-    nFreed = sqlite3MallocSize(p);
+-#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
+-    sqlite3_mutex_enter(pcache1.mutex);
+-    sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_OVERFLOW, nFreed);
+-    sqlite3_mutex_leave(pcache1.mutex);
+-#endif
+-    sqlite3_free(p);
++SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec *p, u32 i){
++  u32 h;
++  if( p==0 ) return SQLITE_OK;
++  assert( i>0 );
++  assert( i<=p->iSize );
++  i--;
++  while((p->iSize > BITVEC_NBIT) && p->iDivisor) {
++    u32 bin = i/p->iDivisor;
++    i = i%p->iDivisor;
++    if( p->u.apSub[bin]==0 ){
++      p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor );
++      if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM;
++    }
++    p = p->u.apSub[bin];
+   }
+-  return nFreed;
+-}
+-
+-#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+-/*
+-** Return the size of a pcache allocation
+-*/
+-static int pcache1MemSize(void *p){
+-  if( p>=pcache1.pStart && p<pcache1.pEnd ){
+-    return pcache1.szSlot;
+-  }else{
+-    int iSize;
+-    assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
+-    sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
+-    iSize = sqlite3MallocSize(p);
+-    sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
+-    return iSize;
++  if( p->iSize<=BITVEC_NBIT ){
++    p->u.aBitmap[i/BITVEC_SZELEM] |= 1 << (i&(BITVEC_SZELEM-1));
++    return SQLITE_OK;
+   }
++  h = BITVEC_HASH(i++);
++  /* if there wasn't a hash collision, and this doesn't */
++  /* completely fill the hash, then just add it without */
++  /* worring about sub-dividing and re-hashing. */
++  if( !p->u.aHash[h] ){
++    if (p->nSet<(BITVEC_NINT-1)) {
++      goto bitvec_set_end;
++    } else {
++      goto bitvec_set_rehash;
++    }
++  }
++  /* there was a collision, check to see if it's already */
++  /* in hash, if not, try to find a spot for it */
++  do {
++    if( p->u.aHash[h]==i ) return SQLITE_OK;
++    h++;
++    if( h>=BITVEC_NINT ) h = 0;
++  } while( p->u.aHash[h] );
++  /* we didn't find it in the hash.  h points to the first */
++  /* available free spot. check to see if this is going to */
++  /* make our hash too "full".  */
++bitvec_set_rehash:
++  if( p->nSet>=BITVEC_MXHASH ){
++    unsigned int j;
++    int rc;
++    u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash));
++    if( aiValues==0 ){
++      return SQLITE_NOMEM;
++    }else{
++      memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
++      memset(p->u.apSub, 0, sizeof(p->u.apSub));
++      p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR;
++      rc = sqlite3BitvecSet(p, i);
++      for(j=0; j<BITVEC_NINT; j++){
++        if( aiValues[j] ) rc |= sqlite3BitvecSet(p, aiValues[j]);
++      }
++      sqlite3StackFree(0, aiValues);
++      return rc;
++    }
++  }
++bitvec_set_end:
++  p->nSet++;
++  p->u.aHash[h] = i;
++  return SQLITE_OK;
+ }
+-#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
+ 
+ /*
+-** Allocate a new page object initially associated with cache pCache.
++** Clear the i-th bit.
++**
++** pBuf must be a pointer to at least BITVEC_SZ bytes of temporary storage
++** that BitvecClear can use to rebuilt its hash table.
+ */
+-static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
+-  PgHdr1 *p = 0;
+-  void *pPg;
+-
+-  /* The group mutex must be released before pcache1Alloc() is called. This
+-  ** is because it may call sqlite3_release_memory(), which assumes that 
+-  ** this mutex is not held. */
+-  assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
+-  pcache1LeaveMutex(pCache->pGroup);
+-#ifdef SQLITE_PCACHE_SEPARATE_HEADER
+-  pPg = pcache1Alloc(pCache->szPage);
+-  p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra);
+-  if( !pPg || !p ){
+-    pcache1Free(pPg);
+-    sqlite3_free(p);
+-    pPg = 0;
++SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec *p, u32 i, void *pBuf){
++  if( p==0 ) return;
++  assert( i>0 );
++  i--;
++  while( p->iDivisor ){
++    u32 bin = i/p->iDivisor;
++    i = i%p->iDivisor;
++    p = p->u.apSub[bin];
++    if (!p) {
++      return;
++    }
+   }
+-#else
+-  pPg = pcache1Alloc(ROUND8(sizeof(PgHdr1)) + pCache->szPage + pCache->szExtra);
+-  p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
+-#endif
+-  pcache1EnterMutex(pCache->pGroup);
+-
+-  if( pPg ){
+-    p->page.pBuf = pPg;
+-    p->page.pExtra = &p[1];
+-    if( pCache->bPurgeable ){
+-      pCache->pGroup->nCurrentPage++;
++  if( p->iSize<=BITVEC_NBIT ){
++    p->u.aBitmap[i/BITVEC_SZELEM] &= ~(1 << (i&(BITVEC_SZELEM-1)));
++  }else{
++    unsigned int j;
++    u32 *aiValues = pBuf;
++    memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash));
++    memset(p->u.aHash, 0, sizeof(p->u.aHash));
++    p->nSet = 0;
++    for(j=0; j<BITVEC_NINT; j++){
++      if( aiValues[j] && aiValues[j]!=(i+1) ){
++        u32 h = BITVEC_HASH(aiValues[j]-1);
++        p->nSet++;
++        while( p->u.aHash[h] ){
++          h++;
++          if( h>=BITVEC_NINT ) h = 0;
++        }
++        p->u.aHash[h] = aiValues[j];
++      }
+     }
+-    return p;
+   }
+-  return 0;
+ }
+ 
+ /*
+-** Free a page object allocated by pcache1AllocPage().
+-**
+-** The pointer is allowed to be NULL, which is prudent.  But it turns out
+-** that the current implementation happens to never call this routine
+-** with a NULL pointer, so we mark the NULL test with ALWAYS().
++** Destroy a bitmap object.  Reclaim all memory used.
+ */
+-static void pcache1FreePage(PgHdr1 *p){
+-  if( ALWAYS(p) ){
+-    PCache1 *pCache = p->pCache;
+-    assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) );
+-    pcache1Free(p->page.pBuf);
+-#ifdef SQLITE_PCACHE_SEPARATE_HEADER
+-    sqlite3_free(p);
+-#endif
+-    if( pCache->bPurgeable ){
+-      pCache->pGroup->nCurrentPage--;
++SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec *p){
++  if( p==0 ) return;
++  if( p->iDivisor ){
++    unsigned int i;
++    for(i=0; i<BITVEC_NPTR; i++){
++      sqlite3BitvecDestroy(p->u.apSub[i]);
+     }
+   }
++  sqlite3_free(p);
+ }
+ 
+ /*
+-** Malloc function used by SQLite to obtain space from the buffer configured
+-** using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no such buffer
+-** exists, this function falls back to sqlite3Malloc().
++** Return the value of the iSize parameter specified when Bitvec *p
++** was created.
+ */
+-SQLITE_PRIVATE void *sqlite3PageMalloc(int sz){
+-  return pcache1Alloc(sz);
++SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){
++  return p->iSize;
+ }
+ 
++#ifndef SQLITE_OMIT_BUILTIN_TEST
+ /*
+-** Free an allocated buffer obtained from sqlite3PageMalloc().
++** Let V[] be an array of unsigned characters sufficient to hold
++** up to N bits.  Let I be an integer between 0 and N.  0<=I<N.
++** Then the following macros can be used to set, clear, or test
++** individual bits within V.
+ */
+-SQLITE_PRIVATE void sqlite3PageFree(void *p){
+-  pcache1Free(p);
+-}
+-
++#define SETBIT(V,I)      V[I>>3] |= (1<<(I&7))
++#define CLEARBIT(V,I)    V[I>>3] &= ~(1<<(I&7))
++#define TESTBIT(V,I)     (V[I>>3]&(1<<(I&7)))!=0
+ 
+ /*
+-** Return true if it desirable to avoid allocating a new page cache
+-** entry.
++** This routine runs an extensive test of the Bitvec code.
+ **
+-** If memory was allocated specifically to the page cache using
+-** SQLITE_CONFIG_PAGECACHE but that memory has all been used, then
+-** it is desirable to avoid allocating a new page cache entry because
+-** presumably SQLITE_CONFIG_PAGECACHE was suppose to be sufficient
+-** for all page cache needs and we should not need to spill the
+-** allocation onto the heap.
++** The input is an array of integers that acts as a program
++** to test the Bitvec.  The integers are opcodes followed
++** by 0, 1, or 3 operands, depending on the opcode.  Another
++** opcode follows immediately after the last operand.
+ **
+-** Or, the heap is used for all page cache memory but the heap is
+-** under memory pressure, then again it is desirable to avoid
+-** allocating a new page cache entry in order to avoid stressing
+-** the heap even further.
+-*/
+-static int pcache1UnderMemoryPressure(PCache1 *pCache){
+-  if( pcache1.nSlot && (pCache->szPage+pCache->szExtra)<=pcache1.szSlot ){
+-    return pcache1.bUnderPressure;
+-  }else{
+-    return sqlite3HeapNearlyFull();
+-  }
+-}
+-
+-/******************************************************************************/
+-/******** General Implementation Functions ************************************/
+-
+-/*
+-** This function is used to resize the hash table used by the cache passed
+-** as the first argument.
++** There are 6 opcodes numbered from 0 through 5.  0 is the
++** "halt" opcode and causes the test to end.
+ **
+-** The PCache mutex must be held when this function is called.
++**    0          Halt and return the number of errors
++**    1 N S X    Set N bits beginning with S and incrementing by X
++**    2 N S X    Clear N bits beginning with S and incrementing by X
++**    3 N        Set N randomly chosen bits
++**    4 N        Clear N randomly chosen bits
++**    5 N S X    Set N bits from S increment X in array only, not in bitvec
++**
++** The opcodes 1 through 4 perform set and clear operations are performed
++** on both a Bitvec object and on a linear array of bits obtained from malloc.
++** Opcode 5 works on the linear array only, not on the Bitvec.
++** Opcode 5 is used to deliberately induce a fault in order to
++** confirm that error detection works.
++**
++** At the conclusion of the test the linear array is compared
++** against the Bitvec object.  If there are any differences,
++** an error is returned.  If they are the same, zero is returned.
++**
++** If a memory allocation error occurs, return -1.
+ */
+-static void pcache1ResizeHash(PCache1 *p){
+-  PgHdr1 **apNew;
+-  unsigned int nNew;
+-  unsigned int i;
++SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){
++  Bitvec *pBitvec = 0;
++  unsigned char *pV = 0;
++  int rc = -1;
++  int i, nx, pc, op;
++  void *pTmpSpace;
+ 
+-  assert( sqlite3_mutex_held(p->pGroup->mutex) );
++  /* Allocate the Bitvec to be tested and a linear array of
++  ** bits to act as the reference */
++  pBitvec = sqlite3BitvecCreate( sz );
++  pV = sqlite3MallocZero( (sz+7)/8 + 1 );
++  pTmpSpace = sqlite3_malloc64(BITVEC_SZ);
++  if( pBitvec==0 || pV==0 || pTmpSpace==0  ) goto bitvec_end;
+ 
+-  nNew = p->nHash*2;
+-  if( nNew<256 ){
+-    nNew = 256;
+-  }
++  /* NULL pBitvec tests */
++  sqlite3BitvecSet(0, 1);
++  sqlite3BitvecClear(0, 1, pTmpSpace);
+ 
+-  pcache1LeaveMutex(p->pGroup);
+-  if( p->nHash ){ sqlite3BeginBenignMalloc(); }
+-  apNew = (PgHdr1 **)sqlite3MallocZero(sizeof(PgHdr1 *)*nNew);
+-  if( p->nHash ){ sqlite3EndBenignMalloc(); }
+-  pcache1EnterMutex(p->pGroup);
+-  if( apNew ){
+-    for(i=0; i<p->nHash; i++){
+-      PgHdr1 *pPage;
+-      PgHdr1 *pNext = p->apHash[i];
+-      while( (pPage = pNext)!=0 ){
+-        unsigned int h = pPage->iKey % nNew;
+-        pNext = pPage->pNext;
+-        pPage->pNext = apNew[h];
+-        apNew[h] = pPage;
++  /* Run the program */
++  pc = 0;
++  while( (op = aOp[pc])!=0 ){
++    switch( op ){
++      case 1:
++      case 2:
++      case 5: {
++        nx = 4;
++        i = aOp[pc+2] - 1;
++        aOp[pc+2] += aOp[pc+3];
++        break;
++      }
++      case 3:
++      case 4: 
++      default: {
++        nx = 2;
++        sqlite3_randomness(sizeof(i), &i);
++        break;
+       }
+     }
+-    sqlite3_free(p->apHash);
+-    p->apHash = apNew;
+-    p->nHash = nNew;
++    if( (--aOp[pc+1]) > 0 ) nx = 0;
++    pc += nx;
++    i = (i & 0x7fffffff)%sz;
++    if( (op & 1)!=0 ){
++      SETBIT(pV, (i+1));
++      if( op!=5 ){
++        if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end;
++      }
++    }else{
++      CLEARBIT(pV, (i+1));
++      sqlite3BitvecClear(pBitvec, i+1, pTmpSpace);
++    }
++  }
++
++  /* Test to make sure the linear array exactly matches the
++  ** Bitvec object.  Start with the assumption that they do
++  ** match (rc==0).  Change rc to non-zero if a discrepancy
++  ** is found.
++  */
++  rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1)
++          + sqlite3BitvecTest(pBitvec, 0)
++          + (sqlite3BitvecSize(pBitvec) - sz);
++  for(i=1; i<=sz; i++){
++    if(  (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){
++      rc = i;
++      break;
++    }
+   }
++
++  /* Free allocated structure */
++bitvec_end:
++  sqlite3_free(pTmpSpace);
++  sqlite3_free(pV);
++  sqlite3BitvecDestroy(pBitvec);
++  return rc;
+ }
++#endif /* SQLITE_OMIT_BUILTIN_TEST */
+ 
++/************** End of bitvec.c **********************************************/
++/************** Begin file pcache.c ******************************************/
+ /*
+-** This function is used internally to remove the page pPage from the 
+-** PGroup LRU list, if is part of it. If pPage is not part of the PGroup
+-** LRU list, then this function is a no-op.
++** 2008 August 05
+ **
+-** The PGroup mutex must be held when this function is called.
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++*************************************************************************
++** This file implements that page cache.
+ */
+-static void pcache1PinPage(PgHdr1 *pPage){
+-  PCache1 *pCache;
+-  PGroup *pGroup;
+ 
+-  assert( pPage!=0 );
+-  assert( pPage->isPinned==0 );
+-  pCache = pPage->pCache;
+-  pGroup = pCache->pGroup;
+-  assert( pPage->pLruNext || pPage==pGroup->pLruTail );
+-  assert( pPage->pLruPrev || pPage==pGroup->pLruHead );
+-  assert( sqlite3_mutex_held(pGroup->mutex) );
+-  if( pPage->pLruPrev ){
+-    pPage->pLruPrev->pLruNext = pPage->pLruNext;
+-  }else{
+-    pGroup->pLruHead = pPage->pLruNext;
+-  }
+-  if( pPage->pLruNext ){
+-    pPage->pLruNext->pLruPrev = pPage->pLruPrev;
+-  }else{
+-    pGroup->pLruTail = pPage->pLruPrev;
+-  }
+-  pPage->pLruNext = 0;
+-  pPage->pLruPrev = 0;
+-  pPage->isPinned = 1;
+-  pCache->nRecyclable--;
+-}
++/*
++** A complete page cache is an instance of this structure.
++*/
++struct PCache {
++  PgHdr *pDirty, *pDirtyTail;         /* List of dirty pages in LRU order */
++  PgHdr *pSynced;                     /* Last synced page in dirty page list */
++  int nRef;                           /* Number of referenced pages */
++  int szCache;                        /* Configured cache size */
++  int szPage;                         /* Size of every page in this cache */
++  int szExtra;                        /* Size of extra space for each page */
++  u8 bPurgeable;                      /* True if pages are on backing store */
++  u8 eCreate;                         /* eCreate value for for xFetch() */
++  int (*xStress)(void*,PgHdr*);       /* Call to try make a page clean */
++  void *pStress;                      /* Argument to xStress */
++  sqlite3_pcache *pCache;             /* Pluggable cache module */
++  PgHdr *pPage1;                      /* Reference to page 1 */
++};
++
++/********************************** Linked List Management ********************/
+ 
++/* Allowed values for second argument to pcacheManageDirtyList() */
++#define PCACHE_DIRTYLIST_REMOVE   1    /* Remove pPage from dirty list */
++#define PCACHE_DIRTYLIST_ADD      2    /* Add pPage to the dirty list */
++#define PCACHE_DIRTYLIST_FRONT    3    /* Move pPage to the front of the list */
+ 
+ /*
+-** Remove the page supplied as an argument from the hash table 
+-** (PCache1.apHash structure) that it is currently stored in.
+-**
+-** The PGroup mutex must be held when this function is called.
++** Manage pPage's participation on the dirty list.  Bits of the addRemove
++** argument determines what operation to do.  The 0x01 bit means first
++** remove pPage from the dirty list.  The 0x02 means add pPage back to
++** the dirty list.  Doing both moves pPage to the front of the dirty list.
+ */
+-static void pcache1RemoveFromHash(PgHdr1 *pPage){
+-  unsigned int h;
+-  PCache1 *pCache = pPage->pCache;
+-  PgHdr1 **pp;
+-
+-  assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
+-  h = pPage->iKey % pCache->nHash;
+-  for(pp=&pCache->apHash[h]; (*pp)!=pPage; pp=&(*pp)->pNext);
+-  *pp = (*pp)->pNext;
++static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){
++  PCache *p = pPage->pCache;
+ 
+-  pCache->nPage--;
++  if( addRemove & PCACHE_DIRTYLIST_REMOVE ){
++    assert( pPage->pDirtyNext || pPage==p->pDirtyTail );
++    assert( pPage->pDirtyPrev || pPage==p->pDirty );
++  
++    /* Update the PCache1.pSynced variable if necessary. */
++    if( p->pSynced==pPage ){
++      PgHdr *pSynced = pPage->pDirtyPrev;
++      while( pSynced && (pSynced->flags&PGHDR_NEED_SYNC) ){
++        pSynced = pSynced->pDirtyPrev;
++      }
++      p->pSynced = pSynced;
++    }
++  
++    if( pPage->pDirtyNext ){
++      pPage->pDirtyNext->pDirtyPrev = pPage->pDirtyPrev;
++    }else{
++      assert( pPage==p->pDirtyTail );
++      p->pDirtyTail = pPage->pDirtyPrev;
++    }
++    if( pPage->pDirtyPrev ){
++      pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext;
++    }else{
++      assert( pPage==p->pDirty );
++      p->pDirty = pPage->pDirtyNext;
++      if( p->pDirty==0 && p->bPurgeable ){
++        assert( p->eCreate==1 );
++        p->eCreate = 2;
++      }
++    }
++    pPage->pDirtyNext = 0;
++    pPage->pDirtyPrev = 0;
++  }
++  if( addRemove & PCACHE_DIRTYLIST_ADD ){
++    assert( pPage->pDirtyNext==0 && pPage->pDirtyPrev==0 && p->pDirty!=pPage );
++  
++    pPage->pDirtyNext = p->pDirty;
++    if( pPage->pDirtyNext ){
++      assert( pPage->pDirtyNext->pDirtyPrev==0 );
++      pPage->pDirtyNext->pDirtyPrev = pPage;
++    }else{
++      p->pDirtyTail = pPage;
++      if( p->bPurgeable ){
++        assert( p->eCreate==2 );
++        p->eCreate = 1;
++      }
++    }
++    p->pDirty = pPage;
++    if( !p->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) ){
++      p->pSynced = pPage;
++    }
++  }
+ }
+ 
+ /*
+-** If there are currently more than nMaxPage pages allocated, try
+-** to recycle pages to reduce the number allocated to nMaxPage.
++** Wrapper around the pluggable caches xUnpin method. If the cache is
++** being used for an in-memory database, this function is a no-op.
+ */
+-static void pcache1EnforceMaxPage(PGroup *pGroup){
+-  assert( sqlite3_mutex_held(pGroup->mutex) );
+-  while( pGroup->nCurrentPage>pGroup->nMaxPage && pGroup->pLruTail ){
+-    PgHdr1 *p = pGroup->pLruTail;
+-    assert( p->pCache->pGroup==pGroup );
+-    assert( p->isPinned==0 );
+-    pcache1PinPage(p);
+-    pcache1RemoveFromHash(p);
+-    pcache1FreePage(p);
++static void pcacheUnpin(PgHdr *p){
++  if( p->pCache->bPurgeable ){
++    if( p->pgno==1 ){
++      p->pCache->pPage1 = 0;
++    }
++    sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0);
+   }
+ }
+ 
+ /*
+-** Discard all pages from cache pCache with a page number (key value) 
+-** greater than or equal to iLimit. Any pinned pages that meet this 
+-** criteria are unpinned before they are discarded.
++** Compute the number of pages of cache requested.  p->szCache is the
++** cache size requested by the "PRAGMA cache_size" statement.
++**
+ **
+-** The PCache mutex must be held when this function is called.
+ */
+-static void pcache1TruncateUnsafe(
+-  PCache1 *pCache,             /* The cache to truncate */
+-  unsigned int iLimit          /* Drop pages with this pgno or larger */
+-){
+-  TESTONLY( unsigned int nPage = 0; )  /* To assert pCache->nPage is correct */
+-  unsigned int h;
+-  assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
+-  for(h=0; h<pCache->nHash; h++){
+-    PgHdr1 **pp = &pCache->apHash[h]; 
+-    PgHdr1 *pPage;
+-    while( (pPage = *pp)!=0 ){
+-      if( pPage->iKey>=iLimit ){
+-        pCache->nPage--;
+-        *pp = pPage->pNext;
+-        if( !pPage->isPinned ) pcache1PinPage(pPage);
+-        pcache1FreePage(pPage);
+-      }else{
+-        pp = &pPage->pNext;
+-        TESTONLY( nPage++; )
+-      }
+-    }
++static int numberOfCachePages(PCache *p){
++  if( p->szCache>=0 ){
++    /* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the
++    ** suggested cache size is set to N. */
++    return p->szCache;
++  }else{
++    /* IMPLEMENTATION-OF: R-61436-13639 If the argument N is negative, then
++    ** the number of cache pages is adjusted to use approximately abs(N*1024)
++    ** bytes of memory. */
++    return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
++  }
++}
++
++/*************************************************** General Interfaces ******
++**
++** Initialize and shutdown the page cache subsystem. Neither of these 
++** functions are threadsafe.
++*/
++SQLITE_PRIVATE int sqlite3PcacheInitialize(void){
++  if( sqlite3GlobalConfig.pcache2.xInit==0 ){
++    /* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the
++    ** built-in default page cache is used instead of the application defined
++    ** page cache. */
++    sqlite3PCacheSetDefault();
++  }
++  return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg);
++}
++SQLITE_PRIVATE void sqlite3PcacheShutdown(void){
++  if( sqlite3GlobalConfig.pcache2.xShutdown ){
++    /* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */
++    sqlite3GlobalConfig.pcache2.xShutdown(sqlite3GlobalConfig.pcache2.pArg);
+   }
+-  assert( pCache->nPage==nPage );
+ }
+ 
+-/******************************************************************************/
+-/******** sqlite3_pcache Methods **********************************************/
++/*
++** Return the size in bytes of a PCache object.
++*/
++SQLITE_PRIVATE int sqlite3PcacheSize(void){ return sizeof(PCache); }
+ 
+ /*
+-** Implementation of the sqlite3_pcache.xInit method.
++** Create a new PCache object. Storage space to hold the object
++** has already been allocated and is passed in as the p pointer. 
++** The caller discovers how much space needs to be allocated by 
++** calling sqlite3PcacheSize().
+ */
+-static int pcache1Init(void *NotUsed){
+-  UNUSED_PARAMETER(NotUsed);
+-  assert( pcache1.isInit==0 );
+-  memset(&pcache1, 0, sizeof(pcache1));
+-  if( sqlite3GlobalConfig.bCoreMutex ){
+-    pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU);
+-    pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PMEM);
++SQLITE_PRIVATE int sqlite3PcacheOpen(
++  int szPage,                  /* Size of every page */
++  int szExtra,                 /* Extra space associated with each page */
++  int bPurgeable,              /* True if pages are on backing store */
++  int (*xStress)(void*,PgHdr*),/* Call to try to make pages clean */
++  void *pStress,               /* Argument to xStress */
++  PCache *p                    /* Preallocated space for the PCache */
++){
++  memset(p, 0, sizeof(PCache));
++  p->szPage = 1;
++  p->szExtra = szExtra;
++  p->bPurgeable = bPurgeable;
++  p->eCreate = 2;
++  p->xStress = xStress;
++  p->pStress = pStress;
++  p->szCache = 100;
++  return sqlite3PcacheSetPageSize(p, szPage);
++}
++
++/*
++** Change the page size for PCache object. The caller must ensure that there
++** are no outstanding page references when this function is called.
++*/
++SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){
++  assert( pCache->nRef==0 && pCache->pDirty==0 );
++  if( pCache->szPage ){
++    sqlite3_pcache *pNew;
++    pNew = sqlite3GlobalConfig.pcache2.xCreate(
++                szPage, pCache->szExtra + ROUND8(sizeof(PgHdr)),
++                pCache->bPurgeable
++    );
++    if( pNew==0 ) return SQLITE_NOMEM;
++    sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache));
++    if( pCache->pCache ){
++      sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
++    }
++    pCache->pCache = pNew;
++    pCache->pPage1 = 0;
++    pCache->szPage = szPage;
+   }
+-  pcache1.grp.mxPinned = 10;
+-  pcache1.isInit = 1;
+   return SQLITE_OK;
+ }
+ 
+ /*
+-** Implementation of the sqlite3_pcache.xShutdown method.
+-** Note that the static mutex allocated in xInit does 
+-** not need to be freed.
++** Try to obtain a page from the cache.
++**
++** This routine returns a pointer to an sqlite3_pcache_page object if
++** such an object is already in cache, or if a new one is created.
++** This routine returns a NULL pointer if the object was not in cache
++** and could not be created.
++**
++** The createFlags should be 0 to check for existing pages and should
++** be 3 (not 1, but 3) to try to create a new page.
++**
++** If the createFlag is 0, then NULL is always returned if the page
++** is not already in the cache.  If createFlag is 1, then a new page
++** is created only if that can be done without spilling dirty pages
++** and without exceeding the cache size limit.
++**
++** The caller needs to invoke sqlite3PcacheFetchFinish() to properly
++** initialize the sqlite3_pcache_page object and convert it into a
++** PgHdr object.  The sqlite3PcacheFetch() and sqlite3PcacheFetchFinish()
++** routines are split this way for performance reasons. When separated
++** they can both (usually) operate without having to push values to
++** the stack on entry and pop them back off on exit, which saves a
++** lot of pushing and popping.
+ */
+-static void pcache1Shutdown(void *NotUsed){
+-  UNUSED_PARAMETER(NotUsed);
+-  assert( pcache1.isInit!=0 );
+-  memset(&pcache1, 0, sizeof(pcache1));
+-}
++SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch(
++  PCache *pCache,       /* Obtain the page from this cache */
++  Pgno pgno,            /* Page number to obtain */
++  int createFlag        /* If true, create page if it does not exist already */
++){
++  int eCreate;
+ 
+-/* forward declaration */
+-static void pcache1Destroy(sqlite3_pcache *p);
++  assert( pCache!=0 );
++  assert( pCache->pCache!=0 );
++  assert( createFlag==3 || createFlag==0 );
++  assert( pgno>0 );
++
++  /* eCreate defines what to do if the page does not exist.
++  **    0     Do not allocate a new page.  (createFlag==0)
++  **    1     Allocate a new page if doing so is inexpensive.
++  **          (createFlag==1 AND bPurgeable AND pDirty)
++  **    2     Allocate a new page even it doing so is difficult.
++  **          (createFlag==1 AND !(bPurgeable AND pDirty)
++  */
++  eCreate = createFlag & pCache->eCreate;
++  assert( eCreate==0 || eCreate==1 || eCreate==2 );
++  assert( createFlag==0 || pCache->eCreate==eCreate );
++  assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) );
++  return sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate);
++}
+ 
+ /*
+-** Implementation of the sqlite3_pcache.xCreate method.
++** If the sqlite3PcacheFetch() routine is unable to allocate a new
++** page because new clean pages are available for reuse and the cache
++** size limit has been reached, then this routine can be invoked to 
++** try harder to allocate a page.  This routine might invoke the stress
++** callback to spill dirty pages to the journal.  It will then try to
++** allocate the new page and will only fail to allocate a new page on
++** an OOM error.
+ **
+-** Allocate a new cache.
++** This routine should be invoked only after sqlite3PcacheFetch() fails.
+ */
+-static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
+-  PCache1 *pCache;      /* The newly created page cache */
+-  PGroup *pGroup;       /* The group the new page cache will belong to */
+-  int sz;               /* Bytes of memory required to allocate the new cache */
++SQLITE_PRIVATE int sqlite3PcacheFetchStress(
++  PCache *pCache,                 /* Obtain the page from this cache */
++  Pgno pgno,                      /* Page number to obtain */
++  sqlite3_pcache_page **ppPage    /* Write result here */
++){
++  PgHdr *pPg;
++  if( pCache->eCreate==2 ) return 0;
+ 
+-  /*
+-  ** The separateCache variable is true if each PCache has its own private
+-  ** PGroup.  In other words, separateCache is true for mode (1) where no
+-  ** mutexing is required.
+-  **
+-  **   *  Always use a unified cache (mode-2) if ENABLE_MEMORY_MANAGEMENT
+-  **
+-  **   *  Always use a unified cache in single-threaded applications
+-  **
+-  **   *  Otherwise (if multi-threaded and ENABLE_MEMORY_MANAGEMENT is off)
+-  **      use separate caches (mode-1)
++
++  /* Find a dirty page to write-out and recycle. First try to find a 
++  ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC
++  ** cleared), but if that is not possible settle for any other 
++  ** unreferenced dirty page.
+   */
+-#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || SQLITE_THREADSAFE==0
+-  const int separateCache = 0;
+-#else
+-  int separateCache = sqlite3GlobalConfig.bCoreMutex>0;
++  for(pPg=pCache->pSynced; 
++      pPg && (pPg->nRef || (pPg->flags&PGHDR_NEED_SYNC)); 
++      pPg=pPg->pDirtyPrev
++  );
++  pCache->pSynced = pPg;
++  if( !pPg ){
++    for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev);
++  }
++  if( pPg ){
++    int rc;
++#ifdef SQLITE_LOG_CACHE_SPILL
++    sqlite3_log(SQLITE_FULL, 
++                "spill page %d making room for %d - cache used: %d/%d",
++                pPg->pgno, pgno,
++                sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache),
++                numberOfCachePages(pCache));
+ #endif
+-
+-  assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 );
+-  assert( szExtra < 300 );
+-
+-  sz = sizeof(PCache1) + sizeof(PGroup)*separateCache;
+-  pCache = (PCache1 *)sqlite3MallocZero(sz);
+-  if( pCache ){
+-    if( separateCache ){
+-      pGroup = (PGroup*)&pCache[1];
+-      pGroup->mxPinned = 10;
+-    }else{
+-      pGroup = &pcache1.grp;
+-    }
+-    pCache->pGroup = pGroup;
+-    pCache->szPage = szPage;
+-    pCache->szExtra = szExtra;
+-    pCache->bPurgeable = (bPurgeable ? 1 : 0);
+-    pcache1EnterMutex(pGroup);
+-    pcache1ResizeHash(pCache);
+-    if( bPurgeable ){
+-      pCache->nMin = 10;
+-      pGroup->nMinPage += pCache->nMin;
+-      pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
+-    }
+-    pcache1LeaveMutex(pGroup);
+-    if( pCache->nHash==0 ){
+-      pcache1Destroy((sqlite3_pcache*)pCache);
+-      pCache = 0;
++    rc = pCache->xStress(pCache->pStress, pPg);
++    if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
++      return rc;
+     }
+   }
+-  return (sqlite3_pcache *)pCache;
++  *ppPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2);
++  return *ppPage==0 ? SQLITE_NOMEM : SQLITE_OK;
+ }
+ 
+ /*
+-** Implementation of the sqlite3_pcache.xCachesize method. 
++** This is a helper routine for sqlite3PcacheFetchFinish()
+ **
+-** Configure the cache_size limit for a cache.
++** In the uncommon case where the page being fetched has not been
++** initialized, this routine is invoked to do the initialization.
++** This routine is broken out into a separate function since it
++** requires extra stack manipulation that can be avoided in the common
++** case.
+ */
+-static void pcache1Cachesize(sqlite3_pcache *p, int nMax){
+-  PCache1 *pCache = (PCache1 *)p;
+-  if( pCache->bPurgeable ){
+-    PGroup *pGroup = pCache->pGroup;
+-    pcache1EnterMutex(pGroup);
+-    pGroup->nMaxPage += (nMax - pCache->nMax);
+-    pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
+-    pCache->nMax = nMax;
+-    pCache->n90pct = pCache->nMax*9/10;
+-    pcache1EnforceMaxPage(pGroup);
+-    pcache1LeaveMutex(pGroup);
+-  }
++static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit(
++  PCache *pCache,             /* Obtain the page from this cache */
++  Pgno pgno,                  /* Page number obtained */
++  sqlite3_pcache_page *pPage  /* Page obtained by prior PcacheFetch() call */
++){
++  PgHdr *pPgHdr;
++  assert( pPage!=0 );
++  pPgHdr = (PgHdr*)pPage->pExtra;
++  assert( pPgHdr->pPage==0 );
++ memset(pPgHdr, 0, sizeof(PgHdr));
++  pPgHdr->pPage = pPage;
++  pPgHdr->pData = pPage->pBuf;
++  pPgHdr->pExtra = (void *)&pPgHdr[1];
++  memset(pPgHdr->pExtra, 0, pCache->szExtra);
++  pPgHdr->pCache = pCache;
++  pPgHdr->pgno = pgno;
++  return sqlite3PcacheFetchFinish(pCache,pgno,pPage);
+ }
+ 
+ /*
+-** Implementation of the sqlite3_pcache.xShrink method. 
+-**
+-** Free up as much memory as possible.
++** This routine converts the sqlite3_pcache_page object returned by
++** sqlite3PcacheFetch() into an initialized PgHdr object.  This routine
++** must be called after sqlite3PcacheFetch() in order to get a usable
++** result.
+ */
+-static void pcache1Shrink(sqlite3_pcache *p){
+-  PCache1 *pCache = (PCache1*)p;
+-  if( pCache->bPurgeable ){
+-    PGroup *pGroup = pCache->pGroup;
+-    int savedMaxPage;
+-    pcache1EnterMutex(pGroup);
+-    savedMaxPage = pGroup->nMaxPage;
+-    pGroup->nMaxPage = 0;
+-    pcache1EnforceMaxPage(pGroup);
+-    pGroup->nMaxPage = savedMaxPage;
+-    pcache1LeaveMutex(pGroup);
++SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish(
++  PCache *pCache,             /* Obtain the page from this cache */
++  Pgno pgno,                  /* Page number obtained */
++  sqlite3_pcache_page *pPage  /* Page obtained by prior PcacheFetch() call */
++){
++  PgHdr *pPgHdr;
++
++  if( pPage==0 ) return 0;
++  pPgHdr = (PgHdr *)pPage->pExtra;
++
++  if( !pPgHdr->pPage ){
++    return pcacheFetchFinishWithInit(pCache, pgno, pPage);
++  }
++  if( 0==pPgHdr->nRef ){
++    pCache->nRef++;
++  }
++  pPgHdr->nRef++;
++  if( pgno==1 ){
++    pCache->pPage1 = pPgHdr;
+   }
++  return pPgHdr;
+ }
+ 
+ /*
+-** Implementation of the sqlite3_pcache.xPagecount method. 
++** Decrement the reference count on a page. If the page is clean and the
++** reference count drops to 0, then it is made eligible for recycling.
+ */
+-static int pcache1Pagecount(sqlite3_pcache *p){
+-  int n;
+-  PCache1 *pCache = (PCache1*)p;
+-  pcache1EnterMutex(pCache->pGroup);
+-  n = pCache->nPage;
+-  pcache1LeaveMutex(pCache->pGroup);
+-  return n;
++SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){
++  assert( p->nRef>0 );
++  p->nRef--;
++  if( p->nRef==0 ){
++    p->pCache->nRef--;
++    if( (p->flags&PGHDR_DIRTY)==0 ){
++      pcacheUnpin(p);
++    }else if( p->pDirtyPrev!=0 ){
++      /* Move the page to the head of the dirty list. */
++      pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
++    }
++  }
+ }
+ 
+-
+ /*
+-** Implement steps 3, 4, and 5 of the pcache1Fetch() algorithm described
+-** in the header of the pcache1Fetch() procedure.
+-**
+-** This steps are broken out into a separate procedure because they are
+-** usually not needed, and by avoiding the stack initialization required
+-** for these steps, the main pcache1Fetch() procedure can run faster.
++** Increase the reference count of a supplied page by 1.
+ */
+-static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2(
+-  PCache1 *pCache, 
+-  unsigned int iKey, 
+-  int createFlag
+-){
+-  unsigned int nPinned;
+-  PGroup *pGroup = pCache->pGroup;
+-  PgHdr1 *pPage = 0;
++SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr *p){
++  assert(p->nRef>0);
++  p->nRef++;
++}
+ 
+-  /* Step 3: Abort if createFlag is 1 but the cache is nearly full */
+-  assert( pCache->nPage >= pCache->nRecyclable );
+-  nPinned = pCache->nPage - pCache->nRecyclable;
+-  assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage );
+-  assert( pCache->n90pct == pCache->nMax*9/10 );
+-  if( createFlag==1 && (
+-        nPinned>=pGroup->mxPinned
+-     || nPinned>=pCache->n90pct
+-     || (pcache1UnderMemoryPressure(pCache) && pCache->nRecyclable<nPinned)
+-  )){
+-    return 0;
++/*
++** Drop a page from the cache. There must be exactly one reference to the
++** page. This function deletes that reference, so after it returns the
++** page pointed to by p is invalid.
++*/
++SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){
++  assert( p->nRef==1 );
++  if( p->flags&PGHDR_DIRTY ){
++    pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
+   }
+-
+-  if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache);
+-  assert( pCache->nHash>0 && pCache->apHash );
+-
+-  /* Step 4. Try to recycle a page. */
+-  if( pCache->bPurgeable && pGroup->pLruTail && (
+-         (pCache->nPage+1>=pCache->nMax)
+-      || pGroup->nCurrentPage>=pGroup->nMaxPage
+-      || pcache1UnderMemoryPressure(pCache)
+-  )){
+-    PCache1 *pOther;
+-    pPage = pGroup->pLruTail;
+-    assert( pPage->isPinned==0 );
+-    pcache1RemoveFromHash(pPage);
+-    pcache1PinPage(pPage);
+-    pOther = pPage->pCache;
+-
+-    /* We want to verify that szPage and szExtra are the same for pOther
+-    ** and pCache.  Assert that we can verify this by comparing sums. */
+-    assert( (pCache->szPage & (pCache->szPage-1))==0 && pCache->szPage>=512 );
+-    assert( pCache->szExtra<512 );
+-    assert( (pOther->szPage & (pOther->szPage-1))==0 && pOther->szPage>=512 );
+-    assert( pOther->szExtra<512 );
+-
+-    if( pOther->szPage+pOther->szExtra != pCache->szPage+pCache->szExtra ){
+-      pcache1FreePage(pPage);
+-      pPage = 0;
+-    }else{
+-      pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable);
+-    }
++  p->pCache->nRef--;
++  if( p->pgno==1 ){
++    p->pCache->pPage1 = 0;
+   }
++  sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 1);
++}
+ 
+-  /* Step 5. If a usable page buffer has still not been found, 
+-  ** attempt to allocate a new one. 
+-  */
+-  if( !pPage ){
+-    if( createFlag==1 ) sqlite3BeginBenignMalloc();
+-    pPage = pcache1AllocPage(pCache);
+-    if( createFlag==1 ) sqlite3EndBenignMalloc();
++/*
++** Make sure the page is marked as dirty. If it isn't dirty already,
++** make it so.
++*/
++SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){
++  p->flags &= ~PGHDR_DONT_WRITE;
++  assert( p->nRef>0 );
++  if( 0==(p->flags & PGHDR_DIRTY) ){
++    p->flags |= PGHDR_DIRTY;
++    pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD);
+   }
++}
+ 
+-  if( pPage ){
+-    unsigned int h = iKey % pCache->nHash;
+-    pCache->nPage++;
+-    pPage->iKey = iKey;
+-    pPage->pNext = pCache->apHash[h];
+-    pPage->pCache = pCache;
+-    pPage->pLruPrev = 0;
+-    pPage->pLruNext = 0;
+-    pPage->isPinned = 1;
+-    *(void **)pPage->page.pExtra = 0;
+-    pCache->apHash[h] = pPage;
+-    if( iKey>pCache->iMaxKey ){
+-      pCache->iMaxKey = iKey;
++/*
++** Make sure the page is marked as clean. If it isn't clean already,
++** make it so.
++*/
++SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){
++  if( (p->flags & PGHDR_DIRTY) ){
++    pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE);
++    p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC);
++    if( p->nRef==0 ){
++      pcacheUnpin(p);
+     }
+   }
+-  return pPage;
+ }
+ 
+ /*
+-** Implementation of the sqlite3_pcache.xFetch method. 
+-**
+-** Fetch a page by key value.
+-**
+-** Whether or not a new page may be allocated by this function depends on
+-** the value of the createFlag argument.  0 means do not allocate a new
+-** page.  1 means allocate a new page if space is easily available.  2 
+-** means to try really hard to allocate a new page.
+-**
+-** For a non-purgeable cache (a cache used as the storage for an in-memory
+-** database) there is really no difference between createFlag 1 and 2.  So
+-** the calling function (pcache.c) will never have a createFlag of 1 on
+-** a non-purgeable cache.
+-**
+-** There are three different approaches to obtaining space for a page,
+-** depending on the value of parameter createFlag (which may be 0, 1 or 2).
+-**
+-**   1. Regardless of the value of createFlag, the cache is searched for a 
+-**      copy of the requested page. If one is found, it is returned.
+-**
+-**   2. If createFlag==0 and the page is not already in the cache, NULL is
+-**      returned.
+-**
+-**   3. If createFlag is 1, and the page is not already in the cache, then
+-**      return NULL (do not allocate a new page) if any of the following
+-**      conditions are true:
+-**
+-**       (a) the number of pages pinned by the cache is greater than
+-**           PCache1.nMax, or
+-**
+-**       (b) the number of pages pinned by the cache is greater than
+-**           the sum of nMax for all purgeable caches, less the sum of 
+-**           nMin for all other purgeable caches, or
+-**
+-**   4. If none of the first three conditions apply and the cache is marked
+-**      as purgeable, and if one of the following is true:
+-**
+-**       (a) The number of pages allocated for the cache is already 
+-**           PCache1.nMax, or
+-**
+-**       (b) The number of pages allocated for all purgeable caches is
+-**           already equal to or greater than the sum of nMax for all
+-**           purgeable caches,
+-**
+-**       (c) The system is under memory pressure and wants to avoid
+-**           unnecessary pages cache entry allocations
+-**
+-**      then attempt to recycle a page from the LRU list. If it is the right
+-**      size, return the recycled buffer. Otherwise, free the buffer and
+-**      proceed to step 5. 
+-**
+-**   5. Otherwise, allocate and return a new page buffer.
++** Make every page in the cache clean.
+ */
+-static sqlite3_pcache_page *pcache1Fetch(
+-  sqlite3_pcache *p, 
+-  unsigned int iKey, 
+-  int createFlag
+-){
+-  PCache1 *pCache = (PCache1 *)p;
+-  PgHdr1 *pPage = 0;
+-
+-  assert( offsetof(PgHdr1,page)==0 );
+-  assert( pCache->bPurgeable || createFlag!=1 );
+-  assert( pCache->bPurgeable || pCache->nMin==0 );
+-  assert( pCache->bPurgeable==0 || pCache->nMin==10 );
+-  assert( pCache->nMin==0 || pCache->bPurgeable );
+-  assert( pCache->nHash>0 );
+-  pcache1EnterMutex(pCache->pGroup);
+-
+-  /* Step 1: Search the hash table for an existing entry. */
+-  pPage = pCache->apHash[iKey % pCache->nHash];
+-  while( pPage && pPage->iKey!=iKey ){ pPage = pPage->pNext; }
++SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache *pCache){
++  PgHdr *p;
++  while( (p = pCache->pDirty)!=0 ){
++    sqlite3PcacheMakeClean(p);
++  }
++}
+ 
+-  /* Step 2: Abort if no existing page is found and createFlag is 0 */
+-  if( pPage ){
+-    if( !pPage->isPinned ) pcache1PinPage(pPage);
+-  }else if( createFlag ){
+-    /* Steps 3, 4, and 5 implemented by this subroutine */
+-    pPage = pcache1FetchStage2(pCache, iKey, createFlag);
++/*
++** Clear the PGHDR_NEED_SYNC flag from all dirty pages.
++*/
++SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *pCache){
++  PgHdr *p;
++  for(p=pCache->pDirty; p; p=p->pDirtyNext){
++    p->flags &= ~PGHDR_NEED_SYNC;
+   }
+-  assert( pPage==0 || pCache->iMaxKey>=iKey );
+-  pcache1LeaveMutex(pCache->pGroup);
+-  return (sqlite3_pcache_page*)pPage;
++  pCache->pSynced = pCache->pDirtyTail;
+ }
+ 
++/*
++** Change the page number of page p to newPgno. 
++*/
++SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){
++  PCache *pCache = p->pCache;
++  assert( p->nRef>0 );
++  assert( newPgno>0 );
++  sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno);
++  p->pgno = newPgno;
++  if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){
++    pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT);
++  }
++}
+ 
+ /*
+-** Implementation of the sqlite3_pcache.xUnpin method.
++** Drop every cache entry whose page number is greater than "pgno". The
++** caller must ensure that there are no outstanding references to any pages
++** other than page 1 with a page number greater than pgno.
+ **
+-** Mark a page as unpinned (eligible for asynchronous recycling).
++** If there is a reference to page 1 and the pgno parameter passed to this
++** function is 0, then the data area associated with page 1 is zeroed, but
++** the page object is not dropped.
+ */
+-static void pcache1Unpin(
+-  sqlite3_pcache *p, 
+-  sqlite3_pcache_page *pPg, 
+-  int reuseUnlikely
+-){
+-  PCache1 *pCache = (PCache1 *)p;
+-  PgHdr1 *pPage = (PgHdr1 *)pPg;
+-  PGroup *pGroup = pCache->pGroup;
+- 
+-  assert( pPage->pCache==pCache );
+-  pcache1EnterMutex(pGroup);
+-
+-  /* It is an error to call this function if the page is already 
+-  ** part of the PGroup LRU list.
+-  */
+-  assert( pPage->pLruPrev==0 && pPage->pLruNext==0 );
+-  assert( pGroup->pLruHead!=pPage && pGroup->pLruTail!=pPage );
+-  assert( pPage->isPinned==1 );
+-
+-  if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){
+-    pcache1RemoveFromHash(pPage);
+-    pcache1FreePage(pPage);
+-  }else{
+-    /* Add the page to the PGroup LRU list. */
+-    if( pGroup->pLruHead ){
+-      pGroup->pLruHead->pLruPrev = pPage;
+-      pPage->pLruNext = pGroup->pLruHead;
+-      pGroup->pLruHead = pPage;
+-    }else{
+-      pGroup->pLruTail = pPage;
+-      pGroup->pLruHead = pPage;
++SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){
++  if( pCache->pCache ){
++    PgHdr *p;
++    PgHdr *pNext;
++    for(p=pCache->pDirty; p; p=pNext){
++      pNext = p->pDirtyNext;
++      /* This routine never gets call with a positive pgno except right
++      ** after sqlite3PcacheCleanAll().  So if there are dirty pages,
++      ** it must be that pgno==0.
++      */
++      assert( p->pgno>0 );
++      if( ALWAYS(p->pgno>pgno) ){
++        assert( p->flags&PGHDR_DIRTY );
++        sqlite3PcacheMakeClean(p);
++      }
+     }
+-    pCache->nRecyclable++;
+-    pPage->isPinned = 0;
++    if( pgno==0 && pCache->pPage1 ){
++      memset(pCache->pPage1->pData, 0, pCache->szPage);
++      pgno = 1;
++    }
++    sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1);
+   }
+-
+-  pcache1LeaveMutex(pCache->pGroup);
+ }
+ 
+ /*
+-** Implementation of the sqlite3_pcache.xRekey method. 
++** Close a cache.
+ */
+-static void pcache1Rekey(
+-  sqlite3_pcache *p,
+-  sqlite3_pcache_page *pPg,
+-  unsigned int iOld,
+-  unsigned int iNew
+-){
+-  PCache1 *pCache = (PCache1 *)p;
+-  PgHdr1 *pPage = (PgHdr1 *)pPg;
+-  PgHdr1 **pp;
+-  unsigned int h; 
+-  assert( pPage->iKey==iOld );
+-  assert( pPage->pCache==pCache );
++SQLITE_PRIVATE void sqlite3PcacheClose(PCache *pCache){
++  assert( pCache->pCache!=0 );
++  sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache);
++}
+ 
+-  pcache1EnterMutex(pCache->pGroup);
++/* 
++** Discard the contents of the cache.
++*/
++SQLITE_PRIVATE void sqlite3PcacheClear(PCache *pCache){
++  sqlite3PcacheTruncate(pCache, 0);
++}
+ 
+-  h = iOld%pCache->nHash;
+-  pp = &pCache->apHash[h];
+-  while( (*pp)!=pPage ){
+-    pp = &(*pp)->pNext;
++/*
++** Merge two lists of pages connected by pDirty and in pgno order.
++** Do not both fixing the pDirtyPrev pointers.
++*/
++static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){
++  PgHdr result, *pTail;
++  pTail = &result;
++  while( pA && pB ){
++    if( pA->pgno<pB->pgno ){
++      pTail->pDirty = pA;
++      pTail = pA;
++      pA = pA->pDirty;
++    }else{
++      pTail->pDirty = pB;
++      pTail = pB;
++      pB = pB->pDirty;
++    }
+   }
+-  *pp = pPage->pNext;
+-
+-  h = iNew%pCache->nHash;
+-  pPage->iKey = iNew;
+-  pPage->pNext = pCache->apHash[h];
+-  pCache->apHash[h] = pPage;
+-  if( iNew>pCache->iMaxKey ){
+-    pCache->iMaxKey = iNew;
++  if( pA ){
++    pTail->pDirty = pA;
++  }else if( pB ){
++    pTail->pDirty = pB;
++  }else{
++    pTail->pDirty = 0;
+   }
+-
+-  pcache1LeaveMutex(pCache->pGroup);
++  return result.pDirty;
+ }
+ 
+ /*
+-** Implementation of the sqlite3_pcache.xTruncate method. 
++** Sort the list of pages in accending order by pgno.  Pages are
++** connected by pDirty pointers.  The pDirtyPrev pointers are
++** corrupted by this sort.
+ **
+-** Discard all unpinned pages in the cache with a page number equal to
+-** or greater than parameter iLimit. Any pinned pages with a page number
+-** equal to or greater than iLimit are implicitly unpinned.
++** Since there cannot be more than 2^31 distinct pages in a database,
++** there cannot be more than 31 buckets required by the merge sorter.
++** One extra bucket is added to catch overflow in case something
++** ever changes to make the previous sentence incorrect.
+ */
+-static void pcache1Truncate(sqlite3_pcache *p, unsigned int iLimit){
+-  PCache1 *pCache = (PCache1 *)p;
+-  pcache1EnterMutex(pCache->pGroup);
+-  if( iLimit<=pCache->iMaxKey ){
+-    pcache1TruncateUnsafe(pCache, iLimit);
+-    pCache->iMaxKey = iLimit-1;
++#define N_SORT_BUCKET  32
++static PgHdr *pcacheSortDirtyList(PgHdr *pIn){
++  PgHdr *a[N_SORT_BUCKET], *p;
++  int i;
++  memset(a, 0, sizeof(a));
++  while( pIn ){
++    p = pIn;
++    pIn = p->pDirty;
++    p->pDirty = 0;
++    for(i=0; ALWAYS(i<N_SORT_BUCKET-1); i++){
++      if( a[i]==0 ){
++        a[i] = p;
++        break;
++      }else{
++        p = pcacheMergeDirtyList(a[i], p);
++        a[i] = 0;
++      }
++    }
++    if( NEVER(i==N_SORT_BUCKET-1) ){
++      /* To get here, there need to be 2^(N_SORT_BUCKET) elements in
++      ** the input list.  But that is impossible.
++      */
++      a[i] = pcacheMergeDirtyList(a[i], p);
++    }
+   }
+-  pcache1LeaveMutex(pCache->pGroup);
++  p = a[0];
++  for(i=1; i<N_SORT_BUCKET; i++){
++    p = pcacheMergeDirtyList(p, a[i]);
++  }
++  return p;
+ }
+ 
+ /*
+-** Implementation of the sqlite3_pcache.xDestroy method. 
+-**
+-** Destroy a cache allocated using pcache1Create().
++** Return a list of all dirty pages in the cache, sorted by page number.
+ */
+-static void pcache1Destroy(sqlite3_pcache *p){
+-  PCache1 *pCache = (PCache1 *)p;
+-  PGroup *pGroup = pCache->pGroup;
+-  assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) );
+-  pcache1EnterMutex(pGroup);
+-  pcache1TruncateUnsafe(pCache, 0);
+-  assert( pGroup->nMaxPage >= pCache->nMax );
+-  pGroup->nMaxPage -= pCache->nMax;
+-  assert( pGroup->nMinPage >= pCache->nMin );
+-  pGroup->nMinPage -= pCache->nMin;
+-  pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
+-  pcache1EnforceMaxPage(pGroup);
+-  pcache1LeaveMutex(pGroup);
+-  sqlite3_free(pCache->apHash);
+-  sqlite3_free(pCache);
++SQLITE_PRIVATE PgHdr *sqlite3PcacheDirtyList(PCache *pCache){
++  PgHdr *p;
++  for(p=pCache->pDirty; p; p=p->pDirtyNext){
++    p->pDirty = p->pDirtyNext;
++  }
++  return pcacheSortDirtyList(pCache->pDirty);
++}
++
++/* 
++** Return the total number of referenced pages held by the cache.
++*/
++SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache *pCache){
++  return pCache->nRef;
+ }
+ 
+ /*
+-** This function is called during initialization (sqlite3_initialize()) to
+-** install the default pluggable cache module, assuming the user has not
+-** already provided an alternative.
++** Return the number of references to the page supplied as an argument.
+ */
+-SQLITE_PRIVATE void sqlite3PCacheSetDefault(void){
+-  static const sqlite3_pcache_methods2 defaultMethods = {
+-    1,                       /* iVersion */
+-    0,                       /* pArg */
+-    pcache1Init,             /* xInit */
+-    pcache1Shutdown,         /* xShutdown */
+-    pcache1Create,           /* xCreate */
+-    pcache1Cachesize,        /* xCachesize */
+-    pcache1Pagecount,        /* xPagecount */
+-    pcache1Fetch,            /* xFetch */
+-    pcache1Unpin,            /* xUnpin */
+-    pcache1Rekey,            /* xRekey */
+-    pcache1Truncate,         /* xTruncate */
+-    pcache1Destroy,          /* xDestroy */
+-    pcache1Shrink            /* xShrink */
+-  };
+-  sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods);
++SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr *p){
++  return p->nRef;
++}
++
++/* 
++** Return the total number of pages in the cache.
++*/
++SQLITE_PRIVATE int sqlite3PcachePagecount(PCache *pCache){
++  assert( pCache->pCache!=0 );
++  return sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache);
+ }
+ 
++#ifdef SQLITE_TEST
+ /*
+-** Return the size of the header on each page of this PCACHE implementation.
++** Get the suggested cache-size value.
+ */
+-SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void){ return ROUND8(sizeof(PgHdr1)); }
++SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *pCache){
++  return numberOfCachePages(pCache);
++}
++#endif
+ 
+ /*
+-** Return the global mutex used by this PCACHE implementation.  The
+-** sqlite3_status() routine needs access to this mutex.
++** Set the suggested cache-size value.
+ */
+-SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void){
+-  return pcache1.mutex;
++SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){
++  assert( pCache->pCache!=0 );
++  pCache->szCache = mxPage;
++  sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache,
++                                         numberOfCachePages(pCache));
+ }
+ 
+-#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+ /*
+-** This function is called to free superfluous dynamically allocated memory
+-** held by the pager system. Memory in use by any SQLite pager allocated
+-** by the current thread may be sqlite3_free()ed.
+-**
+-** nReq is the number of bytes of memory required. Once this much has
+-** been released, the function returns. The return value is the total number 
+-** of bytes of memory released.
++** Free up as much memory as possible from the page cache.
+ */
+-SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){
+-  int nFree = 0;
+-  assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
+-  assert( sqlite3_mutex_notheld(pcache1.mutex) );
+-  if( pcache1.pStart==0 ){
+-    PgHdr1 *p;
+-    pcache1EnterMutex(&pcache1.grp);
+-    while( (nReq<0 || nFree<nReq) && ((p=pcache1.grp.pLruTail)!=0) ){
+-      nFree += pcache1MemSize(p->page.pBuf);
+-#ifdef SQLITE_PCACHE_SEPARATE_HEADER
+-      nFree += sqlite3MemSize(p);
+-#endif
+-      assert( p->isPinned==0 );
+-      pcache1PinPage(p);
+-      pcache1RemoveFromHash(p);
+-      pcache1FreePage(p);
+-    }
+-    pcache1LeaveMutex(&pcache1.grp);
+-  }
+-  return nFree;
++SQLITE_PRIVATE void sqlite3PcacheShrink(PCache *pCache){
++  assert( pCache->pCache!=0 );
++  sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache);
+ }
+-#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
+ 
+-#ifdef SQLITE_TEST
+ /*
+-** This function is used by test procedures to inspect the internal state
+-** of the global cache.
++** Return the size of the header added by this middleware layer
++** in the page-cache hierarchy.
+ */
+-SQLITE_PRIVATE void sqlite3PcacheStats(
+-  int *pnCurrent,      /* OUT: Total number of pages cached */
+-  int *pnMax,          /* OUT: Global maximum cache size */
+-  int *pnMin,          /* OUT: Sum of PCache1.nMin for purgeable caches */
+-  int *pnRecyclable    /* OUT: Total number of pages available for recycling */
+-){
+-  PgHdr1 *p;
+-  int nRecyclable = 0;
+-  for(p=pcache1.grp.pLruHead; p; p=p->pLruNext){
+-    assert( p->isPinned==0 );
+-    nRecyclable++;
++SQLITE_PRIVATE int sqlite3HeaderSizePcache(void){ return ROUND8(sizeof(PgHdr)); }
++
++
++#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG)
++/*
++** For all dirty pages currently in the cache, invoke the specified
++** callback. This is only used if the SQLITE_CHECK_PAGES macro is
++** defined.
++*/
++SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)){
++  PgHdr *pDirty;
++  for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext){
++    xIter(pDirty);
+   }
+-  *pnCurrent = pcache1.grp.nCurrentPage;
+-  *pnMax = (int)pcache1.grp.nMaxPage;
+-  *pnMin = (int)pcache1.grp.nMinPage;
+-  *pnRecyclable = nRecyclable;
+ }
+ #endif
+ 
+-/************** End of pcache1.c *********************************************/
+-/************** Begin file rowset.c ******************************************/
++/************** End of pcache.c **********************************************/
++/************** Begin file pcache1.c *****************************************/
+ /*
+-** 2008 December 3
++** 2008 November 05
+ **
+ ** The author disclaims copyright to this source code.  In place of
+ ** a legal notice, here is a blessing:
+@@ -40991,11779 +43568,12180 @@
+ **
+ *************************************************************************
+ **
+-** This module implements an object we call a "RowSet".
+-**
+-** The RowSet object is a collection of rowids.  Rowids
+-** are inserted into the RowSet in an arbitrary order.  Inserts
+-** can be intermixed with tests to see if a given rowid has been
+-** previously inserted into the RowSet.
+-**
+-** After all inserts are finished, it is possible to extract the
+-** elements of the RowSet in sorted order.  Once this extraction
+-** process has started, no new elements may be inserted.
+-**
+-** Hence, the primitive operations for a RowSet are:
+-**
+-**    CREATE
+-**    INSERT
+-**    TEST
+-**    SMALLEST
+-**    DESTROY
++** This file implements the default page cache implementation (the
++** sqlite3_pcache interface). It also contains part of the implementation
++** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features.
++** If the default page cache implementation is overridden, then neither of
++** these two features are available.
++*/
++
++
++typedef struct PCache1 PCache1;
++typedef struct PgHdr1 PgHdr1;
++typedef struct PgFreeslot PgFreeslot;
++typedef struct PGroup PGroup;
++
++/* Each page cache (or PCache) belongs to a PGroup.  A PGroup is a set 
++** of one or more PCaches that are able to recycle each other's unpinned
++** pages when they are under memory pressure.  A PGroup is an instance of
++** the following object.
+ **
+-** The CREATE and DESTROY primitives are the constructor and destructor,
+-** obviously.  The INSERT primitive adds a new element to the RowSet.
+-** TEST checks to see if an element is already in the RowSet.  SMALLEST
+-** extracts the least value from the RowSet.
++** This page cache implementation works in one of two modes:
+ **
+-** The INSERT primitive might allocate additional memory.  Memory is
+-** allocated in chunks so most INSERTs do no allocation.  There is an 
+-** upper bound on the size of allocated memory.  No memory is freed
+-** until DESTROY.
++**   (1)  Every PCache is the sole member of its own PGroup.  There is
++**        one PGroup per PCache.
+ **
+-** The TEST primitive includes a "batch" number.  The TEST primitive
+-** will only see elements that were inserted before the last change
+-** in the batch number.  In other words, if an INSERT occurs between
+-** two TESTs where the TESTs have the same batch nubmer, then the
+-** value added by the INSERT will not be visible to the second TEST.
+-** The initial batch number is zero, so if the very first TEST contains
+-** a non-zero batch number, it will see all prior INSERTs.
++**   (2)  There is a single global PGroup that all PCaches are a member
++**        of.
+ **
+-** No INSERTs may occurs after a SMALLEST.  An assertion will fail if
+-** that is attempted.
++** Mode 1 uses more memory (since PCache instances are not able to rob
++** unused pages from other PCaches) but it also operates without a mutex,
++** and is therefore often faster.  Mode 2 requires a mutex in order to be
++** threadsafe, but recycles pages more efficiently.
+ **
+-** The cost of an INSERT is roughly constant.  (Sometimes new memory
+-** has to be allocated on an INSERT.)  The cost of a TEST with a new
+-** batch number is O(NlogN) where N is the number of elements in the RowSet.
+-** The cost of a TEST using the same batch number is O(logN).  The cost
+-** of the first SMALLEST is O(NlogN).  Second and subsequent SMALLEST
+-** primitives are constant time.  The cost of DESTROY is O(N).
++** For mode (1), PGroup.mutex is NULL.  For mode (2) there is only a single
++** PGroup which is the pcache1.grp global variable and its mutex is
++** SQLITE_MUTEX_STATIC_LRU.
++*/
++struct PGroup {
++  sqlite3_mutex *mutex;          /* MUTEX_STATIC_LRU or NULL */
++  unsigned int nMaxPage;         /* Sum of nMax for purgeable caches */
++  unsigned int nMinPage;         /* Sum of nMin for purgeable caches */
++  unsigned int mxPinned;         /* nMaxpage + 10 - nMinPage */
++  unsigned int nCurrentPage;     /* Number of purgeable pages allocated */
++  PgHdr1 *pLruHead, *pLruTail;   /* LRU list of unpinned pages */
++};
++
++/* Each page cache is an instance of the following object.  Every
++** open database file (including each in-memory database and each
++** temporary or transient database) has a single page cache which
++** is an instance of this object.
+ **
+-** There is an added cost of O(N) when switching between TEST and
+-** SMALLEST primitives.
++** Pointers to structures of this type are cast and returned as 
++** opaque sqlite3_pcache* handles.
+ */
++struct PCache1 {
++  /* Cache configuration parameters. Page size (szPage) and the purgeable
++  ** flag (bPurgeable) are set when the cache is created. nMax may be 
++  ** modified at any time by a call to the pcache1Cachesize() method.
++  ** The PGroup mutex must be held when accessing nMax.
++  */
++  PGroup *pGroup;                     /* PGroup this cache belongs to */
++  int szPage;                         /* Size of allocated pages in bytes */
++  int szExtra;                        /* Size of extra space in bytes */
++  int bPurgeable;                     /* True if cache is purgeable */
++  unsigned int nMin;                  /* Minimum number of pages reserved */
++  unsigned int nMax;                  /* Configured "cache_size" value */
++  unsigned int n90pct;                /* nMax*9/10 */
++  unsigned int iMaxKey;               /* Largest key seen since xTruncate() */
+ 
++  /* Hash table of all pages. The following variables may only be accessed
++  ** when the accessor is holding the PGroup mutex.
++  */
++  unsigned int nRecyclable;           /* Number of pages in the LRU list */
++  unsigned int nPage;                 /* Total number of pages in apHash */
++  unsigned int nHash;                 /* Number of slots in apHash[] */
++  PgHdr1 **apHash;                    /* Hash table for fast lookup by key */
++};
+ 
+ /*
+-** Target size for allocation chunks.
++** Each cache entry is represented by an instance of the following 
++** structure. Unless SQLITE_PCACHE_SEPARATE_HEADER is defined, a buffer of
++** PgHdr1.pCache->szPage bytes is allocated directly before this structure 
++** in memory.
+ */
+-#define ROWSET_ALLOCATION_SIZE 1024
++struct PgHdr1 {
++  sqlite3_pcache_page page;
++  unsigned int iKey;             /* Key value (page number) */
++  u8 isPinned;                   /* Page in use, not on the LRU list */
++  PgHdr1 *pNext;                 /* Next in hash table chain */
++  PCache1 *pCache;               /* Cache that currently owns this page */
++  PgHdr1 *pLruNext;              /* Next in LRU list of unpinned pages */
++  PgHdr1 *pLruPrev;              /* Previous in LRU list of unpinned pages */
++};
+ 
+ /*
+-** The number of rowset entries per allocation chunk.
++** Free slots in the allocator used to divide up the buffer provided using
++** the SQLITE_CONFIG_PAGECACHE mechanism.
+ */
+-#define ROWSET_ENTRY_PER_CHUNK  \
+-                       ((ROWSET_ALLOCATION_SIZE-8)/sizeof(struct RowSetEntry))
++struct PgFreeslot {
++  PgFreeslot *pNext;  /* Next free slot */
++};
+ 
+ /*
+-** Each entry in a RowSet is an instance of the following object.
+-**
+-** This same object is reused to store a linked list of trees of RowSetEntry
+-** objects.  In that alternative use, pRight points to the next entry
+-** in the list, pLeft points to the tree, and v is unused.  The
+-** RowSet.pForest value points to the head of this forest list.
++** Global data used by this cache.
+ */
+-struct RowSetEntry {            
+-  i64 v;                        /* ROWID value for this entry */
+-  struct RowSetEntry *pRight;   /* Right subtree (larger entries) or list */
+-  struct RowSetEntry *pLeft;    /* Left subtree (smaller entries) */
+-};
++static SQLITE_WSD struct PCacheGlobal {
++  PGroup grp;                    /* The global PGroup for mode (2) */
++
++  /* Variables related to SQLITE_CONFIG_PAGECACHE settings.  The
++  ** szSlot, nSlot, pStart, pEnd, nReserve, and isInit values are all
++  ** fixed at sqlite3_initialize() time and do not require mutex protection.
++  ** The nFreeSlot and pFree values do require mutex protection.
++  */
++  int isInit;                    /* True if initialized */
++  int szSlot;                    /* Size of each free slot */
++  int nSlot;                     /* The number of pcache slots */
++  int nReserve;                  /* Try to keep nFreeSlot above this */
++  void *pStart, *pEnd;           /* Bounds of pagecache malloc range */
++  /* Above requires no mutex.  Use mutex below for variable that follow. */
++  sqlite3_mutex *mutex;          /* Mutex for accessing the following: */
++  PgFreeslot *pFree;             /* Free page blocks */
++  int nFreeSlot;                 /* Number of unused pcache slots */
++  /* The following value requires a mutex to change.  We skip the mutex on
++  ** reading because (1) most platforms read a 32-bit integer atomically and
++  ** (2) even if an incorrect value is read, no great harm is done since this
++  ** is really just an optimization. */
++  int bUnderPressure;            /* True if low on PAGECACHE memory */
++} pcache1_g;
+ 
+ /*
+-** RowSetEntry objects are allocated in large chunks (instances of the
+-** following structure) to reduce memory allocation overhead.  The
+-** chunks are kept on a linked list so that they can be deallocated
+-** when the RowSet is destroyed.
++** All code in this file should access the global structure above via the
++** alias "pcache1". This ensures that the WSD emulation is used when
++** compiling for systems that do not support real WSD.
+ */
+-struct RowSetChunk {
+-  struct RowSetChunk *pNextChunk;        /* Next chunk on list of them all */
+-  struct RowSetEntry aEntry[ROWSET_ENTRY_PER_CHUNK]; /* Allocated entries */
+-};
++#define pcache1 (GLOBAL(struct PCacheGlobal, pcache1_g))
+ 
+ /*
+-** A RowSet in an instance of the following structure.
+-**
+-** A typedef of this structure if found in sqliteInt.h.
++** Macros to enter and leave the PCache LRU mutex.
+ */
+-struct RowSet {
+-  struct RowSetChunk *pChunk;    /* List of all chunk allocations */
+-  sqlite3 *db;                   /* The database connection */
+-  struct RowSetEntry *pEntry;    /* List of entries using pRight */
+-  struct RowSetEntry *pLast;     /* Last entry on the pEntry list */
+-  struct RowSetEntry *pFresh;    /* Source of new entry objects */
+-  struct RowSetEntry *pForest;   /* List of binary trees of entries */
+-  u16 nFresh;                    /* Number of objects on pFresh */
+-  u16 rsFlags;                   /* Various flags */
+-  int iBatch;                    /* Current insert batch */
+-};
++#define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex)
++#define pcache1LeaveMutex(X) sqlite3_mutex_leave((X)->mutex)
++
++/******************************************************************************/
++/******** Page Allocation/SQLITE_CONFIG_PCACHE Related Functions **************/
+ 
+ /*
+-** Allowed values for RowSet.rsFlags
++** This function is called during initialization if a static buffer is 
++** supplied to use for the page-cache by passing the SQLITE_CONFIG_PAGECACHE
++** verb to sqlite3_config(). Parameter pBuf points to an allocation large
++** enough to contain 'n' buffers of 'sz' bytes each.
++**
++** This routine is called from sqlite3_initialize() and so it is guaranteed
++** to be serialized already.  There is no need for further mutexing.
+ */
+-#define ROWSET_SORTED  0x01   /* True if RowSet.pEntry is sorted */
+-#define ROWSET_NEXT    0x02   /* True if sqlite3RowSetNext() has been called */
++SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){
++  if( pcache1.isInit ){
++    PgFreeslot *p;
++    sz = ROUNDDOWN8(sz);
++    pcache1.szSlot = sz;
++    pcache1.nSlot = pcache1.nFreeSlot = n;
++    pcache1.nReserve = n>90 ? 10 : (n/10 + 1);
++    pcache1.pStart = pBuf;
++    pcache1.pFree = 0;
++    pcache1.bUnderPressure = 0;
++    while( n-- ){
++      p = (PgFreeslot*)pBuf;
++      p->pNext = pcache1.pFree;
++      pcache1.pFree = p;
++      pBuf = (void*)&((char*)pBuf)[sz];
++    }
++    pcache1.pEnd = pBuf;
++  }
++}
+ 
+ /*
+-** Turn bulk memory into a RowSet object.  N bytes of memory
+-** are available at pSpace.  The db pointer is used as a memory context
+-** for any subsequent allocations that need to occur.
+-** Return a pointer to the new RowSet object.
++** Malloc function used within this file to allocate space from the buffer
++** configured using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no 
++** such buffer exists or there is no space left in it, this function falls 
++** back to sqlite3Malloc().
+ **
+-** It must be the case that N is sufficient to make a Rowset.  If not
+-** an assertion fault occurs.
+-** 
+-** If N is larger than the minimum, use the surplus as an initial
+-** allocation of entries available to be filled.
++** Multiple threads can run this routine at the same time.  Global variables
++** in pcache1 need to be protected via mutex.
+ */
+-SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){
+-  RowSet *p;
+-  assert( N >= ROUND8(sizeof(*p)) );
+-  p = pSpace;
+-  p->pChunk = 0;
+-  p->db = db;
+-  p->pEntry = 0;
+-  p->pLast = 0;
+-  p->pForest = 0;
+-  p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p);
+-  p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry));
+-  p->rsFlags = ROWSET_SORTED;
+-  p->iBatch = 0;
++static void *pcache1Alloc(int nByte){
++  void *p = 0;
++  assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
++  if( nByte<=pcache1.szSlot ){
++    sqlite3_mutex_enter(pcache1.mutex);
++    p = (PgHdr1 *)pcache1.pFree;
++    if( p ){
++      pcache1.pFree = pcache1.pFree->pNext;
++      pcache1.nFreeSlot--;
++      pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
++      assert( pcache1.nFreeSlot>=0 );
++      sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
++      sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1);
++    }
++    sqlite3_mutex_leave(pcache1.mutex);
++  }
++  if( p==0 ){
++    /* Memory is not available in the SQLITE_CONFIG_PAGECACHE pool.  Get
++    ** it from sqlite3Malloc instead.
++    */
++    p = sqlite3Malloc(nByte);
++#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
++    if( p ){
++      int sz = sqlite3MallocSize(p);
++      sqlite3_mutex_enter(pcache1.mutex);
++      sqlite3StatusSet(SQLITE_STATUS_PAGECACHE_SIZE, nByte);
++      sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
++      sqlite3_mutex_leave(pcache1.mutex);
++    }
++#endif
++    sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
++  }
+   return p;
+ }
+ 
+ /*
+-** Deallocate all chunks from a RowSet.  This frees all memory that
+-** the RowSet has allocated over its lifetime.  This routine is
+-** the destructor for the RowSet.
++** Free an allocated buffer obtained from pcache1Alloc().
+ */
+-SQLITE_PRIVATE void sqlite3RowSetClear(RowSet *p){
+-  struct RowSetChunk *pChunk, *pNextChunk;
+-  for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){
+-    pNextChunk = pChunk->pNextChunk;
+-    sqlite3DbFree(p->db, pChunk);
++static int pcache1Free(void *p){
++  int nFreed = 0;
++  if( p==0 ) return 0;
++  if( p>=pcache1.pStart && p<pcache1.pEnd ){
++    PgFreeslot *pSlot;
++    sqlite3_mutex_enter(pcache1.mutex);
++    sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_USED, 1);
++    pSlot = (PgFreeslot*)p;
++    pSlot->pNext = pcache1.pFree;
++    pcache1.pFree = pSlot;
++    pcache1.nFreeSlot++;
++    pcache1.bUnderPressure = pcache1.nFreeSlot<pcache1.nReserve;
++    assert( pcache1.nFreeSlot<=pcache1.nSlot );
++    sqlite3_mutex_leave(pcache1.mutex);
++  }else{
++    assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
++    sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
++    nFreed = sqlite3MallocSize(p);
++#ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS
++    sqlite3_mutex_enter(pcache1.mutex);
++    sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_OVERFLOW, nFreed);
++    sqlite3_mutex_leave(pcache1.mutex);
++#endif
++    sqlite3_free(p);
+   }
+-  p->pChunk = 0;
+-  p->nFresh = 0;
+-  p->pEntry = 0;
+-  p->pLast = 0;
+-  p->pForest = 0;
+-  p->rsFlags = ROWSET_SORTED;
++  return nFreed;
+ }
+ 
++#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+ /*
+-** Allocate a new RowSetEntry object that is associated with the
+-** given RowSet.  Return a pointer to the new and completely uninitialized
+-** objected.
+-**
+-** In an OOM situation, the RowSet.db->mallocFailed flag is set and this
+-** routine returns NULL.
++** Return the size of a pcache allocation
+ */
+-static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){
+-  assert( p!=0 );
+-  if( p->nFresh==0 ){
+-    struct RowSetChunk *pNew;
+-    pNew = sqlite3DbMallocRaw(p->db, sizeof(*pNew));
+-    if( pNew==0 ){
+-      return 0;
+-    }
+-    pNew->pNextChunk = p->pChunk;
+-    p->pChunk = pNew;
+-    p->pFresh = pNew->aEntry;
+-    p->nFresh = ROWSET_ENTRY_PER_CHUNK;
++static int pcache1MemSize(void *p){
++  if( p>=pcache1.pStart && p<pcache1.pEnd ){
++    return pcache1.szSlot;
++  }else{
++    int iSize;
++    assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
++    sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
++    iSize = sqlite3MallocSize(p);
++    sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
++    return iSize;
+   }
+-  p->nFresh--;
+-  return p->pFresh++;
+ }
++#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
+ 
+ /*
+-** Insert a new value into a RowSet.
+-**
+-** The mallocFailed flag of the database connection is set if a
+-** memory allocation fails.
++** Allocate a new page object initially associated with cache pCache.
+ */
+-SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet *p, i64 rowid){
+-  struct RowSetEntry *pEntry;  /* The new entry */
+-  struct RowSetEntry *pLast;   /* The last prior entry */
++static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
++  PgHdr1 *p = 0;
++  void *pPg;
+ 
+-  /* This routine is never called after sqlite3RowSetNext() */
+-  assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 );
++  /* The group mutex must be released before pcache1Alloc() is called. This
++  ** is because it may call sqlite3_release_memory(), which assumes that 
++  ** this mutex is not held. */
++  assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
++  pcache1LeaveMutex(pCache->pGroup);
++#ifdef SQLITE_PCACHE_SEPARATE_HEADER
++  pPg = pcache1Alloc(pCache->szPage);
++  p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra);
++  if( !pPg || !p ){
++    pcache1Free(pPg);
++    sqlite3_free(p);
++    pPg = 0;
++  }
++#else
++  pPg = pcache1Alloc(ROUND8(sizeof(PgHdr1)) + pCache->szPage + pCache->szExtra);
++  p = (PgHdr1 *)&((u8 *)pPg)[pCache->szPage];
++#endif
++  pcache1EnterMutex(pCache->pGroup);
+ 
+-  pEntry = rowSetEntryAlloc(p);
+-  if( pEntry==0 ) return;
+-  pEntry->v = rowid;
+-  pEntry->pRight = 0;
+-  pLast = p->pLast;
+-  if( pLast ){
+-    if( (p->rsFlags & ROWSET_SORTED)!=0 && rowid<=pLast->v ){
+-      p->rsFlags &= ~ROWSET_SORTED;
++  if( pPg ){
++    p->page.pBuf = pPg;
++    p->page.pExtra = &p[1];
++    if( pCache->bPurgeable ){
++      pCache->pGroup->nCurrentPage++;
+     }
+-    pLast->pRight = pEntry;
+-  }else{
+-    p->pEntry = pEntry;
++    return p;
+   }
+-  p->pLast = pEntry;
++  return 0;
+ }
+ 
+ /*
+-** Merge two lists of RowSetEntry objects.  Remove duplicates.
++** Free a page object allocated by pcache1AllocPage().
+ **
+-** The input lists are connected via pRight pointers and are 
+-** assumed to each already be in sorted order.
++** The pointer is allowed to be NULL, which is prudent.  But it turns out
++** that the current implementation happens to never call this routine
++** with a NULL pointer, so we mark the NULL test with ALWAYS().
+ */
+-static struct RowSetEntry *rowSetEntryMerge(
+-  struct RowSetEntry *pA,    /* First sorted list to be merged */
+-  struct RowSetEntry *pB     /* Second sorted list to be merged */
+-){
+-  struct RowSetEntry head;
+-  struct RowSetEntry *pTail;
+-
+-  pTail = &head;
+-  while( pA && pB ){
+-    assert( pA->pRight==0 || pA->v<=pA->pRight->v );
+-    assert( pB->pRight==0 || pB->v<=pB->pRight->v );
+-    if( pA->v<pB->v ){
+-      pTail->pRight = pA;
+-      pA = pA->pRight;
+-      pTail = pTail->pRight;
+-    }else if( pB->v<pA->v ){
+-      pTail->pRight = pB;
+-      pB = pB->pRight;
+-      pTail = pTail->pRight;
+-    }else{
+-      pA = pA->pRight;
++static void pcache1FreePage(PgHdr1 *p){
++  if( ALWAYS(p) ){
++    PCache1 *pCache = p->pCache;
++    assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) );
++    pcache1Free(p->page.pBuf);
++#ifdef SQLITE_PCACHE_SEPARATE_HEADER
++    sqlite3_free(p);
++#endif
++    if( pCache->bPurgeable ){
++      pCache->pGroup->nCurrentPage--;
+     }
+   }
+-  if( pA ){
+-    assert( pA->pRight==0 || pA->v<=pA->pRight->v );
+-    pTail->pRight = pA;
+-  }else{
+-    assert( pB==0 || pB->pRight==0 || pB->v<=pB->pRight->v );
+-    pTail->pRight = pB;
+-  }
+-  return head.pRight;
+ }
+ 
+ /*
+-** Sort all elements on the list of RowSetEntry objects into order of
+-** increasing v.
+-*/ 
+-static struct RowSetEntry *rowSetEntrySort(struct RowSetEntry *pIn){
+-  unsigned int i;
+-  struct RowSetEntry *pNext, *aBucket[40];
+-
+-  memset(aBucket, 0, sizeof(aBucket));
+-  while( pIn ){
+-    pNext = pIn->pRight;
+-    pIn->pRight = 0;
+-    for(i=0; aBucket[i]; i++){
+-      pIn = rowSetEntryMerge(aBucket[i], pIn);
+-      aBucket[i] = 0;
+-    }
+-    aBucket[i] = pIn;
+-    pIn = pNext;
+-  }
+-  pIn = 0;
+-  for(i=0; i<sizeof(aBucket)/sizeof(aBucket[0]); i++){
+-    pIn = rowSetEntryMerge(pIn, aBucket[i]);
+-  }
+-  return pIn;
++** Malloc function used by SQLite to obtain space from the buffer configured
++** using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no such buffer
++** exists, this function falls back to sqlite3Malloc().
++*/
++SQLITE_PRIVATE void *sqlite3PageMalloc(int sz){
++  return pcache1Alloc(sz);
+ }
+ 
+-
+ /*
+-** The input, pIn, is a binary tree (or subtree) of RowSetEntry objects.
+-** Convert this tree into a linked list connected by the pRight pointers
+-** and return pointers to the first and last elements of the new list.
++** Free an allocated buffer obtained from sqlite3PageMalloc().
+ */
+-static void rowSetTreeToList(
+-  struct RowSetEntry *pIn,         /* Root of the input tree */
+-  struct RowSetEntry **ppFirst,    /* Write head of the output list here */
+-  struct RowSetEntry **ppLast      /* Write tail of the output list here */
+-){
+-  assert( pIn!=0 );
+-  if( pIn->pLeft ){
+-    struct RowSetEntry *p;
+-    rowSetTreeToList(pIn->pLeft, ppFirst, &p);
+-    p->pRight = pIn;
+-  }else{
+-    *ppFirst = pIn;
+-  }
+-  if( pIn->pRight ){
+-    rowSetTreeToList(pIn->pRight, &pIn->pRight, ppLast);
+-  }else{
+-    *ppLast = pIn;
+-  }
+-  assert( (*ppLast)->pRight==0 );
++SQLITE_PRIVATE void sqlite3PageFree(void *p){
++  pcache1Free(p);
+ }
+ 
+ 
+ /*
+-** Convert a sorted list of elements (connected by pRight) into a binary
+-** tree with depth of iDepth.  A depth of 1 means the tree contains a single
+-** node taken from the head of *ppList.  A depth of 2 means a tree with
+-** three nodes.  And so forth.
++** Return true if it desirable to avoid allocating a new page cache
++** entry.
+ **
+-** Use as many entries from the input list as required and update the
+-** *ppList to point to the unused elements of the list.  If the input
+-** list contains too few elements, then construct an incomplete tree
+-** and leave *ppList set to NULL.
++** If memory was allocated specifically to the page cache using
++** SQLITE_CONFIG_PAGECACHE but that memory has all been used, then
++** it is desirable to avoid allocating a new page cache entry because
++** presumably SQLITE_CONFIG_PAGECACHE was suppose to be sufficient
++** for all page cache needs and we should not need to spill the
++** allocation onto the heap.
+ **
+-** Return a pointer to the root of the constructed binary tree.
++** Or, the heap is used for all page cache memory but the heap is
++** under memory pressure, then again it is desirable to avoid
++** allocating a new page cache entry in order to avoid stressing
++** the heap even further.
+ */
+-static struct RowSetEntry *rowSetNDeepTree(
+-  struct RowSetEntry **ppList,
+-  int iDepth
+-){
+-  struct RowSetEntry *p;         /* Root of the new tree */
+-  struct RowSetEntry *pLeft;     /* Left subtree */
+-  if( *ppList==0 ){
+-    return 0;
+-  }
+-  if( iDepth==1 ){
+-    p = *ppList;
+-    *ppList = p->pRight;
+-    p->pLeft = p->pRight = 0;
+-    return p;
+-  }
+-  pLeft = rowSetNDeepTree(ppList, iDepth-1);
+-  p = *ppList;
+-  if( p==0 ){
+-    return pLeft;
++static int pcache1UnderMemoryPressure(PCache1 *pCache){
++  if( pcache1.nSlot && (pCache->szPage+pCache->szExtra)<=pcache1.szSlot ){
++    return pcache1.bUnderPressure;
++  }else{
++    return sqlite3HeapNearlyFull();
+   }
+-  p->pLeft = pLeft;
+-  *ppList = p->pRight;
+-  p->pRight = rowSetNDeepTree(ppList, iDepth-1);
+-  return p;
+ }
+ 
+-/*
+-** Convert a sorted list of elements into a binary tree. Make the tree
+-** as deep as it needs to be in order to contain the entire list.
+-*/
+-static struct RowSetEntry *rowSetListToTree(struct RowSetEntry *pList){
+-  int iDepth;           /* Depth of the tree so far */
+-  struct RowSetEntry *p;       /* Current tree root */
+-  struct RowSetEntry *pLeft;   /* Left subtree */
+-
+-  assert( pList!=0 );
+-  p = pList;
+-  pList = p->pRight;
+-  p->pLeft = p->pRight = 0;
+-  for(iDepth=1; pList; iDepth++){
+-    pLeft = p;
+-    p = pList;
+-    pList = p->pRight;
+-    p->pLeft = pLeft;
+-    p->pRight = rowSetNDeepTree(&pList, iDepth);
+-  }
+-  return p;
+-}
++/******************************************************************************/
++/******** General Implementation Functions ************************************/
+ 
+ /*
+-** Take all the entries on p->pEntry and on the trees in p->pForest and
+-** sort them all together into one big ordered list on p->pEntry.
++** This function is used to resize the hash table used by the cache passed
++** as the first argument.
+ **
+-** This routine should only be called once in the life of a RowSet.
++** The PCache mutex must be held when this function is called.
+ */
+-static void rowSetToList(RowSet *p){
++static void pcache1ResizeHash(PCache1 *p){
++  PgHdr1 **apNew;
++  unsigned int nNew;
++  unsigned int i;
+ 
+-  /* This routine is called only once */
+-  assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 );
++  assert( sqlite3_mutex_held(p->pGroup->mutex) );
+ 
+-  if( (p->rsFlags & ROWSET_SORTED)==0 ){
+-    p->pEntry = rowSetEntrySort(p->pEntry);
++  nNew = p->nHash*2;
++  if( nNew<256 ){
++    nNew = 256;
+   }
+ 
+-  /* While this module could theoretically support it, sqlite3RowSetNext()
+-  ** is never called after sqlite3RowSetText() for the same RowSet.  So
+-  ** there is never a forest to deal with.  Should this change, simply
+-  ** remove the assert() and the #if 0. */
+-  assert( p->pForest==0 );
+-#if 0
+-  while( p->pForest ){
+-    struct RowSetEntry *pTree = p->pForest->pLeft;
+-    if( pTree ){
+-      struct RowSetEntry *pHead, *pTail;
+-      rowSetTreeToList(pTree, &pHead, &pTail);
+-      p->pEntry = rowSetEntryMerge(p->pEntry, pHead);
++  pcache1LeaveMutex(p->pGroup);
++  if( p->nHash ){ sqlite3BeginBenignMalloc(); }
++  apNew = (PgHdr1 **)sqlite3MallocZero(sizeof(PgHdr1 *)*nNew);
++  if( p->nHash ){ sqlite3EndBenignMalloc(); }
++  pcache1EnterMutex(p->pGroup);
++  if( apNew ){
++    for(i=0; i<p->nHash; i++){
++      PgHdr1 *pPage;
++      PgHdr1 *pNext = p->apHash[i];
++      while( (pPage = pNext)!=0 ){
++        unsigned int h = pPage->iKey % nNew;
++        pNext = pPage->pNext;
++        pPage->pNext = apNew[h];
++        apNew[h] = pPage;
++      }
+     }
+-    p->pForest = p->pForest->pRight;
++    sqlite3_free(p->apHash);
++    p->apHash = apNew;
++    p->nHash = nNew;
+   }
+-#endif
+-  p->rsFlags |= ROWSET_NEXT;  /* Verify this routine is never called again */
+ }
+ 
+ /*
+-** Extract the smallest element from the RowSet.
+-** Write the element into *pRowid.  Return 1 on success.  Return
+-** 0 if the RowSet is already empty.
++** This function is used internally to remove the page pPage from the 
++** PGroup LRU list, if is part of it. If pPage is not part of the PGroup
++** LRU list, then this function is a no-op.
+ **
+-** After this routine has been called, the sqlite3RowSetInsert()
+-** routine may not be called again.  
++** The PGroup mutex must be held when this function is called.
+ */
+-SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){
+-  assert( p!=0 );
+-
+-  /* Merge the forest into a single sorted list on first call */
+-  if( (p->rsFlags & ROWSET_NEXT)==0 ) rowSetToList(p);
++static void pcache1PinPage(PgHdr1 *pPage){
++  PCache1 *pCache;
++  PGroup *pGroup;
+ 
+-  /* Return the next entry on the list */
+-  if( p->pEntry ){
+-    *pRowid = p->pEntry->v;
+-    p->pEntry = p->pEntry->pRight;
+-    if( p->pEntry==0 ){
+-      sqlite3RowSetClear(p);
+-    }
+-    return 1;
++  assert( pPage!=0 );
++  assert( pPage->isPinned==0 );
++  pCache = pPage->pCache;
++  pGroup = pCache->pGroup;
++  assert( pPage->pLruNext || pPage==pGroup->pLruTail );
++  assert( pPage->pLruPrev || pPage==pGroup->pLruHead );
++  assert( sqlite3_mutex_held(pGroup->mutex) );
++  if( pPage->pLruPrev ){
++    pPage->pLruPrev->pLruNext = pPage->pLruNext;
+   }else{
+-    return 0;
++    pGroup->pLruHead = pPage->pLruNext;
++  }
++  if( pPage->pLruNext ){
++    pPage->pLruNext->pLruPrev = pPage->pLruPrev;
++  }else{
++    pGroup->pLruTail = pPage->pLruPrev;
+   }
++  pPage->pLruNext = 0;
++  pPage->pLruPrev = 0;
++  pPage->isPinned = 1;
++  pCache->nRecyclable--;
+ }
+ 
++
+ /*
+-** Check to see if element iRowid was inserted into the rowset as
+-** part of any insert batch prior to iBatch.  Return 1 or 0.
++** Remove the page supplied as an argument from the hash table 
++** (PCache1.apHash structure) that it is currently stored in.
+ **
+-** If this is the first test of a new batch and if there exist entries
+-** on pRowSet->pEntry, then sort those entries into the forest at
+-** pRowSet->pForest so that they can be tested.
++** The PGroup mutex must be held when this function is called.
+ */
+-SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){
+-  struct RowSetEntry *p, *pTree;
++static void pcache1RemoveFromHash(PgHdr1 *pPage){
++  unsigned int h;
++  PCache1 *pCache = pPage->pCache;
++  PgHdr1 **pp;
+ 
+-  /* This routine is never called after sqlite3RowSetNext() */
+-  assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 );
++  assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
++  h = pPage->iKey % pCache->nHash;
++  for(pp=&pCache->apHash[h]; (*pp)!=pPage; pp=&(*pp)->pNext);
++  *pp = (*pp)->pNext;
+ 
+-  /* Sort entries into the forest on the first test of a new batch 
+-  */
+-  if( iBatch!=pRowSet->iBatch ){
+-    p = pRowSet->pEntry;
+-    if( p ){
+-      struct RowSetEntry **ppPrevTree = &pRowSet->pForest;
+-      if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){
+-        p = rowSetEntrySort(p);
+-      }
+-      for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
+-        ppPrevTree = &pTree->pRight;
+-        if( pTree->pLeft==0 ){
+-          pTree->pLeft = rowSetListToTree(p);
+-          break;
+-        }else{
+-          struct RowSetEntry *pAux, *pTail;
+-          rowSetTreeToList(pTree->pLeft, &pAux, &pTail);
+-          pTree->pLeft = 0;
+-          p = rowSetEntryMerge(pAux, p);
+-        }
+-      }
+-      if( pTree==0 ){
+-        *ppPrevTree = pTree = rowSetEntryAlloc(pRowSet);
+-        if( pTree ){
+-          pTree->v = 0;
+-          pTree->pRight = 0;
+-          pTree->pLeft = rowSetListToTree(p);
+-        }
+-      }
+-      pRowSet->pEntry = 0;
+-      pRowSet->pLast = 0;
+-      pRowSet->rsFlags |= ROWSET_SORTED;
+-    }
+-    pRowSet->iBatch = iBatch;
++  pCache->nPage--;
++}
++
++/*
++** If there are currently more than nMaxPage pages allocated, try
++** to recycle pages to reduce the number allocated to nMaxPage.
++*/
++static void pcache1EnforceMaxPage(PGroup *pGroup){
++  assert( sqlite3_mutex_held(pGroup->mutex) );
++  while( pGroup->nCurrentPage>pGroup->nMaxPage && pGroup->pLruTail ){
++    PgHdr1 *p = pGroup->pLruTail;
++    assert( p->pCache->pGroup==pGroup );
++    assert( p->isPinned==0 );
++    pcache1PinPage(p);
++    pcache1RemoveFromHash(p);
++    pcache1FreePage(p);
+   }
++}
+ 
+-  /* Test to see if the iRowid value appears anywhere in the forest.
+-  ** Return 1 if it does and 0 if not.
+-  */
+-  for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
+-    p = pTree->pLeft;
+-    while( p ){
+-      if( p->v<iRowid ){
+-        p = p->pRight;
+-      }else if( p->v>iRowid ){
+-        p = p->pLeft;
++/*
++** Discard all pages from cache pCache with a page number (key value) 
++** greater than or equal to iLimit. Any pinned pages that meet this 
++** criteria are unpinned before they are discarded.
++**
++** The PCache mutex must be held when this function is called.
++*/
++static void pcache1TruncateUnsafe(
++  PCache1 *pCache,             /* The cache to truncate */
++  unsigned int iLimit          /* Drop pages with this pgno or larger */
++){
++  TESTONLY( unsigned int nPage = 0; )  /* To assert pCache->nPage is correct */
++  unsigned int h;
++  assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
++  for(h=0; h<pCache->nHash; h++){
++    PgHdr1 **pp = &pCache->apHash[h]; 
++    PgHdr1 *pPage;
++    while( (pPage = *pp)!=0 ){
++      if( pPage->iKey>=iLimit ){
++        pCache->nPage--;
++        *pp = pPage->pNext;
++        if( !pPage->isPinned ) pcache1PinPage(pPage);
++        pcache1FreePage(pPage);
+       }else{
+-        return 1;
++        pp = &pPage->pNext;
++        TESTONLY( nPage++; )
+       }
+     }
+   }
+-  return 0;
++  assert( pCache->nPage==nPage );
+ }
+ 
+-/************** End of rowset.c **********************************************/
+-/************** Begin file pager.c *******************************************/
++/******************************************************************************/
++/******** sqlite3_pcache Methods **********************************************/
++
+ /*
+-** 2001 September 15
+-**
+-** The author disclaims copyright to this source code.  In place of
+-** a legal notice, here is a blessing:
+-**
+-**    May you do good and not evil.
+-**    May you find forgiveness for yourself and forgive others.
+-**    May you share freely, never taking more than you give.
+-**
+-*************************************************************************
+-** This is the implementation of the page cache subsystem or "pager".
+-** 
+-** The pager is used to access a database disk file.  It implements
+-** atomic commit and rollback through the use of a journal file that
+-** is separate from the database file.  The pager also implements file
+-** locking to prevent two processes from writing the same database
+-** file simultaneously, or one process from reading the database while
+-** another is writing.
++** Implementation of the sqlite3_pcache.xInit method.
+ */
+-#ifndef SQLITE_OMIT_DISKIO
+-/************** Include wal.h in the middle of pager.c ***********************/
+-/************** Begin file wal.h *********************************************/
++static int pcache1Init(void *NotUsed){
++  UNUSED_PARAMETER(NotUsed);
++  assert( pcache1.isInit==0 );
++  memset(&pcache1, 0, sizeof(pcache1));
++  if( sqlite3GlobalConfig.bCoreMutex ){
++    pcache1.grp.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU);
++    pcache1.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PMEM);
++  }
++  pcache1.grp.mxPinned = 10;
++  pcache1.isInit = 1;
++  return SQLITE_OK;
++}
++
+ /*
+-** 2010 February 1
+-**
+-** The author disclaims copyright to this source code.  In place of
+-** a legal notice, here is a blessing:
+-**
+-**    May you do good and not evil.
+-**    May you find forgiveness for yourself and forgive others.
+-**    May you share freely, never taking more than you give.
+-**
+-*************************************************************************
+-** This header file defines the interface to the write-ahead logging 
+-** system. Refer to the comments below and the header comment attached to 
+-** the implementation of each function in log.c for further details.
++** Implementation of the sqlite3_pcache.xShutdown method.
++** Note that the static mutex allocated in xInit does 
++** not need to be freed.
+ */
++static void pcache1Shutdown(void *NotUsed){
++  UNUSED_PARAMETER(NotUsed);
++  assert( pcache1.isInit!=0 );
++  memset(&pcache1, 0, sizeof(pcache1));
++}
+ 
+-#ifndef _WAL_H_
+-#define _WAL_H_
+-
++/* forward declaration */
++static void pcache1Destroy(sqlite3_pcache *p);
+ 
+-/* Additional values that can be added to the sync_flags argument of
+-** sqlite3WalFrames():
++/*
++** Implementation of the sqlite3_pcache.xCreate method.
++**
++** Allocate a new cache.
+ */
+-#define WAL_SYNC_TRANSACTIONS  0x20   /* Sync at the end of each transaction */
+-#define SQLITE_SYNC_MASK       0x13   /* Mask off the SQLITE_SYNC_* values */
++static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){
++  PCache1 *pCache;      /* The newly created page cache */
++  PGroup *pGroup;       /* The group the new page cache will belong to */
++  int sz;               /* Bytes of memory required to allocate the new cache */
+ 
+-#ifdef SQLITE_OMIT_WAL
+-# define sqlite3WalOpen(x,y,z)                   0
+-# define sqlite3WalLimit(x,y)
+-# define sqlite3WalClose(w,x,y,z)                0
+-# define sqlite3WalBeginReadTransaction(y,z)     0
+-# define sqlite3WalEndReadTransaction(z)
+-# define sqlite3WalDbsize(y)                     0
+-# define sqlite3WalBeginWriteTransaction(y)      0
+-# define sqlite3WalEndWriteTransaction(x)        0
+-# define sqlite3WalUndo(x,y,z)                   0
+-# define sqlite3WalSavepoint(y,z)
+-# define sqlite3WalSavepointUndo(y,z)            0
+-# define sqlite3WalFrames(u,v,w,x,y,z)           0
+-# define sqlite3WalCheckpoint(r,s,t,u,v,w,x,y,z) 0
+-# define sqlite3WalCallback(z)                   0
+-# define sqlite3WalExclusiveMode(y,z)            0
+-# define sqlite3WalHeapMemory(z)                 0
+-# define sqlite3WalFramesize(z)                  0
+-# define sqlite3WalFindFrame(x,y,z)              0
++  /*
++  ** The separateCache variable is true if each PCache has its own private
++  ** PGroup.  In other words, separateCache is true for mode (1) where no
++  ** mutexing is required.
++  **
++  **   *  Always use a unified cache (mode-2) if ENABLE_MEMORY_MANAGEMENT
++  **
++  **   *  Always use a unified cache in single-threaded applications
++  **
++  **   *  Otherwise (if multi-threaded and ENABLE_MEMORY_MANAGEMENT is off)
++  **      use separate caches (mode-1)
++  */
++#if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) || SQLITE_THREADSAFE==0
++  const int separateCache = 0;
+ #else
++  int separateCache = sqlite3GlobalConfig.bCoreMutex>0;
++#endif
+ 
+-#define WAL_SAVEPOINT_NDATA 4
+-
+-/* Connection to a write-ahead log (WAL) file. 
+-** There is one object of this type for each pager. 
+-*/
+-typedef struct Wal Wal;
+-
+-/* Open and close a connection to a write-ahead log. */
+-SQLITE_PRIVATE int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**);
+-SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, int sync_flags, int, u8 *);
++  assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 );
++  assert( szExtra < 300 );
+ 
+-/* Set the limiting size of a WAL file. */
+-SQLITE_PRIVATE void sqlite3WalLimit(Wal*, i64);
++  sz = sizeof(PCache1) + sizeof(PGroup)*separateCache;
++  pCache = (PCache1 *)sqlite3MallocZero(sz);
++  if( pCache ){
++    if( separateCache ){
++      pGroup = (PGroup*)&pCache[1];
++      pGroup->mxPinned = 10;
++    }else{
++      pGroup = &pcache1.grp;
++    }
++    pCache->pGroup = pGroup;
++    pCache->szPage = szPage;
++    pCache->szExtra = szExtra;
++    pCache->bPurgeable = (bPurgeable ? 1 : 0);
++    pcache1EnterMutex(pGroup);
++    pcache1ResizeHash(pCache);
++    if( bPurgeable ){
++      pCache->nMin = 10;
++      pGroup->nMinPage += pCache->nMin;
++      pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
++    }
++    pcache1LeaveMutex(pGroup);
++    if( pCache->nHash==0 ){
++      pcache1Destroy((sqlite3_pcache*)pCache);
++      pCache = 0;
++    }
++  }
++  return (sqlite3_pcache *)pCache;
++}
+ 
+-/* Used by readers to open (lock) and close (unlock) a snapshot.  A 
+-** snapshot is like a read-transaction.  It is the state of the database
+-** at an instant in time.  sqlite3WalOpenSnapshot gets a read lock and
+-** preserves the current state even if the other threads or processes
+-** write to or checkpoint the WAL.  sqlite3WalCloseSnapshot() closes the
+-** transaction and releases the lock.
++/*
++** Implementation of the sqlite3_pcache.xCachesize method. 
++**
++** Configure the cache_size limit for a cache.
+ */
+-SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *);
+-SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal);
+-
+-/* Read a page from the write-ahead log, if it is present. */
+-SQLITE_PRIVATE int sqlite3WalFindFrame(Wal *, Pgno, u32 *);
+-SQLITE_PRIVATE int sqlite3WalReadFrame(Wal *, u32, int, u8 *);
+-
+-/* If the WAL is not empty, return the size of the database. */
+-SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal);
+-
+-/* Obtain or release the WRITER lock. */
+-SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal);
+-SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal);
+-
+-/* Undo any frames written (but not committed) to the log */
+-SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx);
+-
+-/* Return an integer that records the current (uncommitted) write
+-** position in the WAL */
+-SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData);
+-
+-/* Move the write position of the WAL back to iFrame.  Called in
+-** response to a ROLLBACK TO command. */
+-SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData);
+-
+-/* Write a frame or frames to the log. */
+-SQLITE_PRIVATE int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int);
+-
+-/* Copy pages from the log to the database file */ 
+-SQLITE_PRIVATE int sqlite3WalCheckpoint(
+-  Wal *pWal,                      /* Write-ahead log connection */
+-  int eMode,                      /* One of PASSIVE, FULL and RESTART */
+-  int (*xBusy)(void*),            /* Function to call when busy */
+-  void *pBusyArg,                 /* Context argument for xBusyHandler */
+-  int sync_flags,                 /* Flags to sync db file with (or 0) */
+-  int nBuf,                       /* Size of buffer nBuf */
+-  u8 *zBuf,                       /* Temporary buffer to use */
+-  int *pnLog,                     /* OUT: Number of frames in WAL */
+-  int *pnCkpt                     /* OUT: Number of backfilled frames in WAL */
+-);
++static void pcache1Cachesize(sqlite3_pcache *p, int nMax){
++  PCache1 *pCache = (PCache1 *)p;
++  if( pCache->bPurgeable ){
++    PGroup *pGroup = pCache->pGroup;
++    pcache1EnterMutex(pGroup);
++    pGroup->nMaxPage += (nMax - pCache->nMax);
++    pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
++    pCache->nMax = nMax;
++    pCache->n90pct = pCache->nMax*9/10;
++    pcache1EnforceMaxPage(pGroup);
++    pcache1LeaveMutex(pGroup);
++  }
++}
+ 
+-/* Return the value to pass to a sqlite3_wal_hook callback, the
+-** number of frames in the WAL at the point of the last commit since
+-** sqlite3WalCallback() was called.  If no commits have occurred since
+-** the last call, then return 0.
++/*
++** Implementation of the sqlite3_pcache.xShrink method. 
++**
++** Free up as much memory as possible.
+ */
+-SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal);
++static void pcache1Shrink(sqlite3_pcache *p){
++  PCache1 *pCache = (PCache1*)p;
++  if( pCache->bPurgeable ){
++    PGroup *pGroup = pCache->pGroup;
++    int savedMaxPage;
++    pcache1EnterMutex(pGroup);
++    savedMaxPage = pGroup->nMaxPage;
++    pGroup->nMaxPage = 0;
++    pcache1EnforceMaxPage(pGroup);
++    pGroup->nMaxPage = savedMaxPage;
++    pcache1LeaveMutex(pGroup);
++  }
++}
+ 
+-/* Tell the wal layer that an EXCLUSIVE lock has been obtained (or released)
+-** by the pager layer on the database file.
++/*
++** Implementation of the sqlite3_pcache.xPagecount method. 
+ */
+-SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op);
++static int pcache1Pagecount(sqlite3_pcache *p){
++  int n;
++  PCache1 *pCache = (PCache1*)p;
++  pcache1EnterMutex(pCache->pGroup);
++  n = pCache->nPage;
++  pcache1LeaveMutex(pCache->pGroup);
++  return n;
++}
+ 
+-/* Return true if the argument is non-NULL and the WAL module is using
+-** heap-memory for the wal-index. Otherwise, if the argument is NULL or the
+-** WAL module is using shared-memory, return false. 
+-*/
+-SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal);
+ 
+-#ifdef SQLITE_ENABLE_ZIPVFS
+-/* If the WAL file is not empty, return the number of bytes of content
+-** stored in each frame (i.e. the db page-size when the WAL was created).
++/*
++** Implement steps 3, 4, and 5 of the pcache1Fetch() algorithm described
++** in the header of the pcache1Fetch() procedure.
++**
++** This steps are broken out into a separate procedure because they are
++** usually not needed, and by avoiding the stack initialization required
++** for these steps, the main pcache1Fetch() procedure can run faster.
+ */
+-SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal);
+-#endif
++static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2(
++  PCache1 *pCache, 
++  unsigned int iKey, 
++  int createFlag
++){
++  unsigned int nPinned;
++  PGroup *pGroup = pCache->pGroup;
++  PgHdr1 *pPage = 0;
+ 
+-#endif /* ifndef SQLITE_OMIT_WAL */
+-#endif /* _WAL_H_ */
++  /* Step 3: Abort if createFlag is 1 but the cache is nearly full */
++  assert( pCache->nPage >= pCache->nRecyclable );
++  nPinned = pCache->nPage - pCache->nRecyclable;
++  assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage );
++  assert( pCache->n90pct == pCache->nMax*9/10 );
++  if( createFlag==1 && (
++        nPinned>=pGroup->mxPinned
++     || nPinned>=pCache->n90pct
++     || (pcache1UnderMemoryPressure(pCache) && pCache->nRecyclable<nPinned)
++  )){
++    return 0;
++  }
+ 
+-/************** End of wal.h *************************************************/
+-/************** Continuing where we left off in pager.c **********************/
++  if( pCache->nPage>=pCache->nHash ) pcache1ResizeHash(pCache);
++  assert( pCache->nHash>0 && pCache->apHash );
+ 
++  /* Step 4. Try to recycle a page. */
++  if( pCache->bPurgeable && pGroup->pLruTail && (
++         (pCache->nPage+1>=pCache->nMax)
++      || pGroup->nCurrentPage>=pGroup->nMaxPage
++      || pcache1UnderMemoryPressure(pCache)
++  )){
++    PCache1 *pOther;
++    pPage = pGroup->pLruTail;
++    assert( pPage->isPinned==0 );
++    pcache1RemoveFromHash(pPage);
++    pcache1PinPage(pPage);
++    pOther = pPage->pCache;
+ 
+-/******************* NOTES ON THE DESIGN OF THE PAGER ************************
+-**
+-** This comment block describes invariants that hold when using a rollback
+-** journal.  These invariants do not apply for journal_mode=WAL,
+-** journal_mode=MEMORY, or journal_mode=OFF.
+-**
+-** Within this comment block, a page is deemed to have been synced
+-** automatically as soon as it is written when PRAGMA synchronous=OFF.
+-** Otherwise, the page is not synced until the xSync method of the VFS
+-** is called successfully on the file containing the page.
+-**
+-** Definition:  A page of the database file is said to be "overwriteable" if
+-** one or more of the following are true about the page:
+-** 
+-**     (a)  The original content of the page as it was at the beginning of
+-**          the transaction has been written into the rollback journal and
+-**          synced.
+-** 
+-**     (b)  The page was a freelist leaf page at the start of the transaction.
+-** 
+-**     (c)  The page number is greater than the largest page that existed in
+-**          the database file at the start of the transaction.
+-** 
+-** (1) A page of the database file is never overwritten unless one of the
+-**     following are true:
+-** 
+-**     (a) The page and all other pages on the same sector are overwriteable.
+-** 
+-**     (b) The atomic page write optimization is enabled, and the entire
+-**         transaction other than the update of the transaction sequence
+-**         number consists of a single page change.
+-** 
+-** (2) The content of a page written into the rollback journal exactly matches
+-**     both the content in the database when the rollback journal was written
+-**     and the content in the database at the beginning of the current
+-**     transaction.
+-** 
+-** (3) Writes to the database file are an integer multiple of the page size
+-**     in length and are aligned on a page boundary.
+-** 
+-** (4) Reads from the database file are either aligned on a page boundary and
+-**     an integer multiple of the page size in length or are taken from the
+-**     first 100 bytes of the database file.
+-** 
+-** (5) All writes to the database file are synced prior to the rollback journal
+-**     being deleted, truncated, or zeroed.
+-** 
+-** (6) If a master journal file is used, then all writes to the database file
+-**     are synced prior to the master journal being deleted.
+-** 
+-** Definition: Two databases (or the same database at two points it time)
+-** are said to be "logically equivalent" if they give the same answer to
+-** all queries.  Note in particular the content of freelist leaf
+-** pages can be changed arbitrarily without affecting the logical equivalence
+-** of the database.
+-** 
+-** (7) At any time, if any subset, including the empty set and the total set,
+-**     of the unsynced changes to a rollback journal are removed and the 
+-**     journal is rolled back, the resulting database file will be logically
+-**     equivalent to the database file at the beginning of the transaction.
+-** 
+-** (8) When a transaction is rolled back, the xTruncate method of the VFS
+-**     is called to restore the database file to the same size it was at
+-**     the beginning of the transaction.  (In some VFSes, the xTruncate
+-**     method is a no-op, but that does not change the fact the SQLite will
+-**     invoke it.)
+-** 
+-** (9) Whenever the database file is modified, at least one bit in the range
+-**     of bytes from 24 through 39 inclusive will be changed prior to releasing
+-**     the EXCLUSIVE lock, thus signaling other connections on the same
+-**     database to flush their caches.
+-**
+-** (10) The pattern of bits in bytes 24 through 39 shall not repeat in less
+-**      than one billion transactions.
+-**
+-** (11) A database file is well-formed at the beginning and at the conclusion
+-**      of every transaction.
+-**
+-** (12) An EXCLUSIVE lock is held on the database file when writing to
+-**      the database file.
+-**
+-** (13) A SHARED lock is held on the database file while reading any
+-**      content out of the database file.
+-**
+-******************************************************************************/
++    /* We want to verify that szPage and szExtra are the same for pOther
++    ** and pCache.  Assert that we can verify this by comparing sums. */
++    assert( (pCache->szPage & (pCache->szPage-1))==0 && pCache->szPage>=512 );
++    assert( pCache->szExtra<512 );
++    assert( (pOther->szPage & (pOther->szPage-1))==0 && pOther->szPage>=512 );
++    assert( pOther->szExtra<512 );
+ 
+-/*
+-** Macros for troubleshooting.  Normally turned off
+-*/
+-#if 0
+-int sqlite3PagerTrace=1;  /* True to enable tracing */
+-#define sqlite3DebugPrintf printf
+-#define PAGERTRACE(X)     if( sqlite3PagerTrace ){ sqlite3DebugPrintf X; }
+-#else
+-#define PAGERTRACE(X)
+-#endif
++    if( pOther->szPage+pOther->szExtra != pCache->szPage+pCache->szExtra ){
++      pcache1FreePage(pPage);
++      pPage = 0;
++    }else{
++      pGroup->nCurrentPage -= (pOther->bPurgeable - pCache->bPurgeable);
++    }
++  }
+ 
+-/*
+-** The following two macros are used within the PAGERTRACE() macros above
+-** to print out file-descriptors. 
+-**
+-** PAGERID() takes a pointer to a Pager struct as its argument. The
+-** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file
+-** struct as its argument.
+-*/
+-#define PAGERID(p) ((int)(p->fd))
+-#define FILEHANDLEID(fd) ((int)fd)
++  /* Step 5. If a usable page buffer has still not been found, 
++  ** attempt to allocate a new one. 
++  */
++  if( !pPage ){
++    if( createFlag==1 ) sqlite3BeginBenignMalloc();
++    pPage = pcache1AllocPage(pCache);
++    if( createFlag==1 ) sqlite3EndBenignMalloc();
++  }
++
++  if( pPage ){
++    unsigned int h = iKey % pCache->nHash;
++    pCache->nPage++;
++    pPage->iKey = iKey;
++    pPage->pNext = pCache->apHash[h];
++    pPage->pCache = pCache;
++    pPage->pLruPrev = 0;
++    pPage->pLruNext = 0;
++    pPage->isPinned = 1;
++    *(void **)pPage->page.pExtra = 0;
++    pCache->apHash[h] = pPage;
++    if( iKey>pCache->iMaxKey ){
++      pCache->iMaxKey = iKey;
++    }
++  }
++  return pPage;
++}
+ 
+ /*
+-** The Pager.eState variable stores the current 'state' of a pager. A
+-** pager may be in any one of the seven states shown in the following
+-** state diagram.
+-**
+-**                            OPEN <------+------+
+-**                              |         |      |
+-**                              V         |      |
+-**               +---------> READER-------+      |
+-**               |              |                |
+-**               |              V                |
+-**               |<-------WRITER_LOCKED------> ERROR
+-**               |              |                ^  
+-**               |              V                |
+-**               |<------WRITER_CACHEMOD-------->|
+-**               |              |                |
+-**               |              V                |
+-**               |<-------WRITER_DBMOD---------->|
+-**               |              |                |
+-**               |              V                |
+-**               +<------WRITER_FINISHED-------->+
+-**
+-**
+-** List of state transitions and the C [function] that performs each:
+-** 
+-**   OPEN              -> READER              [sqlite3PagerSharedLock]
+-**   READER            -> OPEN                [pager_unlock]
+-**
+-**   READER            -> WRITER_LOCKED       [sqlite3PagerBegin]
+-**   WRITER_LOCKED     -> WRITER_CACHEMOD     [pager_open_journal]
+-**   WRITER_CACHEMOD   -> WRITER_DBMOD        [syncJournal]
+-**   WRITER_DBMOD      -> WRITER_FINISHED     [sqlite3PagerCommitPhaseOne]
+-**   WRITER_***        -> READER              [pager_end_transaction]
+-**
+-**   WRITER_***        -> ERROR               [pager_error]
+-**   ERROR             -> OPEN                [pager_unlock]
+-** 
+-**
+-**  OPEN:
+-**
+-**    The pager starts up in this state. Nothing is guaranteed in this
+-**    state - the file may or may not be locked and the database size is
+-**    unknown. The database may not be read or written.
+-**
+-**    * No read or write transaction is active.
+-**    * Any lock, or no lock at all, may be held on the database file.
+-**    * The dbSize, dbOrigSize and dbFileSize variables may not be trusted.
+-**
+-**  READER:
+-**
+-**    In this state all the requirements for reading the database in 
+-**    rollback (non-WAL) mode are met. Unless the pager is (or recently
+-**    was) in exclusive-locking mode, a user-level read transaction is 
+-**    open. The database size is known in this state.
+-**
+-**    A connection running with locking_mode=normal enters this state when
+-**    it opens a read-transaction on the database and returns to state
+-**    OPEN after the read-transaction is completed. However a connection
+-**    running in locking_mode=exclusive (including temp databases) remains in
+-**    this state even after the read-transaction is closed. The only way
+-**    a locking_mode=exclusive connection can transition from READER to OPEN
+-**    is via the ERROR state (see below).
+-** 
+-**    * A read transaction may be active (but a write-transaction cannot).
+-**    * A SHARED or greater lock is held on the database file.
+-**    * The dbSize variable may be trusted (even if a user-level read 
+-**      transaction is not active). The dbOrigSize and dbFileSize variables
+-**      may not be trusted at this point.
+-**    * If the database is a WAL database, then the WAL connection is open.
+-**    * Even if a read-transaction is not open, it is guaranteed that 
+-**      there is no hot-journal in the file-system.
+-**
+-**  WRITER_LOCKED:
+-**
+-**    The pager moves to this state from READER when a write-transaction
+-**    is first opened on the database. In WRITER_LOCKED state, all locks 
+-**    required to start a write-transaction are held, but no actual 
+-**    modifications to the cache or database have taken place.
+-**
+-**    In rollback mode, a RESERVED or (if the transaction was opened with 
+-**    BEGIN EXCLUSIVE) EXCLUSIVE lock is obtained on the database file when
+-**    moving to this state, but the journal file is not written to or opened 
+-**    to in this state. If the transaction is committed or rolled back while 
+-**    in WRITER_LOCKED state, all that is required is to unlock the database 
+-**    file.
+-**
+-**    IN WAL mode, WalBeginWriteTransaction() is called to lock the log file.
+-**    If the connection is running with locking_mode=exclusive, an attempt
+-**    is made to obtain an EXCLUSIVE lock on the database file.
+-**
+-**    * A write transaction is active.
+-**    * If the connection is open in rollback-mode, a RESERVED or greater 
+-**      lock is held on the database file.
+-**    * If the connection is open in WAL-mode, a WAL write transaction
+-**      is open (i.e. sqlite3WalBeginWriteTransaction() has been successfully
+-**      called).
+-**    * The dbSize, dbOrigSize and dbFileSize variables are all valid.
+-**    * The contents of the pager cache have not been modified.
+-**    * The journal file may or may not be open.
+-**    * Nothing (not even the first header) has been written to the journal.
+-**
+-**  WRITER_CACHEMOD:
+-**
+-**    A pager moves from WRITER_LOCKED state to this state when a page is
+-**    first modified by the upper layer. In rollback mode the journal file
+-**    is opened (if it is not already open) and a header written to the
+-**    start of it. The database file on disk has not been modified.
+-**
+-**    * A write transaction is active.
+-**    * A RESERVED or greater lock is held on the database file.
+-**    * The journal file is open and the first header has been written 
+-**      to it, but the header has not been synced to disk.
+-**    * The contents of the page cache have been modified.
+-**
+-**  WRITER_DBMOD:
+-**
+-**    The pager transitions from WRITER_CACHEMOD into WRITER_DBMOD state
+-**    when it modifies the contents of the database file. WAL connections
+-**    never enter this state (since they do not modify the database file,
+-**    just the log file).
+-**
+-**    * A write transaction is active.
+-**    * An EXCLUSIVE or greater lock is held on the database file.
+-**    * The journal file is open and the first header has been written 
+-**      and synced to disk.
+-**    * The contents of the page cache have been modified (and possibly
+-**      written to disk).
+-**
+-**  WRITER_FINISHED:
+-**
+-**    It is not possible for a WAL connection to enter this state.
+-**
+-**    A rollback-mode pager changes to WRITER_FINISHED state from WRITER_DBMOD
+-**    state after the entire transaction has been successfully written into the
+-**    database file. In this state the transaction may be committed simply
+-**    by finalizing the journal file. Once in WRITER_FINISHED state, it is 
+-**    not possible to modify the database further. At this point, the upper 
+-**    layer must either commit or rollback the transaction.
+-**
+-**    * A write transaction is active.
+-**    * An EXCLUSIVE or greater lock is held on the database file.
+-**    * All writing and syncing of journal and database data has finished.
+-**      If no error occurred, all that remains is to finalize the journal to
+-**      commit the transaction. If an error did occur, the caller will need
+-**      to rollback the transaction. 
+-**
+-**  ERROR:
++** Implementation of the sqlite3_pcache.xFetch method. 
+ **
+-**    The ERROR state is entered when an IO or disk-full error (including
+-**    SQLITE_IOERR_NOMEM) occurs at a point in the code that makes it 
+-**    difficult to be sure that the in-memory pager state (cache contents, 
+-**    db size etc.) are consistent with the contents of the file-system.
++** Fetch a page by key value.
+ **
+-**    Temporary pager files may enter the ERROR state, but in-memory pagers
+-**    cannot.
++** Whether or not a new page may be allocated by this function depends on
++** the value of the createFlag argument.  0 means do not allocate a new
++** page.  1 means allocate a new page if space is easily available.  2 
++** means to try really hard to allocate a new page.
+ **
+-**    For example, if an IO error occurs while performing a rollback, 
+-**    the contents of the page-cache may be left in an inconsistent state.
+-**    At this point it would be dangerous to change back to READER state
+-**    (as usually happens after a rollback). Any subsequent readers might
+-**    report database corruption (due to the inconsistent cache), and if
+-**    they upgrade to writers, they may inadvertently corrupt the database
+-**    file. To avoid this hazard, the pager switches into the ERROR state
+-**    instead of READER following such an error.
++** For a non-purgeable cache (a cache used as the storage for an in-memory
++** database) there is really no difference between createFlag 1 and 2.  So
++** the calling function (pcache.c) will never have a createFlag of 1 on
++** a non-purgeable cache.
+ **
+-**    Once it has entered the ERROR state, any attempt to use the pager
+-**    to read or write data returns an error. Eventually, once all 
+-**    outstanding transactions have been abandoned, the pager is able to
+-**    transition back to OPEN state, discarding the contents of the 
+-**    page-cache and any other in-memory state at the same time. Everything
+-**    is reloaded from disk (and, if necessary, hot-journal rollback peformed)
+-**    when a read-transaction is next opened on the pager (transitioning
+-**    the pager into READER state). At that point the system has recovered 
+-**    from the error.
++** There are three different approaches to obtaining space for a page,
++** depending on the value of parameter createFlag (which may be 0, 1 or 2).
+ **
+-**    Specifically, the pager jumps into the ERROR state if:
++**   1. Regardless of the value of createFlag, the cache is searched for a 
++**      copy of the requested page. If one is found, it is returned.
+ **
+-**      1. An error occurs while attempting a rollback. This happens in
+-**         function sqlite3PagerRollback().
++**   2. If createFlag==0 and the page is not already in the cache, NULL is
++**      returned.
+ **
+-**      2. An error occurs while attempting to finalize a journal file
+-**         following a commit in function sqlite3PagerCommitPhaseTwo().
++**   3. If createFlag is 1, and the page is not already in the cache, then
++**      return NULL (do not allocate a new page) if any of the following
++**      conditions are true:
+ **
+-**      3. An error occurs while attempting to write to the journal or
+-**         database file in function pagerStress() in order to free up
+-**         memory.
++**       (a) the number of pages pinned by the cache is greater than
++**           PCache1.nMax, or
+ **
+-**    In other cases, the error is returned to the b-tree layer. The b-tree
+-**    layer then attempts a rollback operation. If the error condition 
+-**    persists, the pager enters the ERROR state via condition (1) above.
++**       (b) the number of pages pinned by the cache is greater than
++**           the sum of nMax for all purgeable caches, less the sum of 
++**           nMin for all other purgeable caches, or
+ **
+-**    Condition (3) is necessary because it can be triggered by a read-only
+-**    statement executed within a transaction. In this case, if the error
+-**    code were simply returned to the user, the b-tree layer would not
+-**    automatically attempt a rollback, as it assumes that an error in a
+-**    read-only statement cannot leave the pager in an internally inconsistent 
+-**    state.
++**   4. If none of the first three conditions apply and the cache is marked
++**      as purgeable, and if one of the following is true:
+ **
+-**    * The Pager.errCode variable is set to something other than SQLITE_OK.
+-**    * There are one or more outstanding references to pages (after the
+-**      last reference is dropped the pager should move back to OPEN state).
+-**    * The pager is not an in-memory pager.
+-**    
++**       (a) The number of pages allocated for the cache is already 
++**           PCache1.nMax, or
+ **
+-** Notes:
++**       (b) The number of pages allocated for all purgeable caches is
++**           already equal to or greater than the sum of nMax for all
++**           purgeable caches,
+ **
+-**   * A pager is never in WRITER_DBMOD or WRITER_FINISHED state if the
+-**     connection is open in WAL mode. A WAL connection is always in one
+-**     of the first four states.
++**       (c) The system is under memory pressure and wants to avoid
++**           unnecessary pages cache entry allocations
+ **
+-**   * Normally, a connection open in exclusive mode is never in PAGER_OPEN
+-**     state. There are two exceptions: immediately after exclusive-mode has
+-**     been turned on (and before any read or write transactions are 
+-**     executed), and when the pager is leaving the "error state".
++**      then attempt to recycle a page from the LRU list. If it is the right
++**      size, return the recycled buffer. Otherwise, free the buffer and
++**      proceed to step 5. 
+ **
+-**   * See also: assert_pager_state().
++**   5. Otherwise, allocate and return a new page buffer.
+ */
+-#define PAGER_OPEN                  0
+-#define PAGER_READER                1
+-#define PAGER_WRITER_LOCKED         2
+-#define PAGER_WRITER_CACHEMOD       3
+-#define PAGER_WRITER_DBMOD          4
+-#define PAGER_WRITER_FINISHED       5
+-#define PAGER_ERROR                 6
++static sqlite3_pcache_page *pcache1Fetch(
++  sqlite3_pcache *p, 
++  unsigned int iKey, 
++  int createFlag
++){
++  PCache1 *pCache = (PCache1 *)p;
++  PgHdr1 *pPage = 0;
++
++  assert( offsetof(PgHdr1,page)==0 );
++  assert( pCache->bPurgeable || createFlag!=1 );
++  assert( pCache->bPurgeable || pCache->nMin==0 );
++  assert( pCache->bPurgeable==0 || pCache->nMin==10 );
++  assert( pCache->nMin==0 || pCache->bPurgeable );
++  assert( pCache->nHash>0 );
++  pcache1EnterMutex(pCache->pGroup);
++
++  /* Step 1: Search the hash table for an existing entry. */
++  pPage = pCache->apHash[iKey % pCache->nHash];
++  while( pPage && pPage->iKey!=iKey ){ pPage = pPage->pNext; }
++
++  /* Step 2: Abort if no existing page is found and createFlag is 0 */
++  if( pPage ){
++    if( !pPage->isPinned ) pcache1PinPage(pPage);
++  }else if( createFlag ){
++    /* Steps 3, 4, and 5 implemented by this subroutine */
++    pPage = pcache1FetchStage2(pCache, iKey, createFlag);
++  }
++  assert( pPage==0 || pCache->iMaxKey>=iKey );
++  pcache1LeaveMutex(pCache->pGroup);
++  return (sqlite3_pcache_page*)pPage;
++}
++
+ 
+ /*
+-** The Pager.eLock variable is almost always set to one of the 
+-** following locking-states, according to the lock currently held on
+-** the database file: NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK.
+-** This variable is kept up to date as locks are taken and released by
+-** the pagerLockDb() and pagerUnlockDb() wrappers.
+-**
+-** If the VFS xLock() or xUnlock() returns an error other than SQLITE_BUSY
+-** (i.e. one of the SQLITE_IOERR subtypes), it is not clear whether or not
+-** the operation was successful. In these circumstances pagerLockDb() and
+-** pagerUnlockDb() take a conservative approach - eLock is always updated
+-** when unlocking the file, and only updated when locking the file if the
+-** VFS call is successful. This way, the Pager.eLock variable may be set
+-** to a less exclusive (lower) value than the lock that is actually held
+-** at the system level, but it is never set to a more exclusive value.
+-**
+-** This is usually safe. If an xUnlock fails or appears to fail, there may 
+-** be a few redundant xLock() calls or a lock may be held for longer than
+-** required, but nothing really goes wrong.
+-**
+-** The exception is when the database file is unlocked as the pager moves
+-** from ERROR to OPEN state. At this point there may be a hot-journal file 
+-** in the file-system that needs to be rolled back (as part of an OPEN->SHARED
+-** transition, by the same pager or any other). If the call to xUnlock()
+-** fails at this point and the pager is left holding an EXCLUSIVE lock, this
+-** can confuse the call to xCheckReservedLock() call made later as part
+-** of hot-journal detection.
++** Implementation of the sqlite3_pcache.xUnpin method.
+ **
+-** xCheckReservedLock() is defined as returning true "if there is a RESERVED 
+-** lock held by this process or any others". So xCheckReservedLock may 
+-** return true because the caller itself is holding an EXCLUSIVE lock (but
+-** doesn't know it because of a previous error in xUnlock). If this happens
+-** a hot-journal may be mistaken for a journal being created by an active
+-** transaction in another process, causing SQLite to read from the database
+-** without rolling it back.
++** Mark a page as unpinned (eligible for asynchronous recycling).
++*/
++static void pcache1Unpin(
++  sqlite3_pcache *p, 
++  sqlite3_pcache_page *pPg, 
++  int reuseUnlikely
++){
++  PCache1 *pCache = (PCache1 *)p;
++  PgHdr1 *pPage = (PgHdr1 *)pPg;
++  PGroup *pGroup = pCache->pGroup;
++ 
++  assert( pPage->pCache==pCache );
++  pcache1EnterMutex(pGroup);
++
++  /* It is an error to call this function if the page is already 
++  ** part of the PGroup LRU list.
++  */
++  assert( pPage->pLruPrev==0 && pPage->pLruNext==0 );
++  assert( pGroup->pLruHead!=pPage && pGroup->pLruTail!=pPage );
++  assert( pPage->isPinned==1 );
++
++  if( reuseUnlikely || pGroup->nCurrentPage>pGroup->nMaxPage ){
++    pcache1RemoveFromHash(pPage);
++    pcache1FreePage(pPage);
++  }else{
++    /* Add the page to the PGroup LRU list. */
++    if( pGroup->pLruHead ){
++      pGroup->pLruHead->pLruPrev = pPage;
++      pPage->pLruNext = pGroup->pLruHead;
++      pGroup->pLruHead = pPage;
++    }else{
++      pGroup->pLruTail = pPage;
++      pGroup->pLruHead = pPage;
++    }
++    pCache->nRecyclable++;
++    pPage->isPinned = 0;
++  }
++
++  pcache1LeaveMutex(pCache->pGroup);
++}
++
++/*
++** Implementation of the sqlite3_pcache.xRekey method. 
++*/
++static void pcache1Rekey(
++  sqlite3_pcache *p,
++  sqlite3_pcache_page *pPg,
++  unsigned int iOld,
++  unsigned int iNew
++){
++  PCache1 *pCache = (PCache1 *)p;
++  PgHdr1 *pPage = (PgHdr1 *)pPg;
++  PgHdr1 **pp;
++  unsigned int h; 
++  assert( pPage->iKey==iOld );
++  assert( pPage->pCache==pCache );
++
++  pcache1EnterMutex(pCache->pGroup);
++
++  h = iOld%pCache->nHash;
++  pp = &pCache->apHash[h];
++  while( (*pp)!=pPage ){
++    pp = &(*pp)->pNext;
++  }
++  *pp = pPage->pNext;
++
++  h = iNew%pCache->nHash;
++  pPage->iKey = iNew;
++  pPage->pNext = pCache->apHash[h];
++  pCache->apHash[h] = pPage;
++  if( iNew>pCache->iMaxKey ){
++    pCache->iMaxKey = iNew;
++  }
++
++  pcache1LeaveMutex(pCache->pGroup);
++}
++
++/*
++** Implementation of the sqlite3_pcache.xTruncate method. 
+ **
+-** To work around this, if a call to xUnlock() fails when unlocking the
+-** database in the ERROR state, Pager.eLock is set to UNKNOWN_LOCK. It
+-** is only changed back to a real locking state after a successful call
+-** to xLock(EXCLUSIVE). Also, the code to do the OPEN->SHARED state transition
+-** omits the check for a hot-journal if Pager.eLock is set to UNKNOWN_LOCK 
+-** lock. Instead, it assumes a hot-journal exists and obtains an EXCLUSIVE
+-** lock on the database file before attempting to roll it back. See function
+-** PagerSharedLock() for more detail.
++** Discard all unpinned pages in the cache with a page number equal to
++** or greater than parameter iLimit. Any pinned pages with a page number
++** equal to or greater than iLimit are implicitly unpinned.
++*/
++static void pcache1Truncate(sqlite3_pcache *p, unsigned int iLimit){
++  PCache1 *pCache = (PCache1 *)p;
++  pcache1EnterMutex(pCache->pGroup);
++  if( iLimit<=pCache->iMaxKey ){
++    pcache1TruncateUnsafe(pCache, iLimit);
++    pCache->iMaxKey = iLimit-1;
++  }
++  pcache1LeaveMutex(pCache->pGroup);
++}
++
++/*
++** Implementation of the sqlite3_pcache.xDestroy method. 
+ **
+-** Pager.eLock may only be set to UNKNOWN_LOCK when the pager is in 
+-** PAGER_OPEN state.
++** Destroy a cache allocated using pcache1Create().
+ */
+-#define UNKNOWN_LOCK                (EXCLUSIVE_LOCK+1)
++static void pcache1Destroy(sqlite3_pcache *p){
++  PCache1 *pCache = (PCache1 *)p;
++  PGroup *pGroup = pCache->pGroup;
++  assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) );
++  pcache1EnterMutex(pGroup);
++  pcache1TruncateUnsafe(pCache, 0);
++  assert( pGroup->nMaxPage >= pCache->nMax );
++  pGroup->nMaxPage -= pCache->nMax;
++  assert( pGroup->nMinPage >= pCache->nMin );
++  pGroup->nMinPage -= pCache->nMin;
++  pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
++  pcache1EnforceMaxPage(pGroup);
++  pcache1LeaveMutex(pGroup);
++  sqlite3_free(pCache->apHash);
++  sqlite3_free(pCache);
++}
+ 
+ /*
+-** A macro used for invoking the codec if there is one
++** This function is called during initialization (sqlite3_initialize()) to
++** install the default pluggable cache module, assuming the user has not
++** already provided an alternative.
++*/
++SQLITE_PRIVATE void sqlite3PCacheSetDefault(void){
++  static const sqlite3_pcache_methods2 defaultMethods = {
++    1,                       /* iVersion */
++    0,                       /* pArg */
++    pcache1Init,             /* xInit */
++    pcache1Shutdown,         /* xShutdown */
++    pcache1Create,           /* xCreate */
++    pcache1Cachesize,        /* xCachesize */
++    pcache1Pagecount,        /* xPagecount */
++    pcache1Fetch,            /* xFetch */
++    pcache1Unpin,            /* xUnpin */
++    pcache1Rekey,            /* xRekey */
++    pcache1Truncate,         /* xTruncate */
++    pcache1Destroy,          /* xDestroy */
++    pcache1Shrink            /* xShrink */
++  };
++  sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods);
++}
++
++/*
++** Return the size of the header on each page of this PCACHE implementation.
+ */
+-#ifdef SQLITE_HAS_CODEC
+-# define CODEC1(P,D,N,X,E) \
+-    if( P->xCodec && P->xCodec(P->pCodec,D,N,X)==0 ){ E; }
+-# define CODEC2(P,D,N,X,E,O) \
+-    if( P->xCodec==0 ){ O=(char*)D; }else \
+-    if( (O=(char*)(P->xCodec(P->pCodec,D,N,X)))==0 ){ E; }
+-#else
+-# define CODEC1(P,D,N,X,E)   /* NO-OP */
+-# define CODEC2(P,D,N,X,E,O) O=(char*)D
+-#endif
++SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void){ return ROUND8(sizeof(PgHdr1)); }
+ 
+ /*
+-** The maximum allowed sector size. 64KiB. If the xSectorsize() method 
+-** returns a value larger than this, then MAX_SECTOR_SIZE is used instead.
+-** This could conceivably cause corruption following a power failure on
+-** such a system. This is currently an undocumented limit.
++** Return the global mutex used by this PCACHE implementation.  The
++** sqlite3_status() routine needs access to this mutex.
+ */
+-#define MAX_SECTOR_SIZE 0x10000
++SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void){
++  return pcache1.mutex;
++}
+ 
++#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+ /*
+-** An instance of the following structure is allocated for each active
+-** savepoint and statement transaction in the system. All such structures
+-** are stored in the Pager.aSavepoint[] array, which is allocated and
+-** resized using sqlite3Realloc().
++** This function is called to free superfluous dynamically allocated memory
++** held by the pager system. Memory in use by any SQLite pager allocated
++** by the current thread may be sqlite3_free()ed.
+ **
+-** When a savepoint is created, the PagerSavepoint.iHdrOffset field is
+-** set to 0. If a journal-header is written into the main journal while
+-** the savepoint is active, then iHdrOffset is set to the byte offset 
+-** immediately following the last journal record written into the main
+-** journal before the journal-header. This is required during savepoint
+-** rollback (see pagerPlaybackSavepoint()).
++** nReq is the number of bytes of memory required. Once this much has
++** been released, the function returns. The return value is the total number 
++** of bytes of memory released.
+ */
+-typedef struct PagerSavepoint PagerSavepoint;
+-struct PagerSavepoint {
+-  i64 iOffset;                 /* Starting offset in main journal */
+-  i64 iHdrOffset;              /* See above */
+-  Bitvec *pInSavepoint;        /* Set of pages in this savepoint */
+-  Pgno nOrig;                  /* Original number of pages in file */
+-  Pgno iSubRec;                /* Index of first record in sub-journal */
+-#ifndef SQLITE_OMIT_WAL
+-  u32 aWalData[WAL_SAVEPOINT_NDATA];        /* WAL savepoint context */
++SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){
++  int nFree = 0;
++  assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
++  assert( sqlite3_mutex_notheld(pcache1.mutex) );
++  if( pcache1.pStart==0 ){
++    PgHdr1 *p;
++    pcache1EnterMutex(&pcache1.grp);
++    while( (nReq<0 || nFree<nReq) && ((p=pcache1.grp.pLruTail)!=0) ){
++      nFree += pcache1MemSize(p->page.pBuf);
++#ifdef SQLITE_PCACHE_SEPARATE_HEADER
++      nFree += sqlite3MemSize(p);
+ #endif
+-};
++      assert( p->isPinned==0 );
++      pcache1PinPage(p);
++      pcache1RemoveFromHash(p);
++      pcache1FreePage(p);
++    }
++    pcache1LeaveMutex(&pcache1.grp);
++  }
++  return nFree;
++}
++#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
+ 
++#ifdef SQLITE_TEST
+ /*
+-** Bits of the Pager.doNotSpill flag.  See further description below.
++** This function is used by test procedures to inspect the internal state
++** of the global cache.
+ */
+-#define SPILLFLAG_OFF         0x01      /* Never spill cache.  Set via pragma */
+-#define SPILLFLAG_ROLLBACK    0x02      /* Current rolling back, so do not spill */
+-#define SPILLFLAG_NOSYNC      0x04      /* Spill is ok, but do not sync */
++SQLITE_PRIVATE void sqlite3PcacheStats(
++  int *pnCurrent,      /* OUT: Total number of pages cached */
++  int *pnMax,          /* OUT: Global maximum cache size */
++  int *pnMin,          /* OUT: Sum of PCache1.nMin for purgeable caches */
++  int *pnRecyclable    /* OUT: Total number of pages available for recycling */
++){
++  PgHdr1 *p;
++  int nRecyclable = 0;
++  for(p=pcache1.grp.pLruHead; p; p=p->pLruNext){
++    assert( p->isPinned==0 );
++    nRecyclable++;
++  }
++  *pnCurrent = pcache1.grp.nCurrentPage;
++  *pnMax = (int)pcache1.grp.nMaxPage;
++  *pnMin = (int)pcache1.grp.nMinPage;
++  *pnRecyclable = nRecyclable;
++}
++#endif
+ 
++/************** End of pcache1.c *********************************************/
++/************** Begin file rowset.c ******************************************/
+ /*
+-** An open page cache is an instance of struct Pager. A description of
+-** some of the more important member variables follows:
+-**
+-** eState
+-**
+-**   The current 'state' of the pager object. See the comment and state
+-**   diagram above for a description of the pager state.
+-**
+-** eLock
+-**
+-**   For a real on-disk database, the current lock held on the database file -
+-**   NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK.
+-**
+-**   For a temporary or in-memory database (neither of which require any
+-**   locks), this variable is always set to EXCLUSIVE_LOCK. Since such
+-**   databases always have Pager.exclusiveMode==1, this tricks the pager
+-**   logic into thinking that it already has all the locks it will ever
+-**   need (and no reason to release them).
+-**
+-**   In some (obscure) circumstances, this variable may also be set to
+-**   UNKNOWN_LOCK. See the comment above the #define of UNKNOWN_LOCK for
+-**   details.
+-**
+-** changeCountDone
+-**
+-**   This boolean variable is used to make sure that the change-counter 
+-**   (the 4-byte header field at byte offset 24 of the database file) is 
+-**   not updated more often than necessary. 
+-**
+-**   It is set to true when the change-counter field is updated, which 
+-**   can only happen if an exclusive lock is held on the database file.
+-**   It is cleared (set to false) whenever an exclusive lock is 
+-**   relinquished on the database file. Each time a transaction is committed,
+-**   The changeCountDone flag is inspected. If it is true, the work of
+-**   updating the change-counter is omitted for the current transaction.
+-**
+-**   This mechanism means that when running in exclusive mode, a connection 
+-**   need only update the change-counter once, for the first transaction
+-**   committed.
+-**
+-** setMaster
+-**
+-**   When PagerCommitPhaseOne() is called to commit a transaction, it may
+-**   (or may not) specify a master-journal name to be written into the 
+-**   journal file before it is synced to disk.
+-**
+-**   Whether or not a journal file contains a master-journal pointer affects 
+-**   the way in which the journal file is finalized after the transaction is 
+-**   committed or rolled back when running in "journal_mode=PERSIST" mode.
+-**   If a journal file does not contain a master-journal pointer, it is
+-**   finalized by overwriting the first journal header with zeroes. If
+-**   it does contain a master-journal pointer the journal file is finalized 
+-**   by truncating it to zero bytes, just as if the connection were 
+-**   running in "journal_mode=truncate" mode.
+-**
+-**   Journal files that contain master journal pointers cannot be finalized
+-**   simply by overwriting the first journal-header with zeroes, as the
+-**   master journal pointer could interfere with hot-journal rollback of any
+-**   subsequently interrupted transaction that reuses the journal file.
+-**
+-**   The flag is cleared as soon as the journal file is finalized (either
+-**   by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the
+-**   journal file from being successfully finalized, the setMaster flag
+-**   is cleared anyway (and the pager will move to ERROR state).
+-**
+-** doNotSpill
+-**
+-**   This variables control the behavior of cache-spills  (calls made by
+-**   the pcache module to the pagerStress() routine to write cached data
+-**   to the file-system in order to free up memory).
++** 2008 December 3
+ **
+-**   When bits SPILLFLAG_OFF or SPILLFLAG_ROLLBACK of doNotSpill are set,
+-**   writing to the database from pagerStress() is disabled altogether.
+-**   The SPILLFLAG_ROLLBACK case is done in a very obscure case that
+-**   comes up during savepoint rollback that requires the pcache module
+-**   to allocate a new page to prevent the journal file from being written
+-**   while it is being traversed by code in pager_playback().  The SPILLFLAG_OFF
+-**   case is a user preference.
+-** 
+-**   If the SPILLFLAG_NOSYNC bit is set, writing to the database from pagerStress()
+-**   is permitted, but syncing the journal file is not. This flag is set
+-**   by sqlite3PagerWrite() when the file-system sector-size is larger than
+-**   the database page-size in order to prevent a journal sync from happening 
+-**   in between the journalling of two pages on the same sector. 
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
+ **
+-** subjInMemory
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
+ **
+-**   This is a boolean variable. If true, then any required sub-journal
+-**   is opened as an in-memory journal file. If false, then in-memory
+-**   sub-journals are only used for in-memory pager files.
++*************************************************************************
+ **
+-**   This variable is updated by the upper layer each time a new 
+-**   write-transaction is opened.
++** This module implements an object we call a "RowSet".
+ **
+-** dbSize, dbOrigSize, dbFileSize
++** The RowSet object is a collection of rowids.  Rowids
++** are inserted into the RowSet in an arbitrary order.  Inserts
++** can be intermixed with tests to see if a given rowid has been
++** previously inserted into the RowSet.
+ **
+-**   Variable dbSize is set to the number of pages in the database file.
+-**   It is valid in PAGER_READER and higher states (all states except for
+-**   OPEN and ERROR). 
++** After all inserts are finished, it is possible to extract the
++** elements of the RowSet in sorted order.  Once this extraction
++** process has started, no new elements may be inserted.
+ **
+-**   dbSize is set based on the size of the database file, which may be 
+-**   larger than the size of the database (the value stored at offset
+-**   28 of the database header by the btree). If the size of the file
+-**   is not an integer multiple of the page-size, the value stored in
+-**   dbSize is rounded down (i.e. a 5KB file with 2K page-size has dbSize==2).
+-**   Except, any file that is greater than 0 bytes in size is considered
+-**   to have at least one page. (i.e. a 1KB file with 2K page-size leads
+-**   to dbSize==1).
++** Hence, the primitive operations for a RowSet are:
+ **
+-**   During a write-transaction, if pages with page-numbers greater than
+-**   dbSize are modified in the cache, dbSize is updated accordingly.
+-**   Similarly, if the database is truncated using PagerTruncateImage(), 
+-**   dbSize is updated.
++**    CREATE
++**    INSERT
++**    TEST
++**    SMALLEST
++**    DESTROY
+ **
+-**   Variables dbOrigSize and dbFileSize are valid in states 
+-**   PAGER_WRITER_LOCKED and higher. dbOrigSize is a copy of the dbSize
+-**   variable at the start of the transaction. It is used during rollback,
+-**   and to determine whether or not pages need to be journalled before
+-**   being modified.
++** The CREATE and DESTROY primitives are the constructor and destructor,
++** obviously.  The INSERT primitive adds a new element to the RowSet.
++** TEST checks to see if an element is already in the RowSet.  SMALLEST
++** extracts the least value from the RowSet.
+ **
+-**   Throughout a write-transaction, dbFileSize contains the size of
+-**   the file on disk in pages. It is set to a copy of dbSize when the
+-**   write-transaction is first opened, and updated when VFS calls are made
+-**   to write or truncate the database file on disk. 
++** The INSERT primitive might allocate additional memory.  Memory is
++** allocated in chunks so most INSERTs do no allocation.  There is an 
++** upper bound on the size of allocated memory.  No memory is freed
++** until DESTROY.
+ **
+-**   The only reason the dbFileSize variable is required is to suppress 
+-**   unnecessary calls to xTruncate() after committing a transaction. If, 
+-**   when a transaction is committed, the dbFileSize variable indicates 
+-**   that the database file is larger than the database image (Pager.dbSize), 
+-**   pager_truncate() is called. The pager_truncate() call uses xFilesize()
+-**   to measure the database file on disk, and then truncates it if required.
+-**   dbFileSize is not used when rolling back a transaction. In this case
+-**   pager_truncate() is called unconditionally (which means there may be
+-**   a call to xFilesize() that is not strictly required). In either case,
+-**   pager_truncate() may cause the file to become smaller or larger.
++** The TEST primitive includes a "batch" number.  The TEST primitive
++** will only see elements that were inserted before the last change
++** in the batch number.  In other words, if an INSERT occurs between
++** two TESTs where the TESTs have the same batch nubmer, then the
++** value added by the INSERT will not be visible to the second TEST.
++** The initial batch number is zero, so if the very first TEST contains
++** a non-zero batch number, it will see all prior INSERTs.
+ **
+-** dbHintSize
++** No INSERTs may occurs after a SMALLEST.  An assertion will fail if
++** that is attempted.
+ **
+-**   The dbHintSize variable is used to limit the number of calls made to
+-**   the VFS xFileControl(FCNTL_SIZE_HINT) method. 
++** The cost of an INSERT is roughly constant.  (Sometimes new memory
++** has to be allocated on an INSERT.)  The cost of a TEST with a new
++** batch number is O(NlogN) where N is the number of elements in the RowSet.
++** The cost of a TEST using the same batch number is O(logN).  The cost
++** of the first SMALLEST is O(NlogN).  Second and subsequent SMALLEST
++** primitives are constant time.  The cost of DESTROY is O(N).
+ **
+-**   dbHintSize is set to a copy of the dbSize variable when a
+-**   write-transaction is opened (at the same time as dbFileSize and
+-**   dbOrigSize). If the xFileControl(FCNTL_SIZE_HINT) method is called,
+-**   dbHintSize is increased to the number of pages that correspond to the
+-**   size-hint passed to the method call. See pager_write_pagelist() for 
+-**   details.
++** There is an added cost of O(N) when switching between TEST and
++** SMALLEST primitives.
++*/
++
++
++/*
++** Target size for allocation chunks.
++*/
++#define ROWSET_ALLOCATION_SIZE 1024
++
++/*
++** The number of rowset entries per allocation chunk.
++*/
++#define ROWSET_ENTRY_PER_CHUNK  \
++                       ((ROWSET_ALLOCATION_SIZE-8)/sizeof(struct RowSetEntry))
++
++/*
++** Each entry in a RowSet is an instance of the following object.
+ **
+-** errCode
++** This same object is reused to store a linked list of trees of RowSetEntry
++** objects.  In that alternative use, pRight points to the next entry
++** in the list, pLeft points to the tree, and v is unused.  The
++** RowSet.pForest value points to the head of this forest list.
++*/
++struct RowSetEntry {            
++  i64 v;                        /* ROWID value for this entry */
++  struct RowSetEntry *pRight;   /* Right subtree (larger entries) or list */
++  struct RowSetEntry *pLeft;    /* Left subtree (smaller entries) */
++};
++
++/*
++** RowSetEntry objects are allocated in large chunks (instances of the
++** following structure) to reduce memory allocation overhead.  The
++** chunks are kept on a linked list so that they can be deallocated
++** when the RowSet is destroyed.
++*/
++struct RowSetChunk {
++  struct RowSetChunk *pNextChunk;        /* Next chunk on list of them all */
++  struct RowSetEntry aEntry[ROWSET_ENTRY_PER_CHUNK]; /* Allocated entries */
++};
++
++/*
++** A RowSet in an instance of the following structure.
+ **
+-**   The Pager.errCode variable is only ever used in PAGER_ERROR state. It
+-**   is set to zero in all other states. In PAGER_ERROR state, Pager.errCode 
+-**   is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX 
+-**   sub-codes.
++** A typedef of this structure if found in sqliteInt.h.
+ */
+-struct Pager {
+-  sqlite3_vfs *pVfs;          /* OS functions to use for IO */
+-  u8 exclusiveMode;           /* Boolean. True if locking_mode==EXCLUSIVE */
+-  u8 journalMode;             /* One of the PAGER_JOURNALMODE_* values */
+-  u8 useJournal;              /* Use a rollback journal on this file */
+-  u8 noSync;                  /* Do not sync the journal if true */
+-  u8 fullSync;                /* Do extra syncs of the journal for robustness */
+-  u8 ckptSyncFlags;           /* SYNC_NORMAL or SYNC_FULL for checkpoint */
+-  u8 walSyncFlags;            /* SYNC_NORMAL or SYNC_FULL for wal writes */
+-  u8 syncFlags;               /* SYNC_NORMAL or SYNC_FULL otherwise */
+-  u8 tempFile;                /* zFilename is a temporary or immutable file */
+-  u8 noLock;                  /* Do not lock (except in WAL mode) */
+-  u8 readOnly;                /* True for a read-only database */
+-  u8 memDb;                   /* True to inhibit all file I/O */
++struct RowSet {
++  struct RowSetChunk *pChunk;    /* List of all chunk allocations */
++  sqlite3 *db;                   /* The database connection */
++  struct RowSetEntry *pEntry;    /* List of entries using pRight */
++  struct RowSetEntry *pLast;     /* Last entry on the pEntry list */
++  struct RowSetEntry *pFresh;    /* Source of new entry objects */
++  struct RowSetEntry *pForest;   /* List of binary trees of entries */
++  u16 nFresh;                    /* Number of objects on pFresh */
++  u16 rsFlags;                   /* Various flags */
++  int iBatch;                    /* Current insert batch */
++};
+ 
+-  /**************************************************************************
+-  ** The following block contains those class members that change during
+-  ** routine operation.  Class members not in this block are either fixed
+-  ** when the pager is first created or else only change when there is a
+-  ** significant mode change (such as changing the page_size, locking_mode,
+-  ** or the journal_mode).  From another view, these class members describe
+-  ** the "state" of the pager, while other class members describe the
+-  ** "configuration" of the pager.
+-  */
+-  u8 eState;                  /* Pager state (OPEN, READER, WRITER_LOCKED..) */
+-  u8 eLock;                   /* Current lock held on database file */
+-  u8 changeCountDone;         /* Set after incrementing the change-counter */
+-  u8 setMaster;               /* True if a m-j name has been written to jrnl */
+-  u8 doNotSpill;              /* Do not spill the cache when non-zero */
+-  u8 subjInMemory;            /* True to use in-memory sub-journals */
+-  u8 bUseFetch;               /* True to use xFetch() */
+-  u8 hasBeenUsed;             /* True if any content previously read from this pager*/
+-  Pgno dbSize;                /* Number of pages in the database */
+-  Pgno dbOrigSize;            /* dbSize before the current transaction */
+-  Pgno dbFileSize;            /* Number of pages in the database file */
+-  Pgno dbHintSize;            /* Value passed to FCNTL_SIZE_HINT call */
+-  int errCode;                /* One of several kinds of errors */
+-  int nRec;                   /* Pages journalled since last j-header written */
+-  u32 cksumInit;              /* Quasi-random value added to every checksum */
+-  u32 nSubRec;                /* Number of records written to sub-journal */
+-  Bitvec *pInJournal;         /* One bit for each page in the database file */
+-  sqlite3_file *fd;           /* File descriptor for database */
+-  sqlite3_file *jfd;          /* File descriptor for main journal */
+-  sqlite3_file *sjfd;         /* File descriptor for sub-journal */
+-  i64 journalOff;             /* Current write offset in the journal file */
+-  i64 journalHdr;             /* Byte offset to previous journal header */
+-  sqlite3_backup *pBackup;    /* Pointer to list of ongoing backup processes */
+-  PagerSavepoint *aSavepoint; /* Array of active savepoints */
+-  int nSavepoint;             /* Number of elements in aSavepoint[] */
+-  u32 iDataVersion;           /* Changes whenever database content changes */
+-  char dbFileVers[16];        /* Changes whenever database file changes */
++/*
++** Allowed values for RowSet.rsFlags
++*/
++#define ROWSET_SORTED  0x01   /* True if RowSet.pEntry is sorted */
++#define ROWSET_NEXT    0x02   /* True if sqlite3RowSetNext() has been called */
+ 
+-  int nMmapOut;               /* Number of mmap pages currently outstanding */
+-  sqlite3_int64 szMmap;       /* Desired maximum mmap size */
+-  PgHdr *pMmapFreelist;       /* List of free mmap page headers (pDirty) */
+-  /*
+-  ** End of the routinely-changing class members
+-  ***************************************************************************/
++/*
++** Turn bulk memory into a RowSet object.  N bytes of memory
++** are available at pSpace.  The db pointer is used as a memory context
++** for any subsequent allocations that need to occur.
++** Return a pointer to the new RowSet object.
++**
++** It must be the case that N is sufficient to make a Rowset.  If not
++** an assertion fault occurs.
++** 
++** If N is larger than the minimum, use the surplus as an initial
++** allocation of entries available to be filled.
++*/
++SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db, void *pSpace, unsigned int N){
++  RowSet *p;
++  assert( N >= ROUND8(sizeof(*p)) );
++  p = pSpace;
++  p->pChunk = 0;
++  p->db = db;
++  p->pEntry = 0;
++  p->pLast = 0;
++  p->pForest = 0;
++  p->pFresh = (struct RowSetEntry*)(ROUND8(sizeof(*p)) + (char*)p);
++  p->nFresh = (u16)((N - ROUND8(sizeof(*p)))/sizeof(struct RowSetEntry));
++  p->rsFlags = ROWSET_SORTED;
++  p->iBatch = 0;
++  return p;
++}
+ 
+-  u16 nExtra;                 /* Add this many bytes to each in-memory page */
+-  i16 nReserve;               /* Number of unused bytes at end of each page */
+-  u32 vfsFlags;               /* Flags for sqlite3_vfs.xOpen() */
+-  u32 sectorSize;             /* Assumed sector size during rollback */
+-  int pageSize;               /* Number of bytes in a page */
+-  Pgno mxPgno;                /* Maximum allowed size of the database */
+-  i64 journalSizeLimit;       /* Size limit for persistent journal files */
+-  char *zFilename;            /* Name of the database file */
+-  char *zJournal;             /* Name of the journal file */
+-  int (*xBusyHandler)(void*); /* Function to call when busy */
+-  void *pBusyHandlerArg;      /* Context argument for xBusyHandler */
+-  int aStat[3];               /* Total cache hits, misses and writes */
+-#ifdef SQLITE_TEST
+-  int nRead;                  /* Database pages read */
+-#endif
+-  void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */
+-#ifdef SQLITE_HAS_CODEC
+-  void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
+-  void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */
+-  void (*xCodecFree)(void*);             /* Destructor for the codec */
+-  void *pCodec;               /* First argument to xCodec... methods */
+-#endif
+-  char *pTmpSpace;            /* Pager.pageSize bytes of space for tmp use */
+-  PCache *pPCache;            /* Pointer to page cache object */
+-#ifndef SQLITE_OMIT_WAL
+-  Wal *pWal;                  /* Write-ahead log used by "journal_mode=wal" */
+-  char *zWal;                 /* File name for write-ahead log */
+-#endif
+-};
++/*
++** Deallocate all chunks from a RowSet.  This frees all memory that
++** the RowSet has allocated over its lifetime.  This routine is
++** the destructor for the RowSet.
++*/
++SQLITE_PRIVATE void sqlite3RowSetClear(RowSet *p){
++  struct RowSetChunk *pChunk, *pNextChunk;
++  for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){
++    pNextChunk = pChunk->pNextChunk;
++    sqlite3DbFree(p->db, pChunk);
++  }
++  p->pChunk = 0;
++  p->nFresh = 0;
++  p->pEntry = 0;
++  p->pLast = 0;
++  p->pForest = 0;
++  p->rsFlags = ROWSET_SORTED;
++}
+ 
+ /*
+-** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains
+-** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS 
+-** or CACHE_WRITE to sqlite3_db_status().
++** Allocate a new RowSetEntry object that is associated with the
++** given RowSet.  Return a pointer to the new and completely uninitialized
++** objected.
++**
++** In an OOM situation, the RowSet.db->mallocFailed flag is set and this
++** routine returns NULL.
+ */
+-#define PAGER_STAT_HIT   0
+-#define PAGER_STAT_MISS  1
+-#define PAGER_STAT_WRITE 2
++static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){
++  assert( p!=0 );
++  if( p->nFresh==0 ){
++    struct RowSetChunk *pNew;
++    pNew = sqlite3DbMallocRaw(p->db, sizeof(*pNew));
++    if( pNew==0 ){
++      return 0;
++    }
++    pNew->pNextChunk = p->pChunk;
++    p->pChunk = pNew;
++    p->pFresh = pNew->aEntry;
++    p->nFresh = ROWSET_ENTRY_PER_CHUNK;
++  }
++  p->nFresh--;
++  return p->pFresh++;
++}
+ 
+ /*
+-** The following global variables hold counters used for
+-** testing purposes only.  These variables do not exist in
+-** a non-testing build.  These variables are not thread-safe.
++** Insert a new value into a RowSet.
++**
++** The mallocFailed flag of the database connection is set if a
++** memory allocation fails.
+ */
+-#ifdef SQLITE_TEST
+-SQLITE_API int sqlite3_pager_readdb_count = 0;    /* Number of full pages read from DB */
+-SQLITE_API int sqlite3_pager_writedb_count = 0;   /* Number of full pages written to DB */
+-SQLITE_API int sqlite3_pager_writej_count = 0;    /* Number of pages written to journal */
+-# define PAGER_INCR(v)  v++
+-#else
+-# define PAGER_INCR(v)
+-#endif
++SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet *p, i64 rowid){
++  struct RowSetEntry *pEntry;  /* The new entry */
++  struct RowSetEntry *pLast;   /* The last prior entry */
+ 
++  /* This routine is never called after sqlite3RowSetNext() */
++  assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 );
+ 
++  pEntry = rowSetEntryAlloc(p);
++  if( pEntry==0 ) return;
++  pEntry->v = rowid;
++  pEntry->pRight = 0;
++  pLast = p->pLast;
++  if( pLast ){
++    if( (p->rsFlags & ROWSET_SORTED)!=0 && rowid<=pLast->v ){
++      p->rsFlags &= ~ROWSET_SORTED;
++    }
++    pLast->pRight = pEntry;
++  }else{
++    p->pEntry = pEntry;
++  }
++  p->pLast = pEntry;
++}
+ 
+ /*
+-** Journal files begin with the following magic string.  The data
+-** was obtained from /dev/random.  It is used only as a sanity check.
+-**
+-** Since version 2.8.0, the journal format contains additional sanity
+-** checking information.  If the power fails while the journal is being
+-** written, semi-random garbage data might appear in the journal
+-** file after power is restored.  If an attempt is then made
+-** to roll the journal back, the database could be corrupted.  The additional
+-** sanity checking data is an attempt to discover the garbage in the
+-** journal and ignore it.
++** Merge two lists of RowSetEntry objects.  Remove duplicates.
+ **
+-** The sanity checking information for the new journal format consists
+-** of a 32-bit checksum on each page of data.  The checksum covers both
+-** the page number and the pPager->pageSize bytes of data for the page.
+-** This cksum is initialized to a 32-bit random value that appears in the
+-** journal file right after the header.  The random initializer is important,
+-** because garbage data that appears at the end of a journal is likely
+-** data that was once in other files that have now been deleted.  If the
+-** garbage data came from an obsolete journal file, the checksums might
+-** be correct.  But by initializing the checksum to random value which
+-** is different for every journal, we minimize that risk.
++** The input lists are connected via pRight pointers and are 
++** assumed to each already be in sorted order.
+ */
+-static const unsigned char aJournalMagic[] = {
+-  0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd7,
+-};
++static struct RowSetEntry *rowSetEntryMerge(
++  struct RowSetEntry *pA,    /* First sorted list to be merged */
++  struct RowSetEntry *pB     /* Second sorted list to be merged */
++){
++  struct RowSetEntry head;
++  struct RowSetEntry *pTail;
+ 
+-/*
+-** The size of the of each page record in the journal is given by
+-** the following macro.
+-*/
+-#define JOURNAL_PG_SZ(pPager)  ((pPager->pageSize) + 8)
++  pTail = &head;
++  while( pA && pB ){
++    assert( pA->pRight==0 || pA->v<=pA->pRight->v );
++    assert( pB->pRight==0 || pB->v<=pB->pRight->v );
++    if( pA->v<pB->v ){
++      pTail->pRight = pA;
++      pA = pA->pRight;
++      pTail = pTail->pRight;
++    }else if( pB->v<pA->v ){
++      pTail->pRight = pB;
++      pB = pB->pRight;
++      pTail = pTail->pRight;
++    }else{
++      pA = pA->pRight;
++    }
++  }
++  if( pA ){
++    assert( pA->pRight==0 || pA->v<=pA->pRight->v );
++    pTail->pRight = pA;
++  }else{
++    assert( pB==0 || pB->pRight==0 || pB->v<=pB->pRight->v );
++    pTail->pRight = pB;
++  }
++  return head.pRight;
++}
+ 
+ /*
+-** The journal header size for this pager. This is usually the same 
+-** size as a single disk sector. See also setSectorSize().
+-*/
+-#define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize)
++** Sort all elements on the list of RowSetEntry objects into order of
++** increasing v.
++*/ 
++static struct RowSetEntry *rowSetEntrySort(struct RowSetEntry *pIn){
++  unsigned int i;
++  struct RowSetEntry *pNext, *aBucket[40];
+ 
+-/*
+-** The macro MEMDB is true if we are dealing with an in-memory database.
+-** We do this as a macro so that if the SQLITE_OMIT_MEMORYDB macro is set,
+-** the value of MEMDB will be a constant and the compiler will optimize
+-** out code that would never execute.
+-*/
+-#ifdef SQLITE_OMIT_MEMORYDB
+-# define MEMDB 0
+-#else
+-# define MEMDB pPager->memDb
+-#endif
++  memset(aBucket, 0, sizeof(aBucket));
++  while( pIn ){
++    pNext = pIn->pRight;
++    pIn->pRight = 0;
++    for(i=0; aBucket[i]; i++){
++      pIn = rowSetEntryMerge(aBucket[i], pIn);
++      aBucket[i] = 0;
++    }
++    aBucket[i] = pIn;
++    pIn = pNext;
++  }
++  pIn = 0;
++  for(i=0; i<sizeof(aBucket)/sizeof(aBucket[0]); i++){
++    pIn = rowSetEntryMerge(pIn, aBucket[i]);
++  }
++  return pIn;
++}
+ 
+-/*
+-** The macro USEFETCH is true if we are allowed to use the xFetch and xUnfetch
+-** interfaces to access the database using memory-mapped I/O.
+-*/
+-#if SQLITE_MAX_MMAP_SIZE>0
+-# define USEFETCH(x) ((x)->bUseFetch)
+-#else
+-# define USEFETCH(x) 0
+-#endif
+ 
+ /*
+-** The maximum legal page number is (2^31 - 1).
++** The input, pIn, is a binary tree (or subtree) of RowSetEntry objects.
++** Convert this tree into a linked list connected by the pRight pointers
++** and return pointers to the first and last elements of the new list.
+ */
+-#define PAGER_MAX_PGNO 2147483647
++static void rowSetTreeToList(
++  struct RowSetEntry *pIn,         /* Root of the input tree */
++  struct RowSetEntry **ppFirst,    /* Write head of the output list here */
++  struct RowSetEntry **ppLast      /* Write tail of the output list here */
++){
++  assert( pIn!=0 );
++  if( pIn->pLeft ){
++    struct RowSetEntry *p;
++    rowSetTreeToList(pIn->pLeft, ppFirst, &p);
++    p->pRight = pIn;
++  }else{
++    *ppFirst = pIn;
++  }
++  if( pIn->pRight ){
++    rowSetTreeToList(pIn->pRight, &pIn->pRight, ppLast);
++  }else{
++    *ppLast = pIn;
++  }
++  assert( (*ppLast)->pRight==0 );
++}
++
+ 
+ /*
+-** The argument to this macro is a file descriptor (type sqlite3_file*).
+-** Return 0 if it is not open, or non-zero (but not 1) if it is.
+-**
+-** This is so that expressions can be written as:
+-**
+-**   if( isOpen(pPager->jfd) ){ ...
++** Convert a sorted list of elements (connected by pRight) into a binary
++** tree with depth of iDepth.  A depth of 1 means the tree contains a single
++** node taken from the head of *ppList.  A depth of 2 means a tree with
++** three nodes.  And so forth.
+ **
+-** instead of
++** Use as many entries from the input list as required and update the
++** *ppList to point to the unused elements of the list.  If the input
++** list contains too few elements, then construct an incomplete tree
++** and leave *ppList set to NULL.
+ **
+-**   if( pPager->jfd->pMethods ){ ...
++** Return a pointer to the root of the constructed binary tree.
+ */
+-#define isOpen(pFd) ((pFd)->pMethods)
++static struct RowSetEntry *rowSetNDeepTree(
++  struct RowSetEntry **ppList,
++  int iDepth
++){
++  struct RowSetEntry *p;         /* Root of the new tree */
++  struct RowSetEntry *pLeft;     /* Left subtree */
++  if( *ppList==0 ){
++    return 0;
++  }
++  if( iDepth==1 ){
++    p = *ppList;
++    *ppList = p->pRight;
++    p->pLeft = p->pRight = 0;
++    return p;
++  }
++  pLeft = rowSetNDeepTree(ppList, iDepth-1);
++  p = *ppList;
++  if( p==0 ){
++    return pLeft;
++  }
++  p->pLeft = pLeft;
++  *ppList = p->pRight;
++  p->pRight = rowSetNDeepTree(ppList, iDepth-1);
++  return p;
++}
+ 
+ /*
+-** Return true if this pager uses a write-ahead log instead of the usual
+-** rollback journal. Otherwise false.
++** Convert a sorted list of elements into a binary tree. Make the tree
++** as deep as it needs to be in order to contain the entire list.
+ */
+-#ifndef SQLITE_OMIT_WAL
+-static int pagerUseWal(Pager *pPager){
+-  return (pPager->pWal!=0);
++static struct RowSetEntry *rowSetListToTree(struct RowSetEntry *pList){
++  int iDepth;           /* Depth of the tree so far */
++  struct RowSetEntry *p;       /* Current tree root */
++  struct RowSetEntry *pLeft;   /* Left subtree */
++
++  assert( pList!=0 );
++  p = pList;
++  pList = p->pRight;
++  p->pLeft = p->pRight = 0;
++  for(iDepth=1; pList; iDepth++){
++    pLeft = p;
++    p = pList;
++    pList = p->pRight;
++    p->pLeft = pLeft;
++    p->pRight = rowSetNDeepTree(&pList, iDepth);
++  }
++  return p;
+ }
+-#else
+-# define pagerUseWal(x) 0
+-# define pagerRollbackWal(x) 0
+-# define pagerWalFrames(v,w,x,y) 0
+-# define pagerOpenWalIfPresent(z) SQLITE_OK
+-# define pagerBeginReadTransaction(z) SQLITE_OK
+-#endif
+ 
+-#ifndef NDEBUG 
+ /*
+-** Usage:
+-**
+-**   assert( assert_pager_state(pPager) );
++** Take all the entries on p->pEntry and on the trees in p->pForest and
++** sort them all together into one big ordered list on p->pEntry.
+ **
+-** This function runs many asserts to try to find inconsistencies in
+-** the internal state of the Pager object.
++** This routine should only be called once in the life of a RowSet.
+ */
+-static int assert_pager_state(Pager *p){
+-  Pager *pPager = p;
+-
+-  /* State must be valid. */
+-  assert( p->eState==PAGER_OPEN
+-       || p->eState==PAGER_READER
+-       || p->eState==PAGER_WRITER_LOCKED
+-       || p->eState==PAGER_WRITER_CACHEMOD
+-       || p->eState==PAGER_WRITER_DBMOD
+-       || p->eState==PAGER_WRITER_FINISHED
+-       || p->eState==PAGER_ERROR
+-  );
+-
+-  /* Regardless of the current state, a temp-file connection always behaves
+-  ** as if it has an exclusive lock on the database file. It never updates
+-  ** the change-counter field, so the changeCountDone flag is always set.
+-  */
+-  assert( p->tempFile==0 || p->eLock==EXCLUSIVE_LOCK );
+-  assert( p->tempFile==0 || pPager->changeCountDone );
++static void rowSetToList(RowSet *p){
+ 
+-  /* If the useJournal flag is clear, the journal-mode must be "OFF". 
+-  ** And if the journal-mode is "OFF", the journal file must not be open.
+-  */
+-  assert( p->journalMode==PAGER_JOURNALMODE_OFF || p->useJournal );
+-  assert( p->journalMode!=PAGER_JOURNALMODE_OFF || !isOpen(p->jfd) );
++  /* This routine is called only once */
++  assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 );
+ 
+-  /* Check that MEMDB implies noSync. And an in-memory journal. Since 
+-  ** this means an in-memory pager performs no IO at all, it cannot encounter 
+-  ** either SQLITE_IOERR or SQLITE_FULL during rollback or while finalizing 
+-  ** a journal file. (although the in-memory journal implementation may 
+-  ** return SQLITE_IOERR_NOMEM while the journal file is being written). It 
+-  ** is therefore not possible for an in-memory pager to enter the ERROR 
+-  ** state.
+-  */
+-  if( MEMDB ){
+-    assert( p->noSync );
+-    assert( p->journalMode==PAGER_JOURNALMODE_OFF 
+-         || p->journalMode==PAGER_JOURNALMODE_MEMORY 
+-    );
+-    assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN );
+-    assert( pagerUseWal(p)==0 );
++  if( (p->rsFlags & ROWSET_SORTED)==0 ){
++    p->pEntry = rowSetEntrySort(p->pEntry);
+   }
+ 
+-  /* If changeCountDone is set, a RESERVED lock or greater must be held
+-  ** on the file.
+-  */
+-  assert( pPager->changeCountDone==0 || pPager->eLock>=RESERVED_LOCK );
+-  assert( p->eLock!=PENDING_LOCK );
+-
+-  switch( p->eState ){
+-    case PAGER_OPEN:
+-      assert( !MEMDB );
+-      assert( pPager->errCode==SQLITE_OK );
+-      assert( sqlite3PcacheRefCount(pPager->pPCache)==0 || pPager->tempFile );
+-      break;
+-
+-    case PAGER_READER:
+-      assert( pPager->errCode==SQLITE_OK );
+-      assert( p->eLock!=UNKNOWN_LOCK );
+-      assert( p->eLock>=SHARED_LOCK );
+-      break;
+-
+-    case PAGER_WRITER_LOCKED:
+-      assert( p->eLock!=UNKNOWN_LOCK );
+-      assert( pPager->errCode==SQLITE_OK );
+-      if( !pagerUseWal(pPager) ){
+-        assert( p->eLock>=RESERVED_LOCK );
+-      }
+-      assert( pPager->dbSize==pPager->dbOrigSize );
+-      assert( pPager->dbOrigSize==pPager->dbFileSize );
+-      assert( pPager->dbOrigSize==pPager->dbHintSize );
+-      assert( pPager->setMaster==0 );
+-      break;
+-
+-    case PAGER_WRITER_CACHEMOD:
+-      assert( p->eLock!=UNKNOWN_LOCK );
+-      assert( pPager->errCode==SQLITE_OK );
+-      if( !pagerUseWal(pPager) ){
+-        /* It is possible that if journal_mode=wal here that neither the
+-        ** journal file nor the WAL file are open. This happens during
+-        ** a rollback transaction that switches from journal_mode=off
+-        ** to journal_mode=wal.
+-        */
+-        assert( p->eLock>=RESERVED_LOCK );
+-        assert( isOpen(p->jfd) 
+-             || p->journalMode==PAGER_JOURNALMODE_OFF 
+-             || p->journalMode==PAGER_JOURNALMODE_WAL 
+-        );
+-      }
+-      assert( pPager->dbOrigSize==pPager->dbFileSize );
+-      assert( pPager->dbOrigSize==pPager->dbHintSize );
+-      break;
+-
+-    case PAGER_WRITER_DBMOD:
+-      assert( p->eLock==EXCLUSIVE_LOCK );
+-      assert( pPager->errCode==SQLITE_OK );
+-      assert( !pagerUseWal(pPager) );
+-      assert( p->eLock>=EXCLUSIVE_LOCK );
+-      assert( isOpen(p->jfd) 
+-           || p->journalMode==PAGER_JOURNALMODE_OFF 
+-           || p->journalMode==PAGER_JOURNALMODE_WAL 
+-      );
+-      assert( pPager->dbOrigSize<=pPager->dbHintSize );
+-      break;
+-
+-    case PAGER_WRITER_FINISHED:
+-      assert( p->eLock==EXCLUSIVE_LOCK );
+-      assert( pPager->errCode==SQLITE_OK );
+-      assert( !pagerUseWal(pPager) );
+-      assert( isOpen(p->jfd) 
+-           || p->journalMode==PAGER_JOURNALMODE_OFF 
+-           || p->journalMode==PAGER_JOURNALMODE_WAL 
+-      );
+-      break;
+-
+-    case PAGER_ERROR:
+-      /* There must be at least one outstanding reference to the pager if
+-      ** in ERROR state. Otherwise the pager should have already dropped
+-      ** back to OPEN state.
+-      */
+-      assert( pPager->errCode!=SQLITE_OK );
+-      assert( sqlite3PcacheRefCount(pPager->pPCache)>0 );
+-      break;
++  /* While this module could theoretically support it, sqlite3RowSetNext()
++  ** is never called after sqlite3RowSetText() for the same RowSet.  So
++  ** there is never a forest to deal with.  Should this change, simply
++  ** remove the assert() and the #if 0. */
++  assert( p->pForest==0 );
++#if 0
++  while( p->pForest ){
++    struct RowSetEntry *pTree = p->pForest->pLeft;
++    if( pTree ){
++      struct RowSetEntry *pHead, *pTail;
++      rowSetTreeToList(pTree, &pHead, &pTail);
++      p->pEntry = rowSetEntryMerge(p->pEntry, pHead);
++    }
++    p->pForest = p->pForest->pRight;
+   }
+-
+-  return 1;
++#endif
++  p->rsFlags |= ROWSET_NEXT;  /* Verify this routine is never called again */
+ }
+-#endif /* ifndef NDEBUG */
+ 
+-#ifdef SQLITE_DEBUG 
+ /*
+-** Return a pointer to a human readable string in a static buffer
+-** containing the state of the Pager object passed as an argument. This
+-** is intended to be used within debuggers. For example, as an alternative
+-** to "print *pPager" in gdb:
++** Extract the smallest element from the RowSet.
++** Write the element into *pRowid.  Return 1 on success.  Return
++** 0 if the RowSet is already empty.
+ **
+-** (gdb) printf "%s", print_pager_state(pPager)
++** After this routine has been called, the sqlite3RowSetInsert()
++** routine may not be called again.  
+ */
+-static char *print_pager_state(Pager *p){
+-  static char zRet[1024];
++SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){
++  assert( p!=0 );
+ 
+-  sqlite3_snprintf(1024, zRet,
+-      "Filename:      %s\n"
+-      "State:         %s errCode=%d\n"
+-      "Lock:          %s\n"
+-      "Locking mode:  locking_mode=%s\n"
+-      "Journal mode:  journal_mode=%s\n"
+-      "Backing store: tempFile=%d memDb=%d useJournal=%d\n"
+-      "Journal:       journalOff=%lld journalHdr=%lld\n"
+-      "Size:          dbsize=%d dbOrigSize=%d dbFileSize=%d\n"
+-      , p->zFilename
+-      , p->eState==PAGER_OPEN            ? "OPEN" :
+-        p->eState==PAGER_READER          ? "READER" :
+-        p->eState==PAGER_WRITER_LOCKED   ? "WRITER_LOCKED" :
+-        p->eState==PAGER_WRITER_CACHEMOD ? "WRITER_CACHEMOD" :
+-        p->eState==PAGER_WRITER_DBMOD    ? "WRITER_DBMOD" :
+-        p->eState==PAGER_WRITER_FINISHED ? "WRITER_FINISHED" :
+-        p->eState==PAGER_ERROR           ? "ERROR" : "?error?"
+-      , (int)p->errCode
+-      , p->eLock==NO_LOCK         ? "NO_LOCK" :
+-        p->eLock==RESERVED_LOCK   ? "RESERVED" :
+-        p->eLock==EXCLUSIVE_LOCK  ? "EXCLUSIVE" :
+-        p->eLock==SHARED_LOCK     ? "SHARED" :
+-        p->eLock==UNKNOWN_LOCK    ? "UNKNOWN" : "?error?"
+-      , p->exclusiveMode ? "exclusive" : "normal"
+-      , p->journalMode==PAGER_JOURNALMODE_MEMORY   ? "memory" :
+-        p->journalMode==PAGER_JOURNALMODE_OFF      ? "off" :
+-        p->journalMode==PAGER_JOURNALMODE_DELETE   ? "delete" :
+-        p->journalMode==PAGER_JOURNALMODE_PERSIST  ? "persist" :
+-        p->journalMode==PAGER_JOURNALMODE_TRUNCATE ? "truncate" :
+-        p->journalMode==PAGER_JOURNALMODE_WAL      ? "wal" : "?error?"
+-      , (int)p->tempFile, (int)p->memDb, (int)p->useJournal
+-      , p->journalOff, p->journalHdr
+-      , (int)p->dbSize, (int)p->dbOrigSize, (int)p->dbFileSize
+-  );
++  /* Merge the forest into a single sorted list on first call */
++  if( (p->rsFlags & ROWSET_NEXT)==0 ) rowSetToList(p);
+ 
+-  return zRet;
++  /* Return the next entry on the list */
++  if( p->pEntry ){
++    *pRowid = p->pEntry->v;
++    p->pEntry = p->pEntry->pRight;
++    if( p->pEntry==0 ){
++      sqlite3RowSetClear(p);
++    }
++    return 1;
++  }else{
++    return 0;
++  }
+ }
+-#endif
+ 
+ /*
+-** Return true if it is necessary to write page *pPg into the sub-journal.
+-** A page needs to be written into the sub-journal if there exists one
+-** or more open savepoints for which:
++** Check to see if element iRowid was inserted into the rowset as
++** part of any insert batch prior to iBatch.  Return 1 or 0.
+ **
+-**   * The page-number is less than or equal to PagerSavepoint.nOrig, and
+-**   * The bit corresponding to the page-number is not set in
+-**     PagerSavepoint.pInSavepoint.
++** If this is the first test of a new batch and if there exist entries
++** on pRowSet->pEntry, then sort those entries into the forest at
++** pRowSet->pForest so that they can be tested.
+ */
+-static int subjRequiresPage(PgHdr *pPg){
+-  Pager *pPager = pPg->pPager;
+-  PagerSavepoint *p;
+-  Pgno pgno = pPg->pgno;
+-  int i;
+-  for(i=0; i<pPager->nSavepoint; i++){
+-    p = &pPager->aSavepoint[i];
+-    if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){
+-      return 1;
++SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){
++  struct RowSetEntry *p, *pTree;
++
++  /* This routine is never called after sqlite3RowSetNext() */
++  assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 );
++
++  /* Sort entries into the forest on the first test of a new batch 
++  */
++  if( iBatch!=pRowSet->iBatch ){
++    p = pRowSet->pEntry;
++    if( p ){
++      struct RowSetEntry **ppPrevTree = &pRowSet->pForest;
++      if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){
++        p = rowSetEntrySort(p);
++      }
++      for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
++        ppPrevTree = &pTree->pRight;
++        if( pTree->pLeft==0 ){
++          pTree->pLeft = rowSetListToTree(p);
++          break;
++        }else{
++          struct RowSetEntry *pAux, *pTail;
++          rowSetTreeToList(pTree->pLeft, &pAux, &pTail);
++          pTree->pLeft = 0;
++          p = rowSetEntryMerge(pAux, p);
++        }
++      }
++      if( pTree==0 ){
++        *ppPrevTree = pTree = rowSetEntryAlloc(pRowSet);
++        if( pTree ){
++          pTree->v = 0;
++          pTree->pRight = 0;
++          pTree->pLeft = rowSetListToTree(p);
++        }
++      }
++      pRowSet->pEntry = 0;
++      pRowSet->pLast = 0;
++      pRowSet->rsFlags |= ROWSET_SORTED;
++    }
++    pRowSet->iBatch = iBatch;
++  }
++
++  /* Test to see if the iRowid value appears anywhere in the forest.
++  ** Return 1 if it does and 0 if not.
++  */
++  for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){
++    p = pTree->pLeft;
++    while( p ){
++      if( p->v<iRowid ){
++        p = p->pRight;
++      }else if( p->v>iRowid ){
++        p = p->pLeft;
++      }else{
++        return 1;
++      }
+     }
+   }
+   return 0;
+ }
+ 
++/************** End of rowset.c **********************************************/
++/************** Begin file pager.c *******************************************/
+ /*
+-** Return true if the page is already in the journal file.
++** 2001 September 15
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++*************************************************************************
++** This is the implementation of the page cache subsystem or "pager".
++** 
++** The pager is used to access a database disk file.  It implements
++** atomic commit and rollback through the use of a journal file that
++** is separate from the database file.  The pager also implements file
++** locking to prevent two processes from writing the same database
++** file simultaneously, or one process from reading the database while
++** another is writing.
+ */
+-static int pageInJournal(Pager *pPager, PgHdr *pPg){
+-  return sqlite3BitvecTest(pPager->pInJournal, pPg->pgno);
+-}
+-
++#ifndef SQLITE_OMIT_DISKIO
++/************** Include wal.h in the middle of pager.c ***********************/
++/************** Begin file wal.h *********************************************/
+ /*
+-** Read a 32-bit integer from the given file descriptor.  Store the integer
+-** that is read in *pRes.  Return SQLITE_OK if everything worked, or an
+-** error code is something goes wrong.
++** 2010 February 1
+ **
+-** All values are stored on disk as big-endian.
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++*************************************************************************
++** This header file defines the interface to the write-ahead logging 
++** system. Refer to the comments below and the header comment attached to 
++** the implementation of each function in log.c for further details.
+ */
+-static int read32bits(sqlite3_file *fd, i64 offset, u32 *pRes){
+-  unsigned char ac[4];
+-  int rc = sqlite3OsRead(fd, ac, sizeof(ac), offset);
+-  if( rc==SQLITE_OK ){
+-    *pRes = sqlite3Get4byte(ac);
+-  }
+-  return rc;
+-}
+ 
+-/*
+-** Write a 32-bit integer into a string buffer in big-endian byte order.
+-*/
+-#define put32bits(A,B)  sqlite3Put4byte((u8*)A,B)
++#ifndef _WAL_H_
++#define _WAL_H_
+ 
+ 
+-/*
+-** Write a 32-bit integer into the given file descriptor.  Return SQLITE_OK
+-** on success or an error code is something goes wrong.
++/* Additional values that can be added to the sync_flags argument of
++** sqlite3WalFrames():
+ */
+-static int write32bits(sqlite3_file *fd, i64 offset, u32 val){
+-  char ac[4];
+-  put32bits(ac, val);
+-  return sqlite3OsWrite(fd, ac, 4, offset);
+-}
++#define WAL_SYNC_TRANSACTIONS  0x20   /* Sync at the end of each transaction */
++#define SQLITE_SYNC_MASK       0x13   /* Mask off the SQLITE_SYNC_* values */
+ 
+-/*
+-** Unlock the database file to level eLock, which must be either NO_LOCK
+-** or SHARED_LOCK. Regardless of whether or not the call to xUnlock()
+-** succeeds, set the Pager.eLock variable to match the (attempted) new lock.
+-**
+-** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is
+-** called, do not modify it. See the comment above the #define of 
+-** UNKNOWN_LOCK for an explanation of this.
++#ifdef SQLITE_OMIT_WAL
++# define sqlite3WalOpen(x,y,z)                   0
++# define sqlite3WalLimit(x,y)
++# define sqlite3WalClose(w,x,y,z)                0
++# define sqlite3WalBeginReadTransaction(y,z)     0
++# define sqlite3WalEndReadTransaction(z)
++# define sqlite3WalDbsize(y)                     0
++# define sqlite3WalBeginWriteTransaction(y)      0
++# define sqlite3WalEndWriteTransaction(x)        0
++# define sqlite3WalUndo(x,y,z)                   0
++# define sqlite3WalSavepoint(y,z)
++# define sqlite3WalSavepointUndo(y,z)            0
++# define sqlite3WalFrames(u,v,w,x,y,z)           0
++# define sqlite3WalCheckpoint(r,s,t,u,v,w,x,y,z) 0
++# define sqlite3WalCallback(z)                   0
++# define sqlite3WalExclusiveMode(y,z)            0
++# define sqlite3WalHeapMemory(z)                 0
++# define sqlite3WalFramesize(z)                  0
++# define sqlite3WalFindFrame(x,y,z)              0
++#else
++
++#define WAL_SAVEPOINT_NDATA 4
++
++/* Connection to a write-ahead log (WAL) file. 
++** There is one object of this type for each pager. 
+ */
+-static int pagerUnlockDb(Pager *pPager, int eLock){
+-  int rc = SQLITE_OK;
++typedef struct Wal Wal;
+ 
+-  assert( !pPager->exclusiveMode || pPager->eLock==eLock );
+-  assert( eLock==NO_LOCK || eLock==SHARED_LOCK );
+-  assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 );
+-  if( isOpen(pPager->fd) ){
+-    assert( pPager->eLock>=eLock );
+-    rc = pPager->noLock ? SQLITE_OK : sqlite3OsUnlock(pPager->fd, eLock);
+-    if( pPager->eLock!=UNKNOWN_LOCK ){
+-      pPager->eLock = (u8)eLock;
+-    }
+-    IOTRACE(("UNLOCK %p %d\n", pPager, eLock))
+-  }
+-  return rc;
+-}
++/* Open and close a connection to a write-ahead log. */
++SQLITE_PRIVATE int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**);
++SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, int sync_flags, int, u8 *);
+ 
+-/*
+-** Lock the database file to level eLock, which must be either SHARED_LOCK,
+-** RESERVED_LOCK or EXCLUSIVE_LOCK. If the caller is successful, set the
+-** Pager.eLock variable to the new locking state. 
+-**
+-** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is 
+-** called, do not modify it unless the new locking state is EXCLUSIVE_LOCK. 
+-** See the comment above the #define of UNKNOWN_LOCK for an explanation 
+-** of this.
++/* Set the limiting size of a WAL file. */
++SQLITE_PRIVATE void sqlite3WalLimit(Wal*, i64);
++
++/* Used by readers to open (lock) and close (unlock) a snapshot.  A 
++** snapshot is like a read-transaction.  It is the state of the database
++** at an instant in time.  sqlite3WalOpenSnapshot gets a read lock and
++** preserves the current state even if the other threads or processes
++** write to or checkpoint the WAL.  sqlite3WalCloseSnapshot() closes the
++** transaction and releases the lock.
+ */
+-static int pagerLockDb(Pager *pPager, int eLock){
+-  int rc = SQLITE_OK;
++SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *);
++SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal);
+ 
+-  assert( eLock==SHARED_LOCK || eLock==RESERVED_LOCK || eLock==EXCLUSIVE_LOCK );
+-  if( pPager->eLock<eLock || pPager->eLock==UNKNOWN_LOCK ){
+-    rc = pPager->noLock ? SQLITE_OK : sqlite3OsLock(pPager->fd, eLock);
+-    if( rc==SQLITE_OK && (pPager->eLock!=UNKNOWN_LOCK||eLock==EXCLUSIVE_LOCK) ){
+-      pPager->eLock = (u8)eLock;
+-      IOTRACE(("LOCK %p %d\n", pPager, eLock))
+-    }
+-  }
+-  return rc;
+-}
++/* Read a page from the write-ahead log, if it is present. */
++SQLITE_PRIVATE int sqlite3WalFindFrame(Wal *, Pgno, u32 *);
++SQLITE_PRIVATE int sqlite3WalReadFrame(Wal *, u32, int, u8 *);
+ 
+-/*
+-** This function determines whether or not the atomic-write optimization
+-** can be used with this pager. The optimization can be used if:
+-**
+-**  (a) the value returned by OsDeviceCharacteristics() indicates that
+-**      a database page may be written atomically, and
+-**  (b) the value returned by OsSectorSize() is less than or equal
+-**      to the page size.
+-**
+-** The optimization is also always enabled for temporary files. It is
+-** an error to call this function if pPager is opened on an in-memory
+-** database.
+-**
+-** If the optimization cannot be used, 0 is returned. If it can be used,
+-** then the value returned is the size of the journal file when it
+-** contains rollback data for exactly one page.
++/* If the WAL is not empty, return the size of the database. */
++SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal);
++
++/* Obtain or release the WRITER lock. */
++SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal);
++SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal);
++
++/* Undo any frames written (but not committed) to the log */
++SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx);
++
++/* Return an integer that records the current (uncommitted) write
++** position in the WAL */
++SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData);
++
++/* Move the write position of the WAL back to iFrame.  Called in
++** response to a ROLLBACK TO command. */
++SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData);
++
++/* Write a frame or frames to the log. */
++SQLITE_PRIVATE int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int);
++
++/* Copy pages from the log to the database file */ 
++SQLITE_PRIVATE int sqlite3WalCheckpoint(
++  Wal *pWal,                      /* Write-ahead log connection */
++  int eMode,                      /* One of PASSIVE, FULL and RESTART */
++  int (*xBusy)(void*),            /* Function to call when busy */
++  void *pBusyArg,                 /* Context argument for xBusyHandler */
++  int sync_flags,                 /* Flags to sync db file with (or 0) */
++  int nBuf,                       /* Size of buffer nBuf */
++  u8 *zBuf,                       /* Temporary buffer to use */
++  int *pnLog,                     /* OUT: Number of frames in WAL */
++  int *pnCkpt                     /* OUT: Number of backfilled frames in WAL */
++);
++
++/* Return the value to pass to a sqlite3_wal_hook callback, the
++** number of frames in the WAL at the point of the last commit since
++** sqlite3WalCallback() was called.  If no commits have occurred since
++** the last call, then return 0.
+ */
+-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+-static int jrnlBufferSize(Pager *pPager){
+-  assert( !MEMDB );
+-  if( !pPager->tempFile ){
+-    int dc;                           /* Device characteristics */
+-    int nSector;                      /* Sector size */
+-    int szPage;                       /* Page size */
++SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal);
+ 
+-    assert( isOpen(pPager->fd) );
+-    dc = sqlite3OsDeviceCharacteristics(pPager->fd);
+-    nSector = pPager->sectorSize;
+-    szPage = pPager->pageSize;
++/* Tell the wal layer that an EXCLUSIVE lock has been obtained (or released)
++** by the pager layer on the database file.
++*/
++SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op);
+ 
+-    assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
+-    assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
+-    if( 0==(dc&(SQLITE_IOCAP_ATOMIC|(szPage>>8)) || nSector>szPage) ){
+-      return 0;
+-    }
+-  }
++/* Return true if the argument is non-NULL and the WAL module is using
++** heap-memory for the wal-index. Otherwise, if the argument is NULL or the
++** WAL module is using shared-memory, return false. 
++*/
++SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal);
+ 
+-  return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager);
+-}
++#ifdef SQLITE_ENABLE_ZIPVFS
++/* If the WAL file is not empty, return the number of bytes of content
++** stored in each frame (i.e. the db page-size when the WAL was created).
++*/
++SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal);
+ #endif
+ 
++#endif /* ifndef SQLITE_OMIT_WAL */
++#endif /* _WAL_H_ */
++
++/************** End of wal.h *************************************************/
++/************** Continuing where we left off in pager.c **********************/
++
++
++/******************* NOTES ON THE DESIGN OF THE PAGER ************************
++**
++** This comment block describes invariants that hold when using a rollback
++** journal.  These invariants do not apply for journal_mode=WAL,
++** journal_mode=MEMORY, or journal_mode=OFF.
++**
++** Within this comment block, a page is deemed to have been synced
++** automatically as soon as it is written when PRAGMA synchronous=OFF.
++** Otherwise, the page is not synced until the xSync method of the VFS
++** is called successfully on the file containing the page.
++**
++** Definition:  A page of the database file is said to be "overwriteable" if
++** one or more of the following are true about the page:
++** 
++**     (a)  The original content of the page as it was at the beginning of
++**          the transaction has been written into the rollback journal and
++**          synced.
++** 
++**     (b)  The page was a freelist leaf page at the start of the transaction.
++** 
++**     (c)  The page number is greater than the largest page that existed in
++**          the database file at the start of the transaction.
++** 
++** (1) A page of the database file is never overwritten unless one of the
++**     following are true:
++** 
++**     (a) The page and all other pages on the same sector are overwriteable.
++** 
++**     (b) The atomic page write optimization is enabled, and the entire
++**         transaction other than the update of the transaction sequence
++**         number consists of a single page change.
++** 
++** (2) The content of a page written into the rollback journal exactly matches
++**     both the content in the database when the rollback journal was written
++**     and the content in the database at the beginning of the current
++**     transaction.
++** 
++** (3) Writes to the database file are an integer multiple of the page size
++**     in length and are aligned on a page boundary.
++** 
++** (4) Reads from the database file are either aligned on a page boundary and
++**     an integer multiple of the page size in length or are taken from the
++**     first 100 bytes of the database file.
++** 
++** (5) All writes to the database file are synced prior to the rollback journal
++**     being deleted, truncated, or zeroed.
++** 
++** (6) If a master journal file is used, then all writes to the database file
++**     are synced prior to the master journal being deleted.
++** 
++** Definition: Two databases (or the same database at two points it time)
++** are said to be "logically equivalent" if they give the same answer to
++** all queries.  Note in particular the content of freelist leaf
++** pages can be changed arbitrarily without affecting the logical equivalence
++** of the database.
++** 
++** (7) At any time, if any subset, including the empty set and the total set,
++**     of the unsynced changes to a rollback journal are removed and the 
++**     journal is rolled back, the resulting database file will be logically
++**     equivalent to the database file at the beginning of the transaction.
++** 
++** (8) When a transaction is rolled back, the xTruncate method of the VFS
++**     is called to restore the database file to the same size it was at
++**     the beginning of the transaction.  (In some VFSes, the xTruncate
++**     method is a no-op, but that does not change the fact the SQLite will
++**     invoke it.)
++** 
++** (9) Whenever the database file is modified, at least one bit in the range
++**     of bytes from 24 through 39 inclusive will be changed prior to releasing
++**     the EXCLUSIVE lock, thus signaling other connections on the same
++**     database to flush their caches.
++**
++** (10) The pattern of bits in bytes 24 through 39 shall not repeat in less
++**      than one billion transactions.
++**
++** (11) A database file is well-formed at the beginning and at the conclusion
++**      of every transaction.
++**
++** (12) An EXCLUSIVE lock is held on the database file when writing to
++**      the database file.
++**
++** (13) A SHARED lock is held on the database file while reading any
++**      content out of the database file.
++**
++******************************************************************************/
++
+ /*
+-** If SQLITE_CHECK_PAGES is defined then we do some sanity checking
+-** on the cache using a hash function.  This is used for testing
+-** and debugging only.
+-*/
+-#ifdef SQLITE_CHECK_PAGES
+-/*
+-** Return a 32-bit hash of the page data for pPage.
++** Macros for troubleshooting.  Normally turned off
+ */
+-static u32 pager_datahash(int nByte, unsigned char *pData){
+-  u32 hash = 0;
+-  int i;
+-  for(i=0; i<nByte; i++){
+-    hash = (hash*1039) + pData[i];
+-  }
+-  return hash;
+-}
+-static u32 pager_pagehash(PgHdr *pPage){
+-  return pager_datahash(pPage->pPager->pageSize, (unsigned char *)pPage->pData);
+-}
+-static void pager_set_pagehash(PgHdr *pPage){
+-  pPage->pageHash = pager_pagehash(pPage);
+-}
++#if 0
++int sqlite3PagerTrace=1;  /* True to enable tracing */
++#define sqlite3DebugPrintf printf
++#define PAGERTRACE(X)     if( sqlite3PagerTrace ){ sqlite3DebugPrintf X; }
++#else
++#define PAGERTRACE(X)
++#endif
+ 
+ /*
+-** The CHECK_PAGE macro takes a PgHdr* as an argument. If SQLITE_CHECK_PAGES
+-** is defined, and NDEBUG is not defined, an assert() statement checks
+-** that the page is either dirty or still matches the calculated page-hash.
++** The following two macros are used within the PAGERTRACE() macros above
++** to print out file-descriptors. 
++**
++** PAGERID() takes a pointer to a Pager struct as its argument. The
++** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file
++** struct as its argument.
+ */
+-#define CHECK_PAGE(x) checkPage(x)
+-static void checkPage(PgHdr *pPg){
+-  Pager *pPager = pPg->pPager;
+-  assert( pPager->eState!=PAGER_ERROR );
+-  assert( (pPg->flags&PGHDR_DIRTY) || pPg->pageHash==pager_pagehash(pPg) );
+-}
+-
+-#else
+-#define pager_datahash(X,Y)  0
+-#define pager_pagehash(X)  0
+-#define pager_set_pagehash(X)
+-#define CHECK_PAGE(x)
+-#endif  /* SQLITE_CHECK_PAGES */
++#define PAGERID(p) ((int)(p->fd))
++#define FILEHANDLEID(fd) ((int)fd)
+ 
+ /*
+-** When this is called the journal file for pager pPager must be open.
+-** This function attempts to read a master journal file name from the 
+-** end of the file and, if successful, copies it into memory supplied 
+-** by the caller. See comments above writeMasterJournal() for the format
+-** used to store a master journal file name at the end of a journal file.
++** The Pager.eState variable stores the current 'state' of a pager. A
++** pager may be in any one of the seven states shown in the following
++** state diagram.
++**
++**                            OPEN <------+------+
++**                              |         |      |
++**                              V         |      |
++**               +---------> READER-------+      |
++**               |              |                |
++**               |              V                |
++**               |<-------WRITER_LOCKED------> ERROR
++**               |              |                ^  
++**               |              V                |
++**               |<------WRITER_CACHEMOD-------->|
++**               |              |                |
++**               |              V                |
++**               |<-------WRITER_DBMOD---------->|
++**               |              |                |
++**               |              V                |
++**               +<------WRITER_FINISHED-------->+
++**
++**
++** List of state transitions and the C [function] that performs each:
++** 
++**   OPEN              -> READER              [sqlite3PagerSharedLock]
++**   READER            -> OPEN                [pager_unlock]
++**
++**   READER            -> WRITER_LOCKED       [sqlite3PagerBegin]
++**   WRITER_LOCKED     -> WRITER_CACHEMOD     [pager_open_journal]
++**   WRITER_CACHEMOD   -> WRITER_DBMOD        [syncJournal]
++**   WRITER_DBMOD      -> WRITER_FINISHED     [sqlite3PagerCommitPhaseOne]
++**   WRITER_***        -> READER              [pager_end_transaction]
++**
++**   WRITER_***        -> ERROR               [pager_error]
++**   ERROR             -> OPEN                [pager_unlock]
++** 
++**
++**  OPEN:
++**
++**    The pager starts up in this state. Nothing is guaranteed in this
++**    state - the file may or may not be locked and the database size is
++**    unknown. The database may not be read or written.
++**
++**    * No read or write transaction is active.
++**    * Any lock, or no lock at all, may be held on the database file.
++**    * The dbSize, dbOrigSize and dbFileSize variables may not be trusted.
++**
++**  READER:
++**
++**    In this state all the requirements for reading the database in 
++**    rollback (non-WAL) mode are met. Unless the pager is (or recently
++**    was) in exclusive-locking mode, a user-level read transaction is 
++**    open. The database size is known in this state.
++**
++**    A connection running with locking_mode=normal enters this state when
++**    it opens a read-transaction on the database and returns to state
++**    OPEN after the read-transaction is completed. However a connection
++**    running in locking_mode=exclusive (including temp databases) remains in
++**    this state even after the read-transaction is closed. The only way
++**    a locking_mode=exclusive connection can transition from READER to OPEN
++**    is via the ERROR state (see below).
++** 
++**    * A read transaction may be active (but a write-transaction cannot).
++**    * A SHARED or greater lock is held on the database file.
++**    * The dbSize variable may be trusted (even if a user-level read 
++**      transaction is not active). The dbOrigSize and dbFileSize variables
++**      may not be trusted at this point.
++**    * If the database is a WAL database, then the WAL connection is open.
++**    * Even if a read-transaction is not open, it is guaranteed that 
++**      there is no hot-journal in the file-system.
++**
++**  WRITER_LOCKED:
++**
++**    The pager moves to this state from READER when a write-transaction
++**    is first opened on the database. In WRITER_LOCKED state, all locks 
++**    required to start a write-transaction are held, but no actual 
++**    modifications to the cache or database have taken place.
++**
++**    In rollback mode, a RESERVED or (if the transaction was opened with 
++**    BEGIN EXCLUSIVE) EXCLUSIVE lock is obtained on the database file when
++**    moving to this state, but the journal file is not written to or opened 
++**    to in this state. If the transaction is committed or rolled back while 
++**    in WRITER_LOCKED state, all that is required is to unlock the database 
++**    file.
++**
++**    IN WAL mode, WalBeginWriteTransaction() is called to lock the log file.
++**    If the connection is running with locking_mode=exclusive, an attempt
++**    is made to obtain an EXCLUSIVE lock on the database file.
++**
++**    * A write transaction is active.
++**    * If the connection is open in rollback-mode, a RESERVED or greater 
++**      lock is held on the database file.
++**    * If the connection is open in WAL-mode, a WAL write transaction
++**      is open (i.e. sqlite3WalBeginWriteTransaction() has been successfully
++**      called).
++**    * The dbSize, dbOrigSize and dbFileSize variables are all valid.
++**    * The contents of the pager cache have not been modified.
++**    * The journal file may or may not be open.
++**    * Nothing (not even the first header) has been written to the journal.
++**
++**  WRITER_CACHEMOD:
++**
++**    A pager moves from WRITER_LOCKED state to this state when a page is
++**    first modified by the upper layer. In rollback mode the journal file
++**    is opened (if it is not already open) and a header written to the
++**    start of it. The database file on disk has not been modified.
++**
++**    * A write transaction is active.
++**    * A RESERVED or greater lock is held on the database file.
++**    * The journal file is open and the first header has been written 
++**      to it, but the header has not been synced to disk.
++**    * The contents of the page cache have been modified.
+ **
+-** zMaster must point to a buffer of at least nMaster bytes allocated by
+-** the caller. This should be sqlite3_vfs.mxPathname+1 (to ensure there is
+-** enough space to write the master journal name). If the master journal
+-** name in the journal is longer than nMaster bytes (including a
+-** nul-terminator), then this is handled as if no master journal name
+-** were present in the journal.
++**  WRITER_DBMOD:
+ **
+-** If a master journal file name is present at the end of the journal
+-** file, then it is copied into the buffer pointed to by zMaster. A
+-** nul-terminator byte is appended to the buffer following the master
+-** journal file name.
++**    The pager transitions from WRITER_CACHEMOD into WRITER_DBMOD state
++**    when it modifies the contents of the database file. WAL connections
++**    never enter this state (since they do not modify the database file,
++**    just the log file).
+ **
+-** If it is determined that no master journal file name is present 
+-** zMaster[0] is set to 0 and SQLITE_OK returned.
++**    * A write transaction is active.
++**    * An EXCLUSIVE or greater lock is held on the database file.
++**    * The journal file is open and the first header has been written 
++**      and synced to disk.
++**    * The contents of the page cache have been modified (and possibly
++**      written to disk).
+ **
+-** If an error occurs while reading from the journal file, an SQLite
+-** error code is returned.
+-*/
+-static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){
+-  int rc;                    /* Return code */
+-  u32 len;                   /* Length in bytes of master journal name */
+-  i64 szJ;                   /* Total size in bytes of journal file pJrnl */
+-  u32 cksum;                 /* MJ checksum value read from journal */
+-  u32 u;                     /* Unsigned loop counter */
+-  unsigned char aMagic[8];   /* A buffer to hold the magic header */
+-  zMaster[0] = '\0';
+-
+-  if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ))
+-   || szJ<16
+-   || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len))
+-   || len>=nMaster 
+-   || len==0 
+-   || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum))
+-   || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8))
+-   || memcmp(aMagic, aJournalMagic, 8)
+-   || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, zMaster, len, szJ-16-len))
+-  ){
+-    return rc;
+-  }
+-
+-  /* See if the checksum matches the master journal name */
+-  for(u=0; u<len; u++){
+-    cksum -= zMaster[u];
+-  }
+-  if( cksum ){
+-    /* If the checksum doesn't add up, then one or more of the disk sectors
+-    ** containing the master journal filename is corrupted. This means
+-    ** definitely roll back, so just return SQLITE_OK and report a (nul)
+-    ** master-journal filename.
+-    */
+-    len = 0;
+-  }
+-  zMaster[len] = '\0';
+-   
+-  return SQLITE_OK;
+-}
+-
+-/*
+-** Return the offset of the sector boundary at or immediately 
+-** following the value in pPager->journalOff, assuming a sector 
+-** size of pPager->sectorSize bytes.
++**  WRITER_FINISHED:
+ **
+-** i.e for a sector size of 512:
++**    It is not possible for a WAL connection to enter this state.
+ **
+-**   Pager.journalOff          Return value
+-**   ---------------------------------------
+-**   0                         0
+-**   512                       512
+-**   100                       512
+-**   2000                      2048
+-** 
+-*/
+-static i64 journalHdrOffset(Pager *pPager){
+-  i64 offset = 0;
+-  i64 c = pPager->journalOff;
+-  if( c ){
+-    offset = ((c-1)/JOURNAL_HDR_SZ(pPager) + 1) * JOURNAL_HDR_SZ(pPager);
+-  }
+-  assert( offset%JOURNAL_HDR_SZ(pPager)==0 );
+-  assert( offset>=c );
+-  assert( (offset-c)<JOURNAL_HDR_SZ(pPager) );
+-  return offset;
+-}
+-
+-/*
+-** The journal file must be open when this function is called.
++**    A rollback-mode pager changes to WRITER_FINISHED state from WRITER_DBMOD
++**    state after the entire transaction has been successfully written into the
++**    database file. In this state the transaction may be committed simply
++**    by finalizing the journal file. Once in WRITER_FINISHED state, it is 
++**    not possible to modify the database further. At this point, the upper 
++**    layer must either commit or rollback the transaction.
+ **
+-** This function is a no-op if the journal file has not been written to
+-** within the current transaction (i.e. if Pager.journalOff==0).
++**    * A write transaction is active.
++**    * An EXCLUSIVE or greater lock is held on the database file.
++**    * All writing and syncing of journal and database data has finished.
++**      If no error occurred, all that remains is to finalize the journal to
++**      commit the transaction. If an error did occur, the caller will need
++**      to rollback the transaction. 
+ **
+-** If doTruncate is non-zero or the Pager.journalSizeLimit variable is
+-** set to 0, then truncate the journal file to zero bytes in size. Otherwise,
+-** zero the 28-byte header at the start of the journal file. In either case, 
+-** if the pager is not in no-sync mode, sync the journal file immediately 
+-** after writing or truncating it.
++**  ERROR:
+ **
+-** If Pager.journalSizeLimit is set to a positive, non-zero value, and
+-** following the truncation or zeroing described above the size of the 
+-** journal file in bytes is larger than this value, then truncate the
+-** journal file to Pager.journalSizeLimit bytes. The journal file does
+-** not need to be synced following this operation.
++**    The ERROR state is entered when an IO or disk-full error (including
++**    SQLITE_IOERR_NOMEM) occurs at a point in the code that makes it 
++**    difficult to be sure that the in-memory pager state (cache contents, 
++**    db size etc.) are consistent with the contents of the file-system.
+ **
+-** If an IO error occurs, abandon processing and return the IO error code.
+-** Otherwise, return SQLITE_OK.
+-*/
+-static int zeroJournalHdr(Pager *pPager, int doTruncate){
+-  int rc = SQLITE_OK;                               /* Return code */
+-  assert( isOpen(pPager->jfd) );
+-  if( pPager->journalOff ){
+-    const i64 iLimit = pPager->journalSizeLimit;    /* Local cache of jsl */
+-
+-    IOTRACE(("JZEROHDR %p\n", pPager))
+-    if( doTruncate || iLimit==0 ){
+-      rc = sqlite3OsTruncate(pPager->jfd, 0);
+-    }else{
+-      static const char zeroHdr[28] = {0};
+-      rc = sqlite3OsWrite(pPager->jfd, zeroHdr, sizeof(zeroHdr), 0);
+-    }
+-    if( rc==SQLITE_OK && !pPager->noSync ){
+-      rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_DATAONLY|pPager->syncFlags);
+-    }
+-
+-    /* At this point the transaction is committed but the write lock 
+-    ** is still held on the file. If there is a size limit configured for 
+-    ** the persistent journal and the journal file currently consumes more
+-    ** space than that limit allows for, truncate it now. There is no need
+-    ** to sync the file following this operation.
+-    */
+-    if( rc==SQLITE_OK && iLimit>0 ){
+-      i64 sz;
+-      rc = sqlite3OsFileSize(pPager->jfd, &sz);
+-      if( rc==SQLITE_OK && sz>iLimit ){
+-        rc = sqlite3OsTruncate(pPager->jfd, iLimit);
+-      }
+-    }
+-  }
+-  return rc;
+-}
+-
+-/*
+-** The journal file must be open when this routine is called. A journal
+-** header (JOURNAL_HDR_SZ bytes) is written into the journal file at the
+-** current location.
++**    Temporary pager files may enter the ERROR state, but in-memory pagers
++**    cannot.
+ **
+-** The format for the journal header is as follows:
+-** - 8 bytes: Magic identifying journal format.
+-** - 4 bytes: Number of records in journal, or -1 no-sync mode is on.
+-** - 4 bytes: Random number used for page hash.
+-** - 4 bytes: Initial database page count.
+-** - 4 bytes: Sector size used by the process that wrote this journal.
+-** - 4 bytes: Database page size.
+-** 
+-** Followed by (JOURNAL_HDR_SZ - 28) bytes of unused space.
+-*/
+-static int writeJournalHdr(Pager *pPager){
+-  int rc = SQLITE_OK;                 /* Return code */
+-  char *zHeader = pPager->pTmpSpace;  /* Temporary space used to build header */
+-  u32 nHeader = (u32)pPager->pageSize;/* Size of buffer pointed to by zHeader */
+-  u32 nWrite;                         /* Bytes of header sector written */
+-  int ii;                             /* Loop counter */
+-
+-  assert( isOpen(pPager->jfd) );      /* Journal file must be open. */
+-
+-  if( nHeader>JOURNAL_HDR_SZ(pPager) ){
+-    nHeader = JOURNAL_HDR_SZ(pPager);
+-  }
+-
+-  /* If there are active savepoints and any of them were created 
+-  ** since the most recent journal header was written, update the 
+-  ** PagerSavepoint.iHdrOffset fields now.
+-  */
+-  for(ii=0; ii<pPager->nSavepoint; ii++){
+-    if( pPager->aSavepoint[ii].iHdrOffset==0 ){
+-      pPager->aSavepoint[ii].iHdrOffset = pPager->journalOff;
+-    }
+-  }
+-
+-  pPager->journalHdr = pPager->journalOff = journalHdrOffset(pPager);
+-
+-  /* 
+-  ** Write the nRec Field - the number of page records that follow this
+-  ** journal header. Normally, zero is written to this value at this time.
+-  ** After the records are added to the journal (and the journal synced, 
+-  ** if in full-sync mode), the zero is overwritten with the true number
+-  ** of records (see syncJournal()).
+-  **
+-  ** A faster alternative is to write 0xFFFFFFFF to the nRec field. When
+-  ** reading the journal this value tells SQLite to assume that the
+-  ** rest of the journal file contains valid page records. This assumption
+-  ** is dangerous, as if a failure occurred whilst writing to the journal
+-  ** file it may contain some garbage data. There are two scenarios
+-  ** where this risk can be ignored:
+-  **
+-  **   * When the pager is in no-sync mode. Corruption can follow a
+-  **     power failure in this case anyway.
+-  **
+-  **   * When the SQLITE_IOCAP_SAFE_APPEND flag is set. This guarantees
+-  **     that garbage data is never appended to the journal file.
+-  */
+-  assert( isOpen(pPager->fd) || pPager->noSync );
+-  if( pPager->noSync || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY)
+-   || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) 
+-  ){
+-    memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic));
+-    put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff);
+-  }else{
+-    memset(zHeader, 0, sizeof(aJournalMagic)+4);
+-  }
+-
+-  /* The random check-hash initializer */ 
+-  sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit);
+-  put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit);
+-  /* The initial database size */
+-  put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbOrigSize);
+-  /* The assumed sector size for this process */
+-  put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize);
+-
+-  /* The page size */
+-  put32bits(&zHeader[sizeof(aJournalMagic)+16], pPager->pageSize);
+-
+-  /* Initializing the tail of the buffer is not necessary.  Everything
+-  ** works find if the following memset() is omitted.  But initializing
+-  ** the memory prevents valgrind from complaining, so we are willing to
+-  ** take the performance hit.
+-  */
+-  memset(&zHeader[sizeof(aJournalMagic)+20], 0,
+-         nHeader-(sizeof(aJournalMagic)+20));
+-
+-  /* In theory, it is only necessary to write the 28 bytes that the 
+-  ** journal header consumes to the journal file here. Then increment the 
+-  ** Pager.journalOff variable by JOURNAL_HDR_SZ so that the next 
+-  ** record is written to the following sector (leaving a gap in the file
+-  ** that will be implicitly filled in by the OS).
+-  **
+-  ** However it has been discovered that on some systems this pattern can 
+-  ** be significantly slower than contiguously writing data to the file,
+-  ** even if that means explicitly writing data to the block of 
+-  ** (JOURNAL_HDR_SZ - 28) bytes that will not be used. So that is what
+-  ** is done. 
+-  **
+-  ** The loop is required here in case the sector-size is larger than the 
+-  ** database page size. Since the zHeader buffer is only Pager.pageSize
+-  ** bytes in size, more than one call to sqlite3OsWrite() may be required
+-  ** to populate the entire journal header sector.
+-  */ 
+-  for(nWrite=0; rc==SQLITE_OK&&nWrite<JOURNAL_HDR_SZ(pPager); nWrite+=nHeader){
+-    IOTRACE(("JHDR %p %lld %d\n", pPager, pPager->journalHdr, nHeader))
+-    rc = sqlite3OsWrite(pPager->jfd, zHeader, nHeader, pPager->journalOff);
+-    assert( pPager->journalHdr <= pPager->journalOff );
+-    pPager->journalOff += nHeader;
+-  }
+-
+-  return rc;
+-}
+-
+-/*
+-** The journal file must be open when this is called. A journal header file
+-** (JOURNAL_HDR_SZ bytes) is read from the current location in the journal
+-** file. The current location in the journal file is given by
+-** pPager->journalOff. See comments above function writeJournalHdr() for
+-** a description of the journal header format.
++**    For example, if an IO error occurs while performing a rollback, 
++**    the contents of the page-cache may be left in an inconsistent state.
++**    At this point it would be dangerous to change back to READER state
++**    (as usually happens after a rollback). Any subsequent readers might
++**    report database corruption (due to the inconsistent cache), and if
++**    they upgrade to writers, they may inadvertently corrupt the database
++**    file. To avoid this hazard, the pager switches into the ERROR state
++**    instead of READER following such an error.
+ **
+-** If the header is read successfully, *pNRec is set to the number of
+-** page records following this header and *pDbSize is set to the size of the
+-** database before the transaction began, in pages. Also, pPager->cksumInit
+-** is set to the value read from the journal header. SQLITE_OK is returned
+-** in this case.
++**    Once it has entered the ERROR state, any attempt to use the pager
++**    to read or write data returns an error. Eventually, once all 
++**    outstanding transactions have been abandoned, the pager is able to
++**    transition back to OPEN state, discarding the contents of the 
++**    page-cache and any other in-memory state at the same time. Everything
++**    is reloaded from disk (and, if necessary, hot-journal rollback peformed)
++**    when a read-transaction is next opened on the pager (transitioning
++**    the pager into READER state). At that point the system has recovered 
++**    from the error.
+ **
+-** If the journal header file appears to be corrupted, SQLITE_DONE is
+-** returned and *pNRec and *PDbSize are undefined.  If JOURNAL_HDR_SZ bytes
+-** cannot be read from the journal file an error code is returned.
++**    Specifically, the pager jumps into the ERROR state if:
++**
++**      1. An error occurs while attempting a rollback. This happens in
++**         function sqlite3PagerRollback().
++**
++**      2. An error occurs while attempting to finalize a journal file
++**         following a commit in function sqlite3PagerCommitPhaseTwo().
++**
++**      3. An error occurs while attempting to write to the journal or
++**         database file in function pagerStress() in order to free up
++**         memory.
++**
++**    In other cases, the error is returned to the b-tree layer. The b-tree
++**    layer then attempts a rollback operation. If the error condition 
++**    persists, the pager enters the ERROR state via condition (1) above.
++**
++**    Condition (3) is necessary because it can be triggered by a read-only
++**    statement executed within a transaction. In this case, if the error
++**    code were simply returned to the user, the b-tree layer would not
++**    automatically attempt a rollback, as it assumes that an error in a
++**    read-only statement cannot leave the pager in an internally inconsistent 
++**    state.
++**
++**    * The Pager.errCode variable is set to something other than SQLITE_OK.
++**    * There are one or more outstanding references to pages (after the
++**      last reference is dropped the pager should move back to OPEN state).
++**    * The pager is not an in-memory pager.
++**    
++**
++** Notes:
++**
++**   * A pager is never in WRITER_DBMOD or WRITER_FINISHED state if the
++**     connection is open in WAL mode. A WAL connection is always in one
++**     of the first four states.
++**
++**   * Normally, a connection open in exclusive mode is never in PAGER_OPEN
++**     state. There are two exceptions: immediately after exclusive-mode has
++**     been turned on (and before any read or write transactions are 
++**     executed), and when the pager is leaving the "error state".
++**
++**   * See also: assert_pager_state().
+ */
+-static int readJournalHdr(
+-  Pager *pPager,               /* Pager object */
+-  int isHot,
+-  i64 journalSize,             /* Size of the open journal file in bytes */
+-  u32 *pNRec,                  /* OUT: Value read from the nRec field */
+-  u32 *pDbSize                 /* OUT: Value of original database size field */
+-){
+-  int rc;                      /* Return code */
+-  unsigned char aMagic[8];     /* A buffer to hold the magic header */
+-  i64 iHdrOff;                 /* Offset of journal header being read */
+-
+-  assert( isOpen(pPager->jfd) );      /* Journal file must be open. */
+-
+-  /* Advance Pager.journalOff to the start of the next sector. If the
+-  ** journal file is too small for there to be a header stored at this
+-  ** point, return SQLITE_DONE.
+-  */
+-  pPager->journalOff = journalHdrOffset(pPager);
+-  if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){
+-    return SQLITE_DONE;
+-  }
+-  iHdrOff = pPager->journalOff;
+-
+-  /* Read in the first 8 bytes of the journal header. If they do not match
+-  ** the  magic string found at the start of each journal header, return
+-  ** SQLITE_DONE. If an IO error occurs, return an error code. Otherwise,
+-  ** proceed.
+-  */
+-  if( isHot || iHdrOff!=pPager->journalHdr ){
+-    rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic), iHdrOff);
+-    if( rc ){
+-      return rc;
+-    }
+-    if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){
+-      return SQLITE_DONE;
+-    }
+-  }
+-
+-  /* Read the first three 32-bit fields of the journal header: The nRec
+-  ** field, the checksum-initializer and the database size at the start
+-  ** of the transaction. Return an error code if anything goes wrong.
+-  */
+-  if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+8, pNRec))
+-   || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+12, &pPager->cksumInit))
+-   || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+16, pDbSize))
+-  ){
+-    return rc;
+-  }
+-
+-  if( pPager->journalOff==0 ){
+-    u32 iPageSize;               /* Page-size field of journal header */
+-    u32 iSectorSize;             /* Sector-size field of journal header */
+-
+-    /* Read the page-size and sector-size journal header fields. */
+-    if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+20, &iSectorSize))
+-     || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+24, &iPageSize))
+-    ){
+-      return rc;
+-    }
+-
+-    /* Versions of SQLite prior to 3.5.8 set the page-size field of the
+-    ** journal header to zero. In this case, assume that the Pager.pageSize
+-    ** variable is already set to the correct page size.
+-    */
+-    if( iPageSize==0 ){
+-      iPageSize = pPager->pageSize;
+-    }
+-
+-    /* Check that the values read from the page-size and sector-size fields
+-    ** are within range. To be 'in range', both values need to be a power
+-    ** of two greater than or equal to 512 or 32, and not greater than their 
+-    ** respective compile time maximum limits.
+-    */
+-    if( iPageSize<512                  || iSectorSize<32
+-     || iPageSize>SQLITE_MAX_PAGE_SIZE || iSectorSize>MAX_SECTOR_SIZE
+-     || ((iPageSize-1)&iPageSize)!=0   || ((iSectorSize-1)&iSectorSize)!=0 
+-    ){
+-      /* If the either the page-size or sector-size in the journal-header is 
+-      ** invalid, then the process that wrote the journal-header must have 
+-      ** crashed before the header was synced. In this case stop reading 
+-      ** the journal file here.
+-      */
+-      return SQLITE_DONE;
+-    }
+-
+-    /* Update the page-size to match the value read from the journal. 
+-    ** Use a testcase() macro to make sure that malloc failure within 
+-    ** PagerSetPagesize() is tested.
+-    */
+-    rc = sqlite3PagerSetPagesize(pPager, &iPageSize, -1);
+-    testcase( rc!=SQLITE_OK );
+-
+-    /* Update the assumed sector-size to match the value used by 
+-    ** the process that created this journal. If this journal was
+-    ** created by a process other than this one, then this routine
+-    ** is being called from within pager_playback(). The local value
+-    ** of Pager.sectorSize is restored at the end of that routine.
+-    */
+-    pPager->sectorSize = iSectorSize;
+-  }
+-
+-  pPager->journalOff += JOURNAL_HDR_SZ(pPager);
+-  return rc;
+-}
+-
++#define PAGER_OPEN                  0
++#define PAGER_READER                1
++#define PAGER_WRITER_LOCKED         2
++#define PAGER_WRITER_CACHEMOD       3
++#define PAGER_WRITER_DBMOD          4
++#define PAGER_WRITER_FINISHED       5
++#define PAGER_ERROR                 6
+ 
+ /*
+-** Write the supplied master journal name into the journal file for pager
+-** pPager at the current location. The master journal name must be the last
+-** thing written to a journal file. If the pager is in full-sync mode, the
+-** journal file descriptor is advanced to the next sector boundary before
+-** anything is written. The format is:
++** The Pager.eLock variable is almost always set to one of the 
++** following locking-states, according to the lock currently held on
++** the database file: NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK.
++** This variable is kept up to date as locks are taken and released by
++** the pagerLockDb() and pagerUnlockDb() wrappers.
+ **
+-**   + 4 bytes: PAGER_MJ_PGNO.
+-**   + N bytes: Master journal filename in utf-8.
+-**   + 4 bytes: N (length of master journal name in bytes, no nul-terminator).
+-**   + 4 bytes: Master journal name checksum.
+-**   + 8 bytes: aJournalMagic[].
++** If the VFS xLock() or xUnlock() returns an error other than SQLITE_BUSY
++** (i.e. one of the SQLITE_IOERR subtypes), it is not clear whether or not
++** the operation was successful. In these circumstances pagerLockDb() and
++** pagerUnlockDb() take a conservative approach - eLock is always updated
++** when unlocking the file, and only updated when locking the file if the
++** VFS call is successful. This way, the Pager.eLock variable may be set
++** to a less exclusive (lower) value than the lock that is actually held
++** at the system level, but it is never set to a more exclusive value.
+ **
+-** The master journal page checksum is the sum of the bytes in the master
+-** journal name, where each byte is interpreted as a signed 8-bit integer.
++** This is usually safe. If an xUnlock fails or appears to fail, there may 
++** be a few redundant xLock() calls or a lock may be held for longer than
++** required, but nothing really goes wrong.
++**
++** The exception is when the database file is unlocked as the pager moves
++** from ERROR to OPEN state. At this point there may be a hot-journal file 
++** in the file-system that needs to be rolled back (as part of an OPEN->SHARED
++** transition, by the same pager or any other). If the call to xUnlock()
++** fails at this point and the pager is left holding an EXCLUSIVE lock, this
++** can confuse the call to xCheckReservedLock() call made later as part
++** of hot-journal detection.
++**
++** xCheckReservedLock() is defined as returning true "if there is a RESERVED 
++** lock held by this process or any others". So xCheckReservedLock may 
++** return true because the caller itself is holding an EXCLUSIVE lock (but
++** doesn't know it because of a previous error in xUnlock). If this happens
++** a hot-journal may be mistaken for a journal being created by an active
++** transaction in another process, causing SQLite to read from the database
++** without rolling it back.
++**
++** To work around this, if a call to xUnlock() fails when unlocking the
++** database in the ERROR state, Pager.eLock is set to UNKNOWN_LOCK. It
++** is only changed back to a real locking state after a successful call
++** to xLock(EXCLUSIVE). Also, the code to do the OPEN->SHARED state transition
++** omits the check for a hot-journal if Pager.eLock is set to UNKNOWN_LOCK 
++** lock. Instead, it assumes a hot-journal exists and obtains an EXCLUSIVE
++** lock on the database file before attempting to roll it back. See function
++** PagerSharedLock() for more detail.
+ **
+-** If zMaster is a NULL pointer (occurs for a single database transaction), 
+-** this call is a no-op.
++** Pager.eLock may only be set to UNKNOWN_LOCK when the pager is in 
++** PAGER_OPEN state.
+ */
+-static int writeMasterJournal(Pager *pPager, const char *zMaster){
+-  int rc;                          /* Return code */
+-  int nMaster;                     /* Length of string zMaster */
+-  i64 iHdrOff;                     /* Offset of header in journal file */
+-  i64 jrnlSize;                    /* Size of journal file on disk */
+-  u32 cksum = 0;                   /* Checksum of string zMaster */
+-
+-  assert( pPager->setMaster==0 );
+-  assert( !pagerUseWal(pPager) );
+-
+-  if( !zMaster 
+-   || pPager->journalMode==PAGER_JOURNALMODE_MEMORY 
+-   || !isOpen(pPager->jfd)
+-  ){
+-    return SQLITE_OK;
+-  }
+-  pPager->setMaster = 1;
+-  assert( pPager->journalHdr <= pPager->journalOff );
+-
+-  /* Calculate the length in bytes and the checksum of zMaster */
+-  for(nMaster=0; zMaster[nMaster]; nMaster++){
+-    cksum += zMaster[nMaster];
+-  }
+-
+-  /* If in full-sync mode, advance to the next disk sector before writing
+-  ** the master journal name. This is in case the previous page written to
+-  ** the journal has already been synced.
+-  */
+-  if( pPager->fullSync ){
+-    pPager->journalOff = journalHdrOffset(pPager);
+-  }
+-  iHdrOff = pPager->journalOff;
+-
+-  /* Write the master journal data to the end of the journal file. If
+-  ** an error occurs, return the error code to the caller.
+-  */
+-  if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_MJ_PGNO(pPager))))
+-   || (0 != (rc = sqlite3OsWrite(pPager->jfd, zMaster, nMaster, iHdrOff+4)))
+-   || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster, nMaster)))
+-   || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster+4, cksum)))
+-   || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, iHdrOff+4+nMaster+8)))
+-  ){
+-    return rc;
+-  }
+-  pPager->journalOff += (nMaster+20);
+-
+-  /* If the pager is in peristent-journal mode, then the physical 
+-  ** journal-file may extend past the end of the master-journal name
+-  ** and 8 bytes of magic data just written to the file. This is 
+-  ** dangerous because the code to rollback a hot-journal file
+-  ** will not be able to find the master-journal name to determine 
+-  ** whether or not the journal is hot. 
+-  **
+-  ** Easiest thing to do in this scenario is to truncate the journal 
+-  ** file to the required size.
+-  */ 
+-  if( SQLITE_OK==(rc = sqlite3OsFileSize(pPager->jfd, &jrnlSize))
+-   && jrnlSize>pPager->journalOff
+-  ){
+-    rc = sqlite3OsTruncate(pPager->jfd, pPager->journalOff);
+-  }
+-  return rc;
+-}
++#define UNKNOWN_LOCK                (EXCLUSIVE_LOCK+1)
+ 
+ /*
+-** Discard the entire contents of the in-memory page-cache.
++** A macro used for invoking the codec if there is one
+ */
+-static void pager_reset(Pager *pPager){
+-  pPager->iDataVersion++;
+-  sqlite3BackupRestart(pPager->pBackup);
+-  sqlite3PcacheClear(pPager->pPCache);
+-}
 +#ifdef SQLITE_HAS_CODEC
-+SQLITE_PRIVATE void sqlite3pager_get_codec(Pager *pPager, void **ctx) {
-+  *ctx = pPager->pCodec;
++# define CODEC1(P,D,N,X,E) \
++    if( P->xCodec && P->xCodec(P->pCodec,D,N,X)==0 ){ E; }
++# define CODEC2(P,D,N,X,E,O) \
++    if( P->xCodec==0 ){ O=(char*)D; }else \
++    if( (O=(char*)(P->xCodec(P->pCodec,D,N,X)))==0 ){ E; }
++#else
++# define CODEC1(P,D,N,X,E)   /* NO-OP */
++# define CODEC2(P,D,N,X,E,O) O=(char*)D
++#endif
+ 
+ /*
+-** Return the pPager->iDataVersion value
++** The maximum allowed sector size. 64KiB. If the xSectorsize() method 
++** returns a value larger than this, then MAX_SECTOR_SIZE is used instead.
++** This could conceivably cause corruption following a power failure on
++** such a system. This is currently an undocumented limit.
+ */
+-SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager *pPager){
+-  assert( pPager->eState>PAGER_OPEN );
+-  return pPager->iDataVersion;
+-}
++#define MAX_SECTOR_SIZE 0x10000
+ 
+ /*
+-** Free all structures in the Pager.aSavepoint[] array and set both
+-** Pager.aSavepoint and Pager.nSavepoint to zero. Close the sub-journal
+-** if it is open and the pager is not in exclusive mode.
++** An instance of the following structure is allocated for each active
++** savepoint and statement transaction in the system. All such structures
++** are stored in the Pager.aSavepoint[] array, which is allocated and
++** resized using sqlite3Realloc().
++**
++** When a savepoint is created, the PagerSavepoint.iHdrOffset field is
++** set to 0. If a journal-header is written into the main journal while
++** the savepoint is active, then iHdrOffset is set to the byte offset 
++** immediately following the last journal record written into the main
++** journal before the journal-header. This is required during savepoint
++** rollback (see pagerPlaybackSavepoint()).
+ */
+-static void releaseAllSavepoints(Pager *pPager){
+-  int ii;               /* Iterator for looping through Pager.aSavepoint */
+-  for(ii=0; ii<pPager->nSavepoint; ii++){
+-    sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
+-  }
+-  if( !pPager->exclusiveMode || sqlite3IsMemJournal(pPager->sjfd) ){
+-    sqlite3OsClose(pPager->sjfd);
+-  }
+-  sqlite3_free(pPager->aSavepoint);
+-  pPager->aSavepoint = 0;
+-  pPager->nSavepoint = 0;
+-  pPager->nSubRec = 0;
+-}
++typedef struct PagerSavepoint PagerSavepoint;
++struct PagerSavepoint {
++  i64 iOffset;                 /* Starting offset in main journal */
++  i64 iHdrOffset;              /* See above */
++  Bitvec *pInSavepoint;        /* Set of pages in this savepoint */
++  Pgno nOrig;                  /* Original number of pages in file */
++  Pgno iSubRec;                /* Index of first record in sub-journal */
++#ifndef SQLITE_OMIT_WAL
++  u32 aWalData[WAL_SAVEPOINT_NDATA];        /* WAL savepoint context */
++#endif
++};
+ 
+ /*
+-** Set the bit number pgno in the PagerSavepoint.pInSavepoint 
+-** bitvecs of all open savepoints. Return SQLITE_OK if successful
+-** or SQLITE_NOMEM if a malloc failure occurs.
++** Bits of the Pager.doNotSpill flag.  See further description below.
+ */
+-static int addToSavepointBitvecs(Pager *pPager, Pgno pgno){
+-  int ii;                   /* Loop counter */
+-  int rc = SQLITE_OK;       /* Result code */
+-
+-  for(ii=0; ii<pPager->nSavepoint; ii++){
+-    PagerSavepoint *p = &pPager->aSavepoint[ii];
+-    if( pgno<=p->nOrig ){
+-      rc |= sqlite3BitvecSet(p->pInSavepoint, pgno);
+-      testcase( rc==SQLITE_NOMEM );
+-      assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
+-    }
+-  }
+-  return rc;
+-}
++#define SPILLFLAG_OFF         0x01      /* Never spill cache.  Set via pragma */
++#define SPILLFLAG_ROLLBACK    0x02      /* Current rolling back, so do not spill */
++#define SPILLFLAG_NOSYNC      0x04      /* Spill is ok, but do not sync */
+ 
+ /*
+-** This function is a no-op if the pager is in exclusive mode and not
+-** in the ERROR state. Otherwise, it switches the pager to PAGER_OPEN
+-** state.
++** An open page cache is an instance of struct Pager. A description of
++** some of the more important member variables follows:
+ **
+-** If the pager is not in exclusive-access mode, the database file is
+-** completely unlocked. If the file is unlocked and the file-system does
+-** not exhibit the UNDELETABLE_WHEN_OPEN property, the journal file is
+-** closed (if it is open).
++** eState
+ **
+-** If the pager is in ERROR state when this function is called, the 
+-** contents of the pager cache are discarded before switching back to 
+-** the OPEN state. Regardless of whether the pager is in exclusive-mode
+-** or not, any journal file left in the file-system will be treated
+-** as a hot-journal and rolled back the next time a read-transaction
+-** is opened (by this or by any other connection).
+-*/
+-static void pager_unlock(Pager *pPager){
+-
+-  assert( pPager->eState==PAGER_READER 
+-       || pPager->eState==PAGER_OPEN 
+-       || pPager->eState==PAGER_ERROR 
+-  );
+-
+-  sqlite3BitvecDestroy(pPager->pInJournal);
+-  pPager->pInJournal = 0;
+-  releaseAllSavepoints(pPager);
+-
+-  if( pagerUseWal(pPager) ){
+-    assert( !isOpen(pPager->jfd) );
+-    sqlite3WalEndReadTransaction(pPager->pWal);
+-    pPager->eState = PAGER_OPEN;
+-  }else if( !pPager->exclusiveMode ){
+-    int rc;                       /* Error code returned by pagerUnlockDb() */
+-    int iDc = isOpen(pPager->fd)?sqlite3OsDeviceCharacteristics(pPager->fd):0;
+-
+-    /* If the operating system support deletion of open files, then
+-    ** close the journal file when dropping the database lock.  Otherwise
+-    ** another connection with journal_mode=delete might delete the file
+-    ** out from under us.
+-    */
+-    assert( (PAGER_JOURNALMODE_MEMORY   & 5)!=1 );
+-    assert( (PAGER_JOURNALMODE_OFF      & 5)!=1 );
+-    assert( (PAGER_JOURNALMODE_WAL      & 5)!=1 );
+-    assert( (PAGER_JOURNALMODE_DELETE   & 5)!=1 );
+-    assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 );
+-    assert( (PAGER_JOURNALMODE_PERSIST  & 5)==1 );
+-    if( 0==(iDc & SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN)
+-     || 1!=(pPager->journalMode & 5)
+-    ){
+-      sqlite3OsClose(pPager->jfd);
+-    }
+-
+-    /* If the pager is in the ERROR state and the call to unlock the database
+-    ** file fails, set the current lock to UNKNOWN_LOCK. See the comment
+-    ** above the #define for UNKNOWN_LOCK for an explanation of why this
+-    ** is necessary.
+-    */
+-    rc = pagerUnlockDb(pPager, NO_LOCK);
+-    if( rc!=SQLITE_OK && pPager->eState==PAGER_ERROR ){
+-      pPager->eLock = UNKNOWN_LOCK;
+-    }
+-
+-    /* The pager state may be changed from PAGER_ERROR to PAGER_OPEN here
+-    ** without clearing the error code. This is intentional - the error
+-    ** code is cleared and the cache reset in the block below.
+-    */
+-    assert( pPager->errCode || pPager->eState!=PAGER_ERROR );
+-    pPager->changeCountDone = 0;
+-    pPager->eState = PAGER_OPEN;
+-  }
+-
+-  /* If Pager.errCode is set, the contents of the pager cache cannot be
+-  ** trusted. Now that there are no outstanding references to the pager,
+-  ** it can safely move back to PAGER_OPEN state. This happens in both
+-  ** normal and exclusive-locking mode.
+-  */
+-  if( pPager->errCode ){
+-    assert( !MEMDB );
+-    pager_reset(pPager);
+-    pPager->changeCountDone = pPager->tempFile;
+-    pPager->eState = PAGER_OPEN;
+-    pPager->errCode = SQLITE_OK;
+-    if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
+-  }
+-
+-  pPager->journalOff = 0;
+-  pPager->journalHdr = 0;
+-  pPager->setMaster = 0;
+-}
+-
+-/*
+-** This function is called whenever an IOERR or FULL error that requires
+-** the pager to transition into the ERROR state may ahve occurred.
+-** The first argument is a pointer to the pager structure, the second 
+-** the error-code about to be returned by a pager API function. The 
+-** value returned is a copy of the second argument to this function. 
++**   The current 'state' of the pager object. See the comment and state
++**   diagram above for a description of the pager state.
+ **
+-** If the second argument is SQLITE_FULL, SQLITE_IOERR or one of the
+-** IOERR sub-codes, the pager enters the ERROR state and the error code
+-** is stored in Pager.errCode. While the pager remains in the ERROR state,
+-** all major API calls on the Pager will immediately return Pager.errCode.
++** eLock
+ **
+-** The ERROR state indicates that the contents of the pager-cache 
+-** cannot be trusted. This state can be cleared by completely discarding 
+-** the contents of the pager-cache. If a transaction was active when
+-** the persistent error occurred, then the rollback journal may need
+-** to be replayed to restore the contents of the database file (as if
+-** it were a hot-journal).
+-*/
+-static int pager_error(Pager *pPager, int rc){
+-  int rc2 = rc & 0xff;
+-  assert( rc==SQLITE_OK || !MEMDB );
+-  assert(
+-       pPager->errCode==SQLITE_FULL ||
+-       pPager->errCode==SQLITE_OK ||
+-       (pPager->errCode & 0xff)==SQLITE_IOERR
+-  );
+-  if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){
+-    pPager->errCode = rc;
+-    pPager->eState = PAGER_ERROR;
+-  }
+-  return rc;
+-}
+-
+-static int pager_truncate(Pager *pPager, Pgno nPage);
+-
+-/*
+-** This routine ends a transaction. A transaction is usually ended by 
+-** either a COMMIT or a ROLLBACK operation. This routine may be called 
+-** after rollback of a hot-journal, or if an error occurs while opening
+-** the journal file or writing the very first journal-header of a
+-** database transaction.
+-** 
+-** This routine is never called in PAGER_ERROR state. If it is called
+-** in PAGER_NONE or PAGER_SHARED state and the lock held is less
+-** exclusive than a RESERVED lock, it is a no-op.
++**   For a real on-disk database, the current lock held on the database file -
++**   NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK.
+ **
+-** Otherwise, any active savepoints are released.
++**   For a temporary or in-memory database (neither of which require any
++**   locks), this variable is always set to EXCLUSIVE_LOCK. Since such
++**   databases always have Pager.exclusiveMode==1, this tricks the pager
++**   logic into thinking that it already has all the locks it will ever
++**   need (and no reason to release them).
+ **
+-** If the journal file is open, then it is "finalized". Once a journal 
+-** file has been finalized it is not possible to use it to roll back a 
+-** transaction. Nor will it be considered to be a hot-journal by this
+-** or any other database connection. Exactly how a journal is finalized
+-** depends on whether or not the pager is running in exclusive mode and
+-** the current journal-mode (Pager.journalMode value), as follows:
++**   In some (obscure) circumstances, this variable may also be set to
++**   UNKNOWN_LOCK. See the comment above the #define of UNKNOWN_LOCK for
++**   details.
+ **
+-**   journalMode==MEMORY
+-**     Journal file descriptor is simply closed. This destroys an 
+-**     in-memory journal.
++** changeCountDone
+ **
+-**   journalMode==TRUNCATE
+-**     Journal file is truncated to zero bytes in size.
++**   This boolean variable is used to make sure that the change-counter 
++**   (the 4-byte header field at byte offset 24 of the database file) is 
++**   not updated more often than necessary. 
+ **
+-**   journalMode==PERSIST
+-**     The first 28 bytes of the journal file are zeroed. This invalidates
+-**     the first journal header in the file, and hence the entire journal
+-**     file. An invalid journal file cannot be rolled back.
++**   It is set to true when the change-counter field is updated, which 
++**   can only happen if an exclusive lock is held on the database file.
++**   It is cleared (set to false) whenever an exclusive lock is 
++**   relinquished on the database file. Each time a transaction is committed,
++**   The changeCountDone flag is inspected. If it is true, the work of
++**   updating the change-counter is omitted for the current transaction.
+ **
+-**   journalMode==DELETE
+-**     The journal file is closed and deleted using sqlite3OsDelete().
++**   This mechanism means that when running in exclusive mode, a connection 
++**   need only update the change-counter once, for the first transaction
++**   committed.
+ **
+-**     If the pager is running in exclusive mode, this method of finalizing
+-**     the journal file is never used. Instead, if the journalMode is
+-**     DELETE and the pager is in exclusive mode, the method described under
+-**     journalMode==PERSIST is used instead.
++** setMaster
+ **
+-** After the journal is finalized, the pager moves to PAGER_READER state.
+-** If running in non-exclusive rollback mode, the lock on the file is 
+-** downgraded to a SHARED_LOCK.
++**   When PagerCommitPhaseOne() is called to commit a transaction, it may
++**   (or may not) specify a master-journal name to be written into the 
++**   journal file before it is synced to disk.
+ **
+-** SQLITE_OK is returned if no error occurs. If an error occurs during
+-** any of the IO operations to finalize the journal file or unlock the
+-** database then the IO error code is returned to the user. If the 
+-** operation to finalize the journal file fails, then the code still
+-** tries to unlock the database file if not in exclusive mode. If the
+-** unlock operation fails as well, then the first error code related
+-** to the first error encountered (the journal finalization one) is
+-** returned.
+-*/
+-static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
+-  int rc = SQLITE_OK;      /* Error code from journal finalization operation */
+-  int rc2 = SQLITE_OK;     /* Error code from db file unlock operation */
+-
+-  /* Do nothing if the pager does not have an open write transaction
+-  ** or at least a RESERVED lock. This function may be called when there
+-  ** is no write-transaction active but a RESERVED or greater lock is
+-  ** held under two circumstances:
+-  **
+-  **   1. After a successful hot-journal rollback, it is called with
+-  **      eState==PAGER_NONE and eLock==EXCLUSIVE_LOCK.
+-  **
+-  **   2. If a connection with locking_mode=exclusive holding an EXCLUSIVE 
+-  **      lock switches back to locking_mode=normal and then executes a
+-  **      read-transaction, this function is called with eState==PAGER_READER 
+-  **      and eLock==EXCLUSIVE_LOCK when the read-transaction is closed.
+-  */
+-  assert( assert_pager_state(pPager) );
+-  assert( pPager->eState!=PAGER_ERROR );
+-  if( pPager->eState<PAGER_WRITER_LOCKED && pPager->eLock<RESERVED_LOCK ){
+-    return SQLITE_OK;
+-  }
+-
+-  releaseAllSavepoints(pPager);
+-  assert( isOpen(pPager->jfd) || pPager->pInJournal==0 );
+-  if( isOpen(pPager->jfd) ){
+-    assert( !pagerUseWal(pPager) );
+-
+-    /* Finalize the journal file. */
+-    if( sqlite3IsMemJournal(pPager->jfd) ){
+-      assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY );
+-      sqlite3OsClose(pPager->jfd);
+-    }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){
+-      if( pPager->journalOff==0 ){
+-        rc = SQLITE_OK;
+-      }else{
+-        rc = sqlite3OsTruncate(pPager->jfd, 0);
+-        if( rc==SQLITE_OK && pPager->fullSync ){
+-          /* Make sure the new file size is written into the inode right away.
+-          ** Otherwise the journal might resurrect following a power loss and
+-          ** cause the last transaction to roll back.  See
+-          ** https://bugzilla.mozilla.org/show_bug.cgi?id=1072773
+-          */
+-          rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags);
+-        }
+-      }
+-      pPager->journalOff = 0;
+-    }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST
+-      || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL)
+-    ){
+-      rc = zeroJournalHdr(pPager, hasMaster);
+-      pPager->journalOff = 0;
+-    }else{
+-      /* This branch may be executed with Pager.journalMode==MEMORY if
+-      ** a hot-journal was just rolled back. In this case the journal
+-      ** file should be closed and deleted. If this connection writes to
+-      ** the database file, it will do so using an in-memory journal. 
+-      */
+-      int bDelete = (!pPager->tempFile && sqlite3JournalExists(pPager->jfd));
+-      assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE 
+-           || pPager->journalMode==PAGER_JOURNALMODE_MEMORY 
+-           || pPager->journalMode==PAGER_JOURNALMODE_WAL 
+-      );
+-      sqlite3OsClose(pPager->jfd);
+-      if( bDelete ){
+-        rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
+-      }
+-    }
+-  }
+-
+-#ifdef SQLITE_CHECK_PAGES
+-  sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash);
+-  if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){
+-    PgHdr *p = sqlite3PagerLookup(pPager, 1);
+-    if( p ){
+-      p->pageHash = 0;
+-      sqlite3PagerUnrefNotNull(p);
+-    }
+-  }
+-#endif
+-
+-  sqlite3BitvecDestroy(pPager->pInJournal);
+-  pPager->pInJournal = 0;
+-  pPager->nRec = 0;
+-  sqlite3PcacheCleanAll(pPager->pPCache);
+-  sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);
+-
+-  if( pagerUseWal(pPager) ){
+-    /* Drop the WAL write-lock, if any. Also, if the connection was in 
+-    ** locking_mode=exclusive mode but is no longer, drop the EXCLUSIVE 
+-    ** lock held on the database file.
+-    */
+-    rc2 = sqlite3WalEndWriteTransaction(pPager->pWal);
+-    assert( rc2==SQLITE_OK );
+-  }else if( rc==SQLITE_OK && bCommit && pPager->dbFileSize>pPager->dbSize ){
+-    /* This branch is taken when committing a transaction in rollback-journal
+-    ** mode if the database file on disk is larger than the database image.
+-    ** At this point the journal has been finalized and the transaction 
+-    ** successfully committed, but the EXCLUSIVE lock is still held on the
+-    ** file. So it is safe to truncate the database file to its minimum
+-    ** required size.  */
+-    assert( pPager->eLock==EXCLUSIVE_LOCK );
+-    rc = pager_truncate(pPager, pPager->dbSize);
+-  }
+-
+-  if( rc==SQLITE_OK && bCommit && isOpen(pPager->fd) ){
+-    rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_COMMIT_PHASETWO, 0);
+-    if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
+-  }
+-
+-  if( !pPager->exclusiveMode 
+-   && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0))
+-  ){
+-    rc2 = pagerUnlockDb(pPager, SHARED_LOCK);
+-    pPager->changeCountDone = 0;
+-  }
+-  pPager->eState = PAGER_READER;
+-  pPager->setMaster = 0;
+-
+-  return (rc==SQLITE_OK?rc2:rc);
+-}
+-
+-/*
+-** Execute a rollback if a transaction is active and unlock the 
+-** database file. 
++**   Whether or not a journal file contains a master-journal pointer affects 
++**   the way in which the journal file is finalized after the transaction is 
++**   committed or rolled back when running in "journal_mode=PERSIST" mode.
++**   If a journal file does not contain a master-journal pointer, it is
++**   finalized by overwriting the first journal header with zeroes. If
++**   it does contain a master-journal pointer the journal file is finalized 
++**   by truncating it to zero bytes, just as if the connection were 
++**   running in "journal_mode=truncate" mode.
++**
++**   Journal files that contain master journal pointers cannot be finalized
++**   simply by overwriting the first journal-header with zeroes, as the
++**   master journal pointer could interfere with hot-journal rollback of any
++**   subsequently interrupted transaction that reuses the journal file.
++**
++**   The flag is cleared as soon as the journal file is finalized (either
++**   by PagerCommitPhaseTwo or PagerRollback). If an IO error prevents the
++**   journal file from being successfully finalized, the setMaster flag
++**   is cleared anyway (and the pager will move to ERROR state).
++**
++** doNotSpill
++**
++**   This variables control the behavior of cache-spills  (calls made by
++**   the pcache module to the pagerStress() routine to write cached data
++**   to the file-system in order to free up memory).
++**
++**   When bits SPILLFLAG_OFF or SPILLFLAG_ROLLBACK of doNotSpill are set,
++**   writing to the database from pagerStress() is disabled altogether.
++**   The SPILLFLAG_ROLLBACK case is done in a very obscure case that
++**   comes up during savepoint rollback that requires the pcache module
++**   to allocate a new page to prevent the journal file from being written
++**   while it is being traversed by code in pager_playback().  The SPILLFLAG_OFF
++**   case is a user preference.
++** 
++**   If the SPILLFLAG_NOSYNC bit is set, writing to the database from pagerStress()
++**   is permitted, but syncing the journal file is not. This flag is set
++**   by sqlite3PagerWrite() when the file-system sector-size is larger than
++**   the database page-size in order to prevent a journal sync from happening 
++**   in between the journalling of two pages on the same sector. 
+ **
+-** If the pager has already entered the ERROR state, do not attempt 
+-** the rollback at this time. Instead, pager_unlock() is called. The
+-** call to pager_unlock() will discard all in-memory pages, unlock
+-** the database file and move the pager back to OPEN state. If this 
+-** means that there is a hot-journal left in the file-system, the next 
+-** connection to obtain a shared lock on the pager (which may be this one) 
+-** will roll it back.
++** subjInMemory
+ **
+-** If the pager has not already entered the ERROR state, but an IO or
+-** malloc error occurs during a rollback, then this will itself cause 
+-** the pager to enter the ERROR state. Which will be cleared by the
+-** call to pager_unlock(), as described above.
+-*/
+-static void pagerUnlockAndRollback(Pager *pPager){
+-  if( pPager->eState!=PAGER_ERROR && pPager->eState!=PAGER_OPEN ){
+-    assert( assert_pager_state(pPager) );
+-    if( pPager->eState>=PAGER_WRITER_LOCKED ){
+-      sqlite3BeginBenignMalloc();
+-      sqlite3PagerRollback(pPager);
+-      sqlite3EndBenignMalloc();
+-    }else if( !pPager->exclusiveMode ){
+-      assert( pPager->eState==PAGER_READER );
+-      pager_end_transaction(pPager, 0, 0);
+-    }
+-  }
+-  pager_unlock(pPager);
+-}
+-
+-/*
+-** Parameter aData must point to a buffer of pPager->pageSize bytes
+-** of data. Compute and return a checksum based ont the contents of the 
+-** page of data and the current value of pPager->cksumInit.
++**   This is a boolean variable. If true, then any required sub-journal
++**   is opened as an in-memory journal file. If false, then in-memory
++**   sub-journals are only used for in-memory pager files.
+ **
+-** This is not a real checksum. It is really just the sum of the 
+-** random initial value (pPager->cksumInit) and every 200th byte
+-** of the page data, starting with byte offset (pPager->pageSize%200).
+-** Each byte is interpreted as an 8-bit unsigned integer.
++**   This variable is updated by the upper layer each time a new 
++**   write-transaction is opened.
+ **
+-** Changing the formula used to compute this checksum results in an
+-** incompatible journal file format.
++** dbSize, dbOrigSize, dbFileSize
+ **
+-** If journal corruption occurs due to a power failure, the most likely 
+-** scenario is that one end or the other of the record will be changed. 
+-** It is much less likely that the two ends of the journal record will be
+-** correct and the middle be corrupt.  Thus, this "checksum" scheme,
+-** though fast and simple, catches the mostly likely kind of corruption.
+-*/
+-static u32 pager_cksum(Pager *pPager, const u8 *aData){
+-  u32 cksum = pPager->cksumInit;         /* Checksum value to return */
+-  int i = pPager->pageSize-200;          /* Loop counter */
+-  while( i>0 ){
+-    cksum += aData[i];
+-    i -= 200;
+-  }
+-  return cksum;
+-}
+-
+-/*
+-** Report the current page size and number of reserved bytes back
+-** to the codec.
+-*/
+-#ifdef SQLITE_HAS_CODEC
+-static void pagerReportSize(Pager *pPager){
+-  if( pPager->xCodecSizeChng ){
+-    pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize,
+-                           (int)pPager->nReserve);
+-  }
+-}
+-#else
+-# define pagerReportSize(X)     /* No-op if we do not support a codec */
+-#endif
+-
+-/*
+-** Read a single page from either the journal file (if isMainJrnl==1) or
+-** from the sub-journal (if isMainJrnl==0) and playback that page.
+-** The page begins at offset *pOffset into the file. The *pOffset
+-** value is increased to the start of the next page in the journal.
++**   Variable dbSize is set to the number of pages in the database file.
++**   It is valid in PAGER_READER and higher states (all states except for
++**   OPEN and ERROR). 
+ **
+-** The main rollback journal uses checksums - the statement journal does 
+-** not.
++**   dbSize is set based on the size of the database file, which may be 
++**   larger than the size of the database (the value stored at offset
++**   28 of the database header by the btree). If the size of the file
++**   is not an integer multiple of the page-size, the value stored in
++**   dbSize is rounded down (i.e. a 5KB file with 2K page-size has dbSize==2).
++**   Except, any file that is greater than 0 bytes in size is considered
++**   to have at least one page. (i.e. a 1KB file with 2K page-size leads
++**   to dbSize==1).
+ **
+-** If the page number of the page record read from the (sub-)journal file
+-** is greater than the current value of Pager.dbSize, then playback is
+-** skipped and SQLITE_OK is returned.
++**   During a write-transaction, if pages with page-numbers greater than
++**   dbSize are modified in the cache, dbSize is updated accordingly.
++**   Similarly, if the database is truncated using PagerTruncateImage(), 
++**   dbSize is updated.
+ **
+-** If pDone is not NULL, then it is a record of pages that have already
+-** been played back.  If the page at *pOffset has already been played back
+-** (if the corresponding pDone bit is set) then skip the playback.
+-** Make sure the pDone bit corresponding to the *pOffset page is set
+-** prior to returning.
++**   Variables dbOrigSize and dbFileSize are valid in states 
++**   PAGER_WRITER_LOCKED and higher. dbOrigSize is a copy of the dbSize
++**   variable at the start of the transaction. It is used during rollback,
++**   and to determine whether or not pages need to be journalled before
++**   being modified.
+ **
+-** If the page record is successfully read from the (sub-)journal file
+-** and played back, then SQLITE_OK is returned. If an IO error occurs
+-** while reading the record from the (sub-)journal file or while writing
+-** to the database file, then the IO error code is returned. If data
+-** is successfully read from the (sub-)journal file but appears to be
+-** corrupted, SQLITE_DONE is returned. Data is considered corrupted in
+-** two circumstances:
+-** 
+-**   * If the record page-number is illegal (0 or PAGER_MJ_PGNO), or
+-**   * If the record is being rolled back from the main journal file
+-**     and the checksum field does not match the record content.
++**   Throughout a write-transaction, dbFileSize contains the size of
++**   the file on disk in pages. It is set to a copy of dbSize when the
++**   write-transaction is first opened, and updated when VFS calls are made
++**   to write or truncate the database file on disk. 
+ **
+-** Neither of these two scenarios are possible during a savepoint rollback.
++**   The only reason the dbFileSize variable is required is to suppress 
++**   unnecessary calls to xTruncate() after committing a transaction. If, 
++**   when a transaction is committed, the dbFileSize variable indicates 
++**   that the database file is larger than the database image (Pager.dbSize), 
++**   pager_truncate() is called. The pager_truncate() call uses xFilesize()
++**   to measure the database file on disk, and then truncates it if required.
++**   dbFileSize is not used when rolling back a transaction. In this case
++**   pager_truncate() is called unconditionally (which means there may be
++**   a call to xFilesize() that is not strictly required). In either case,
++**   pager_truncate() may cause the file to become smaller or larger.
+ **
+-** If this is a savepoint rollback, then memory may have to be dynamically
+-** allocated by this function. If this is the case and an allocation fails,
+-** SQLITE_NOMEM is returned.
++** dbHintSize
++**
++**   The dbHintSize variable is used to limit the number of calls made to
++**   the VFS xFileControl(FCNTL_SIZE_HINT) method. 
++**
++**   dbHintSize is set to a copy of the dbSize variable when a
++**   write-transaction is opened (at the same time as dbFileSize and
++**   dbOrigSize). If the xFileControl(FCNTL_SIZE_HINT) method is called,
++**   dbHintSize is increased to the number of pages that correspond to the
++**   size-hint passed to the method call. See pager_write_pagelist() for 
++**   details.
++**
++** errCode
++**
++**   The Pager.errCode variable is only ever used in PAGER_ERROR state. It
++**   is set to zero in all other states. In PAGER_ERROR state, Pager.errCode 
++**   is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX 
++**   sub-codes.
+ */
+-static int pager_playback_one_page(
+-  Pager *pPager,                /* The pager being played back */
+-  i64 *pOffset,                 /* Offset of record to playback */
+-  Bitvec *pDone,                /* Bitvec of pages already played back */
+-  int isMainJrnl,               /* 1 -> main journal. 0 -> sub-journal. */
+-  int isSavepnt                 /* True for a savepoint rollback */
+-){
+-  int rc;
+-  PgHdr *pPg;                   /* An existing page in the cache */
+-  Pgno pgno;                    /* The page number of a page in journal */
+-  u32 cksum;                    /* Checksum used for sanity checking */
+-  char *aData;                  /* Temporary storage for the page */
+-  sqlite3_file *jfd;            /* The file descriptor for the journal file */
+-  int isSynced;                 /* True if journal page is synced */
++struct Pager {
++  sqlite3_vfs *pVfs;          /* OS functions to use for IO */
++  u8 exclusiveMode;           /* Boolean. True if locking_mode==EXCLUSIVE */
++  u8 journalMode;             /* One of the PAGER_JOURNALMODE_* values */
++  u8 useJournal;              /* Use a rollback journal on this file */
++  u8 noSync;                  /* Do not sync the journal if true */
++  u8 fullSync;                /* Do extra syncs of the journal for robustness */
++  u8 ckptSyncFlags;           /* SYNC_NORMAL or SYNC_FULL for checkpoint */
++  u8 walSyncFlags;            /* SYNC_NORMAL or SYNC_FULL for wal writes */
++  u8 syncFlags;               /* SYNC_NORMAL or SYNC_FULL otherwise */
++  u8 tempFile;                /* zFilename is a temporary or immutable file */
++  u8 noLock;                  /* Do not lock (except in WAL mode) */
++  u8 readOnly;                /* True for a read-only database */
++  u8 memDb;                   /* True to inhibit all file I/O */
+ 
+-  assert( (isMainJrnl&~1)==0 );      /* isMainJrnl is 0 or 1 */
+-  assert( (isSavepnt&~1)==0 );       /* isSavepnt is 0 or 1 */
+-  assert( isMainJrnl || pDone );     /* pDone always used on sub-journals */
+-  assert( isSavepnt || pDone==0 );   /* pDone never used on non-savepoint */
++  /**************************************************************************
++  ** The following block contains those class members that change during
++  ** routine operation.  Class members not in this block are either fixed
++  ** when the pager is first created or else only change when there is a
++  ** significant mode change (such as changing the page_size, locking_mode,
++  ** or the journal_mode).  From another view, these class members describe
++  ** the "state" of the pager, while other class members describe the
++  ** "configuration" of the pager.
++  */
++  u8 eState;                  /* Pager state (OPEN, READER, WRITER_LOCKED..) */
++  u8 eLock;                   /* Current lock held on database file */
++  u8 changeCountDone;         /* Set after incrementing the change-counter */
++  u8 setMaster;               /* True if a m-j name has been written to jrnl */
++  u8 doNotSpill;              /* Do not spill the cache when non-zero */
++  u8 subjInMemory;            /* True to use in-memory sub-journals */
++  u8 bUseFetch;               /* True to use xFetch() */
++  u8 hasBeenUsed;             /* True if any content previously read from this pager*/
++  Pgno dbSize;                /* Number of pages in the database */
++  Pgno dbOrigSize;            /* dbSize before the current transaction */
++  Pgno dbFileSize;            /* Number of pages in the database file */
++  Pgno dbHintSize;            /* Value passed to FCNTL_SIZE_HINT call */
++  int errCode;                /* One of several kinds of errors */
++  int nRec;                   /* Pages journalled since last j-header written */
++  u32 cksumInit;              /* Quasi-random value added to every checksum */
++  u32 nSubRec;                /* Number of records written to sub-journal */
++  Bitvec *pInJournal;         /* One bit for each page in the database file */
++  sqlite3_file *fd;           /* File descriptor for database */
++  sqlite3_file *jfd;          /* File descriptor for main journal */
++  sqlite3_file *sjfd;         /* File descriptor for sub-journal */
++  i64 journalOff;             /* Current write offset in the journal file */
++  i64 journalHdr;             /* Byte offset to previous journal header */
++  sqlite3_backup *pBackup;    /* Pointer to list of ongoing backup processes */
++  PagerSavepoint *aSavepoint; /* Array of active savepoints */
++  int nSavepoint;             /* Number of elements in aSavepoint[] */
++  u32 iDataVersion;           /* Changes whenever database content changes */
++  char dbFileVers[16];        /* Changes whenever database file changes */
+ 
+-  aData = pPager->pTmpSpace;
+-  assert( aData );         /* Temp storage must have already been allocated */
+-  assert( pagerUseWal(pPager)==0 || (!isMainJrnl && isSavepnt) );
++  int nMmapOut;               /* Number of mmap pages currently outstanding */
++  sqlite3_int64 szMmap;       /* Desired maximum mmap size */
++  PgHdr *pMmapFreelist;       /* List of free mmap page headers (pDirty) */
++  /*
++  ** End of the routinely-changing class members
++  ***************************************************************************/
+ 
+-  /* Either the state is greater than PAGER_WRITER_CACHEMOD (a transaction 
+-  ** or savepoint rollback done at the request of the caller) or this is
+-  ** a hot-journal rollback. If it is a hot-journal rollback, the pager
+-  ** is in state OPEN and holds an EXCLUSIVE lock. Hot-journal rollback
+-  ** only reads from the main journal, not the sub-journal.
+-  */
+-  assert( pPager->eState>=PAGER_WRITER_CACHEMOD
+-       || (pPager->eState==PAGER_OPEN && pPager->eLock==EXCLUSIVE_LOCK)
+-  );
+-  assert( pPager->eState>=PAGER_WRITER_CACHEMOD || isMainJrnl );
++  u16 nExtra;                 /* Add this many bytes to each in-memory page */
++  i16 nReserve;               /* Number of unused bytes at end of each page */
++  u32 vfsFlags;               /* Flags for sqlite3_vfs.xOpen() */
++  u32 sectorSize;             /* Assumed sector size during rollback */
++  int pageSize;               /* Number of bytes in a page */
++  Pgno mxPgno;                /* Maximum allowed size of the database */
++  i64 journalSizeLimit;       /* Size limit for persistent journal files */
++  char *zFilename;            /* Name of the database file */
++  char *zJournal;             /* Name of the journal file */
++  int (*xBusyHandler)(void*); /* Function to call when busy */
++  void *pBusyHandlerArg;      /* Context argument for xBusyHandler */
++  int aStat[3];               /* Total cache hits, misses and writes */
++#ifdef SQLITE_TEST
++  int nRead;                  /* Database pages read */
++#endif
++  void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */
++#ifdef SQLITE_HAS_CODEC
++  void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
++  void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */
++  void (*xCodecFree)(void*);             /* Destructor for the codec */
++  void *pCodec;               /* First argument to xCodec... methods */
++#endif
++  char *pTmpSpace;            /* Pager.pageSize bytes of space for tmp use */
++  PCache *pPCache;            /* Pointer to page cache object */
++#ifndef SQLITE_OMIT_WAL
++  Wal *pWal;                  /* Write-ahead log used by "journal_mode=wal" */
++  char *zWal;                 /* File name for write-ahead log */
++#endif
++};
+ 
+-  /* Read the page number and page data from the journal or sub-journal
+-  ** file. Return an error code to the caller if an IO error occurs.
+-  */
+-  jfd = isMainJrnl ? pPager->jfd : pPager->sjfd;
+-  rc = read32bits(jfd, *pOffset, &pgno);
+-  if( rc!=SQLITE_OK ) return rc;
+-  rc = sqlite3OsRead(jfd, (u8*)aData, pPager->pageSize, (*pOffset)+4);
+-  if( rc!=SQLITE_OK ) return rc;
+-  *pOffset += pPager->pageSize + 4 + isMainJrnl*4;
++/*
++** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains
++** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS 
++** or CACHE_WRITE to sqlite3_db_status().
++*/
++#define PAGER_STAT_HIT   0
++#define PAGER_STAT_MISS  1
++#define PAGER_STAT_WRITE 2
+ 
+-  /* Sanity checking on the page.  This is more important that I originally
+-  ** thought.  If a power failure occurs while the journal is being written,
+-  ** it could cause invalid data to be written into the journal.  We need to
+-  ** detect this invalid data (with high probability) and ignore it.
+-  */
+-  if( pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){
+-    assert( !isSavepnt );
+-    return SQLITE_DONE;
+-  }
+-  if( pgno>(Pgno)pPager->dbSize || sqlite3BitvecTest(pDone, pgno) ){
+-    return SQLITE_OK;
+-  }
+-  if( isMainJrnl ){
+-    rc = read32bits(jfd, (*pOffset)-4, &cksum);
+-    if( rc ) return rc;
+-    if( !isSavepnt && pager_cksum(pPager, (u8*)aData)!=cksum ){
+-      return SQLITE_DONE;
+-    }
+-  }
++/*
++** The following global variables hold counters used for
++** testing purposes only.  These variables do not exist in
++** a non-testing build.  These variables are not thread-safe.
++*/
++#ifdef SQLITE_TEST
++SQLITE_API int sqlite3_pager_readdb_count = 0;    /* Number of full pages read from DB */
++SQLITE_API int sqlite3_pager_writedb_count = 0;   /* Number of full pages written to DB */
++SQLITE_API int sqlite3_pager_writej_count = 0;    /* Number of pages written to journal */
++# define PAGER_INCR(v)  v++
++#else
++# define PAGER_INCR(v)
++#endif
+ 
+-  /* If this page has already been played by before during the current
+-  ** rollback, then don't bother to play it back again.
+-  */
+-  if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){
+-    return rc;
+-  }
+ 
+-  /* When playing back page 1, restore the nReserve setting
+-  */
+-  if( pgno==1 && pPager->nReserve!=((u8*)aData)[20] ){
+-    pPager->nReserve = ((u8*)aData)[20];
+-    pagerReportSize(pPager);
+-  }
+ 
+-  /* If the pager is in CACHEMOD state, then there must be a copy of this
+-  ** page in the pager cache. In this case just update the pager cache,
+-  ** not the database file. The page is left marked dirty in this case.
+-  **
+-  ** An exception to the above rule: If the database is in no-sync mode
+-  ** and a page is moved during an incremental vacuum then the page may
+-  ** not be in the pager cache. Later: if a malloc() or IO error occurs
+-  ** during a Movepage() call, then the page may not be in the cache
+-  ** either. So the condition described in the above paragraph is not
+-  ** assert()able.
+-  **
+-  ** If in WRITER_DBMOD, WRITER_FINISHED or OPEN state, then we update the
+-  ** pager cache if it exists and the main file. The page is then marked 
+-  ** not dirty. Since this code is only executed in PAGER_OPEN state for
+-  ** a hot-journal rollback, it is guaranteed that the page-cache is empty
+-  ** if the pager is in OPEN state.
+-  **
+-  ** Ticket #1171:  The statement journal might contain page content that is
+-  ** different from the page content at the start of the transaction.
+-  ** This occurs when a page is changed prior to the start of a statement
+-  ** then changed again within the statement.  When rolling back such a
+-  ** statement we must not write to the original database unless we know
+-  ** for certain that original page contents are synced into the main rollback
+-  ** journal.  Otherwise, a power loss might leave modified data in the
+-  ** database file without an entry in the rollback journal that can
+-  ** restore the database to its original form.  Two conditions must be
+-  ** met before writing to the database files. (1) the database must be
+-  ** locked.  (2) we know that the original page content is fully synced
+-  ** in the main journal either because the page is not in cache or else
+-  ** the page is marked as needSync==0.
+-  **
+-  ** 2008-04-14:  When attempting to vacuum a corrupt database file, it
+-  ** is possible to fail a statement on a database that does not yet exist.
+-  ** Do not attempt to write if database file has never been opened.
+-  */
+-  if( pagerUseWal(pPager) ){
+-    pPg = 0;
+-  }else{
+-    pPg = sqlite3PagerLookup(pPager, pgno);
+-  }
+-  assert( pPg || !MEMDB );
+-  assert( pPager->eState!=PAGER_OPEN || pPg==0 );
+-  PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n",
+-           PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, (u8*)aData),
+-           (isMainJrnl?"main-journal":"sub-journal")
+-  ));
+-  if( isMainJrnl ){
+-    isSynced = pPager->noSync || (*pOffset <= pPager->journalHdr);
+-  }else{
+-    isSynced = (pPg==0 || 0==(pPg->flags & PGHDR_NEED_SYNC));
+-  }
+-  if( isOpen(pPager->fd)
+-   && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
+-   && isSynced
+-  ){
+-    i64 ofst = (pgno-1)*(i64)pPager->pageSize;
+-    testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 );
+-    assert( !pagerUseWal(pPager) );
+-    rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
+-    if( pgno>pPager->dbFileSize ){
+-      pPager->dbFileSize = pgno;
+-    }
+-    if( pPager->pBackup ){
+-      CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM);
+-      sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
+-      CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM, aData);
+-    }
+-  }else if( !isMainJrnl && pPg==0 ){
+-    /* If this is a rollback of a savepoint and data was not written to
+-    ** the database and the page is not in-memory, there is a potential
+-    ** problem. When the page is next fetched by the b-tree layer, it 
+-    ** will be read from the database file, which may or may not be 
+-    ** current. 
+-    **
+-    ** There are a couple of different ways this can happen. All are quite
+-    ** obscure. When running in synchronous mode, this can only happen 
+-    ** if the page is on the free-list at the start of the transaction, then
+-    ** populated, then moved using sqlite3PagerMovepage().
+-    **
+-    ** The solution is to add an in-memory page to the cache containing
+-    ** the data just read from the sub-journal. Mark the page as dirty 
+-    ** and if the pager requires a journal-sync, then mark the page as 
+-    ** requiring a journal-sync before it is written.
+-    */
+-    assert( isSavepnt );
+-    assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 );
+-    pPager->doNotSpill |= SPILLFLAG_ROLLBACK;
+-    rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1);
+-    assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 );
+-    pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK;
+-    if( rc!=SQLITE_OK ) return rc;
+-    pPg->flags &= ~PGHDR_NEED_READ;
+-    sqlite3PcacheMakeDirty(pPg);
+-  }
+-  if( pPg ){
+-    /* No page should ever be explicitly rolled back that is in use, except
+-    ** for page 1 which is held in use in order to keep the lock on the
+-    ** database active. However such a page may be rolled back as a result
+-    ** of an internal error resulting in an automatic call to
+-    ** sqlite3PagerRollback().
+-    */
+-    void *pData;
+-    pData = pPg->pData;
+-    memcpy(pData, (u8*)aData, pPager->pageSize);
+-    pPager->xReiniter(pPg);
+-    if( isMainJrnl && (!isSavepnt || *pOffset<=pPager->journalHdr) ){
+-      /* If the contents of this page were just restored from the main 
+-      ** journal file, then its content must be as they were when the 
+-      ** transaction was first opened. In this case we can mark the page
+-      ** as clean, since there will be no need to write it out to the
+-      ** database.
+-      **
+-      ** There is one exception to this rule. If the page is being rolled
+-      ** back as part of a savepoint (or statement) rollback from an 
+-      ** unsynced portion of the main journal file, then it is not safe
+-      ** to mark the page as clean. This is because marking the page as
+-      ** clean will clear the PGHDR_NEED_SYNC flag. Since the page is
+-      ** already in the journal file (recorded in Pager.pInJournal) and
+-      ** the PGHDR_NEED_SYNC flag is cleared, if the page is written to
+-      ** again within this transaction, it will be marked as dirty but
+-      ** the PGHDR_NEED_SYNC flag will not be set. It could then potentially
+-      ** be written out into the database file before its journal file
+-      ** segment is synced. If a crash occurs during or following this,
+-      ** database corruption may ensue.
+-      */
+-      assert( !pagerUseWal(pPager) );
+-      sqlite3PcacheMakeClean(pPg);
+-    }
+-    pager_set_pagehash(pPg);
++/*
++** Journal files begin with the following magic string.  The data
++** was obtained from /dev/random.  It is used only as a sanity check.
++**
++** Since version 2.8.0, the journal format contains additional sanity
++** checking information.  If the power fails while the journal is being
++** written, semi-random garbage data might appear in the journal
++** file after power is restored.  If an attempt is then made
++** to roll the journal back, the database could be corrupted.  The additional
++** sanity checking data is an attempt to discover the garbage in the
++** journal and ignore it.
++**
++** The sanity checking information for the new journal format consists
++** of a 32-bit checksum on each page of data.  The checksum covers both
++** the page number and the pPager->pageSize bytes of data for the page.
++** This cksum is initialized to a 32-bit random value that appears in the
++** journal file right after the header.  The random initializer is important,
++** because garbage data that appears at the end of a journal is likely
++** data that was once in other files that have now been deleted.  If the
++** garbage data came from an obsolete journal file, the checksums might
++** be correct.  But by initializing the checksum to random value which
++** is different for every journal, we minimize that risk.
++*/
++static const unsigned char aJournalMagic[] = {
++  0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63, 0xd7,
++};
++
++/*
++** The size of the of each page record in the journal is given by
++** the following macro.
++*/
++#define JOURNAL_PG_SZ(pPager)  ((pPager->pageSize) + 8)
++
++/*
++** The journal header size for this pager. This is usually the same 
++** size as a single disk sector. See also setSectorSize().
++*/
++#define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize)
++
++/*
++** The macro MEMDB is true if we are dealing with an in-memory database.
++** We do this as a macro so that if the SQLITE_OMIT_MEMORYDB macro is set,
++** the value of MEMDB will be a constant and the compiler will optimize
++** out code that would never execute.
++*/
++#ifdef SQLITE_OMIT_MEMORYDB
++# define MEMDB 0
++#else
++# define MEMDB pPager->memDb
++#endif
+ 
+-    /* If this was page 1, then restore the value of Pager.dbFileVers.
+-    ** Do this before any decoding. */
+-    if( pgno==1 ){
+-      memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers));
+-    }
++/*
++** The macro USEFETCH is true if we are allowed to use the xFetch and xUnfetch
++** interfaces to access the database using memory-mapped I/O.
++*/
++#if SQLITE_MAX_MMAP_SIZE>0
++# define USEFETCH(x) ((x)->bUseFetch)
++#else
++# define USEFETCH(x) 0
++#endif
+ 
+-    /* Decode the page just read from disk */
+-    CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM);
+-    sqlite3PcacheRelease(pPg);
+-  }
+-  return rc;
+-}
++/*
++** The maximum legal page number is (2^31 - 1).
++*/
++#define PAGER_MAX_PGNO 2147483647
+ 
+ /*
+-** Parameter zMaster is the name of a master journal file. A single journal
+-** file that referred to the master journal file has just been rolled back.
+-** This routine checks if it is possible to delete the master journal file,
+-** and does so if it is.
+-**
+-** Argument zMaster may point to Pager.pTmpSpace. So that buffer is not 
+-** available for use within this function.
+-**
+-** When a master journal file is created, it is populated with the names 
+-** of all of its child journals, one after another, formatted as utf-8 
+-** encoded text. The end of each child journal file is marked with a 
+-** nul-terminator byte (0x00). i.e. the entire contents of a master journal
+-** file for a transaction involving two databases might be:
+-**
+-**   "/home/bill/a.db-journal\x00/home/bill/b.db-journal\x00"
++** The argument to this macro is a file descriptor (type sqlite3_file*).
++** Return 0 if it is not open, or non-zero (but not 1) if it is.
+ **
+-** A master journal file may only be deleted once all of its child 
+-** journals have been rolled back.
++** This is so that expressions can be written as:
+ **
+-** This function reads the contents of the master-journal file into 
+-** memory and loops through each of the child journal names. For
+-** each child journal, it checks if:
++**   if( isOpen(pPager->jfd) ){ ...
+ **
+-**   * if the child journal exists, and if so
+-**   * if the child journal contains a reference to master journal 
+-**     file zMaster
++** instead of
+ **
+-** If a child journal can be found that matches both of the criteria
+-** above, this function returns without doing anything. Otherwise, if
+-** no such child journal can be found, file zMaster is deleted from
+-** the file-system using sqlite3OsDelete().
++**   if( pPager->jfd->pMethods ){ ...
++*/
++#define isOpen(pFd) ((pFd)->pMethods)
++
++/*
++** Return true if this pager uses a write-ahead log instead of the usual
++** rollback journal. Otherwise false.
++*/
++#ifndef SQLITE_OMIT_WAL
++static int pagerUseWal(Pager *pPager){
++  return (pPager->pWal!=0);
++}
++#else
++# define pagerUseWal(x) 0
++# define pagerRollbackWal(x) 0
++# define pagerWalFrames(v,w,x,y) 0
++# define pagerOpenWalIfPresent(z) SQLITE_OK
++# define pagerBeginReadTransaction(z) SQLITE_OK
++#endif
++
++#ifndef NDEBUG 
++/*
++** Usage:
+ **
+-** If an IO error within this function, an error code is returned. This
+-** function allocates memory by calling sqlite3Malloc(). If an allocation
+-** fails, SQLITE_NOMEM is returned. Otherwise, if no IO or malloc errors 
+-** occur, SQLITE_OK is returned.
++**   assert( assert_pager_state(pPager) );
+ **
+-** TODO: This function allocates a single block of memory to load
+-** the entire contents of the master journal file. This could be
+-** a couple of kilobytes or so - potentially larger than the page 
+-** size.
++** This function runs many asserts to try to find inconsistencies in
++** the internal state of the Pager object.
+ */
+-static int pager_delmaster(Pager *pPager, const char *zMaster){
+-  sqlite3_vfs *pVfs = pPager->pVfs;
+-  int rc;                   /* Return code */
+-  sqlite3_file *pMaster;    /* Malloc'd master-journal file descriptor */
+-  sqlite3_file *pJournal;   /* Malloc'd child-journal file descriptor */
+-  char *zMasterJournal = 0; /* Contents of master journal file */
+-  i64 nMasterJournal;       /* Size of master journal file */
+-  char *zJournal;           /* Pointer to one journal within MJ file */
+-  char *zMasterPtr;         /* Space to hold MJ filename from a journal file */
+-  int nMasterPtr;           /* Amount of space allocated to zMasterPtr[] */
++static int assert_pager_state(Pager *p){
++  Pager *pPager = p;
+ 
+-  /* Allocate space for both the pJournal and pMaster file descriptors.
+-  ** If successful, open the master journal file for reading.
++  /* State must be valid. */
++  assert( p->eState==PAGER_OPEN
++       || p->eState==PAGER_READER
++       || p->eState==PAGER_WRITER_LOCKED
++       || p->eState==PAGER_WRITER_CACHEMOD
++       || p->eState==PAGER_WRITER_DBMOD
++       || p->eState==PAGER_WRITER_FINISHED
++       || p->eState==PAGER_ERROR
++  );
++
++  /* Regardless of the current state, a temp-file connection always behaves
++  ** as if it has an exclusive lock on the database file. It never updates
++  ** the change-counter field, so the changeCountDone flag is always set.
+   */
+-  pMaster = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2);
+-  pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile);
+-  if( !pMaster ){
+-    rc = SQLITE_NOMEM;
+-  }else{
+-    const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
+-    rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0);
+-  }
+-  if( rc!=SQLITE_OK ) goto delmaster_out;
++  assert( p->tempFile==0 || p->eLock==EXCLUSIVE_LOCK );
++  assert( p->tempFile==0 || pPager->changeCountDone );
+ 
+-  /* Load the entire master journal file into space obtained from
+-  ** sqlite3_malloc() and pointed to by zMasterJournal.   Also obtain
+-  ** sufficient space (in zMasterPtr) to hold the names of master
+-  ** journal files extracted from regular rollback-journals.
++  /* If the useJournal flag is clear, the journal-mode must be "OFF". 
++  ** And if the journal-mode is "OFF", the journal file must not be open.
+   */
+-  rc = sqlite3OsFileSize(pMaster, &nMasterJournal);
+-  if( rc!=SQLITE_OK ) goto delmaster_out;
+-  nMasterPtr = pVfs->mxPathname+1;
+-  zMasterJournal = sqlite3Malloc(nMasterJournal + nMasterPtr + 1);
+-  if( !zMasterJournal ){
+-    rc = SQLITE_NOMEM;
+-    goto delmaster_out;
++  assert( p->journalMode==PAGER_JOURNALMODE_OFF || p->useJournal );
++  assert( p->journalMode!=PAGER_JOURNALMODE_OFF || !isOpen(p->jfd) );
++
++  /* Check that MEMDB implies noSync. And an in-memory journal. Since 
++  ** this means an in-memory pager performs no IO at all, it cannot encounter 
++  ** either SQLITE_IOERR or SQLITE_FULL during rollback or while finalizing 
++  ** a journal file. (although the in-memory journal implementation may 
++  ** return SQLITE_IOERR_NOMEM while the journal file is being written). It 
++  ** is therefore not possible for an in-memory pager to enter the ERROR 
++  ** state.
++  */
++  if( MEMDB ){
++    assert( p->noSync );
++    assert( p->journalMode==PAGER_JOURNALMODE_OFF 
++         || p->journalMode==PAGER_JOURNALMODE_MEMORY 
++    );
++    assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN );
++    assert( pagerUseWal(p)==0 );
+   }
+-  zMasterPtr = &zMasterJournal[nMasterJournal+1];
+-  rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0);
+-  if( rc!=SQLITE_OK ) goto delmaster_out;
+-  zMasterJournal[nMasterJournal] = 0;
+ 
+-  zJournal = zMasterJournal;
+-  while( (zJournal-zMasterJournal)<nMasterJournal ){
+-    int exists;
+-    rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS, &exists);
+-    if( rc!=SQLITE_OK ){
+-      goto delmaster_out;
+-    }
+-    if( exists ){
+-      /* One of the journals pointed to by the master journal exists.
+-      ** Open it and check if it points at the master journal. If
+-      ** so, return without deleting the master journal file.
+-      */
+-      int c;
+-      int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL);
+-      rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0);
+-      if( rc!=SQLITE_OK ){
+-        goto delmaster_out;
+-      }
++  /* If changeCountDone is set, a RESERVED lock or greater must be held
++  ** on the file.
++  */
++  assert( pPager->changeCountDone==0 || pPager->eLock>=RESERVED_LOCK );
++  assert( p->eLock!=PENDING_LOCK );
+ 
+-      rc = readMasterJournal(pJournal, zMasterPtr, nMasterPtr);
+-      sqlite3OsClose(pJournal);
+-      if( rc!=SQLITE_OK ){
+-        goto delmaster_out;
++  switch( p->eState ){
++    case PAGER_OPEN:
++      assert( !MEMDB );
++      assert( pPager->errCode==SQLITE_OK );
++      assert( sqlite3PcacheRefCount(pPager->pPCache)==0 || pPager->tempFile );
++      break;
++
++    case PAGER_READER:
++      assert( pPager->errCode==SQLITE_OK );
++      assert( p->eLock!=UNKNOWN_LOCK );
++      assert( p->eLock>=SHARED_LOCK );
++      break;
++
++    case PAGER_WRITER_LOCKED:
++      assert( p->eLock!=UNKNOWN_LOCK );
++      assert( pPager->errCode==SQLITE_OK );
++      if( !pagerUseWal(pPager) ){
++        assert( p->eLock>=RESERVED_LOCK );
+       }
++      assert( pPager->dbSize==pPager->dbOrigSize );
++      assert( pPager->dbOrigSize==pPager->dbFileSize );
++      assert( pPager->dbOrigSize==pPager->dbHintSize );
++      assert( pPager->setMaster==0 );
++      break;
+ 
+-      c = zMasterPtr[0]!=0 && strcmp(zMasterPtr, zMaster)==0;
+-      if( c ){
+-        /* We have a match. Do not delete the master journal file. */
+-        goto delmaster_out;
++    case PAGER_WRITER_CACHEMOD:
++      assert( p->eLock!=UNKNOWN_LOCK );
++      assert( pPager->errCode==SQLITE_OK );
++      if( !pagerUseWal(pPager) ){
++        /* It is possible that if journal_mode=wal here that neither the
++        ** journal file nor the WAL file are open. This happens during
++        ** a rollback transaction that switches from journal_mode=off
++        ** to journal_mode=wal.
++        */
++        assert( p->eLock>=RESERVED_LOCK );
++        assert( isOpen(p->jfd) 
++             || p->journalMode==PAGER_JOURNALMODE_OFF 
++             || p->journalMode==PAGER_JOURNALMODE_WAL 
++        );
+       }
++      assert( pPager->dbOrigSize==pPager->dbFileSize );
++      assert( pPager->dbOrigSize==pPager->dbHintSize );
++      break;
++
++    case PAGER_WRITER_DBMOD:
++      assert( p->eLock==EXCLUSIVE_LOCK );
++      assert( pPager->errCode==SQLITE_OK );
++      assert( !pagerUseWal(pPager) );
++      assert( p->eLock>=EXCLUSIVE_LOCK );
++      assert( isOpen(p->jfd) 
++           || p->journalMode==PAGER_JOURNALMODE_OFF 
++           || p->journalMode==PAGER_JOURNALMODE_WAL 
++      );
++      assert( pPager->dbOrigSize<=pPager->dbHintSize );
++      break;
++
++    case PAGER_WRITER_FINISHED:
++      assert( p->eLock==EXCLUSIVE_LOCK );
++      assert( pPager->errCode==SQLITE_OK );
++      assert( !pagerUseWal(pPager) );
++      assert( isOpen(p->jfd) 
++           || p->journalMode==PAGER_JOURNALMODE_OFF 
++           || p->journalMode==PAGER_JOURNALMODE_WAL 
++      );
++      break;
++
++    case PAGER_ERROR:
++      /* There must be at least one outstanding reference to the pager if
++      ** in ERROR state. Otherwise the pager should have already dropped
++      ** back to OPEN state.
++      */
++      assert( pPager->errCode!=SQLITE_OK );
++      assert( sqlite3PcacheRefCount(pPager->pPCache)>0 );
++      break;
++  }
++
++  return 1;
 +}
++#endif /* ifndef NDEBUG */
 +
-+SQLITE_PRIVATE int sqlite3pager_is_mj_pgno(Pager *pPager, Pgno pgno) {
-+  return (PAGER_MJ_PGNO(pPager) == pgno) ? 1 : 0;
++#ifdef SQLITE_DEBUG 
++/*
++** Return a pointer to a human readable string in a static buffer
++** containing the state of the Pager object passed as an argument. This
++** is intended to be used within debuggers. For example, as an alternative
++** to "print *pPager" in gdb:
++**
++** (gdb) printf "%s", print_pager_state(pPager)
++*/
++static char *print_pager_state(Pager *p){
++  static char zRet[1024];
++
++  sqlite3_snprintf(1024, zRet,
++      "Filename:      %s\n"
++      "State:         %s errCode=%d\n"
++      "Lock:          %s\n"
++      "Locking mode:  locking_mode=%s\n"
++      "Journal mode:  journal_mode=%s\n"
++      "Backing store: tempFile=%d memDb=%d useJournal=%d\n"
++      "Journal:       journalOff=%lld journalHdr=%lld\n"
++      "Size:          dbsize=%d dbOrigSize=%d dbFileSize=%d\n"
++      , p->zFilename
++      , p->eState==PAGER_OPEN            ? "OPEN" :
++        p->eState==PAGER_READER          ? "READER" :
++        p->eState==PAGER_WRITER_LOCKED   ? "WRITER_LOCKED" :
++        p->eState==PAGER_WRITER_CACHEMOD ? "WRITER_CACHEMOD" :
++        p->eState==PAGER_WRITER_DBMOD    ? "WRITER_DBMOD" :
++        p->eState==PAGER_WRITER_FINISHED ? "WRITER_FINISHED" :
++        p->eState==PAGER_ERROR           ? "ERROR" : "?error?"
++      , (int)p->errCode
++      , p->eLock==NO_LOCK         ? "NO_LOCK" :
++        p->eLock==RESERVED_LOCK   ? "RESERVED" :
++        p->eLock==EXCLUSIVE_LOCK  ? "EXCLUSIVE" :
++        p->eLock==SHARED_LOCK     ? "SHARED" :
++        p->eLock==UNKNOWN_LOCK    ? "UNKNOWN" : "?error?"
++      , p->exclusiveMode ? "exclusive" : "normal"
++      , p->journalMode==PAGER_JOURNALMODE_MEMORY   ? "memory" :
++        p->journalMode==PAGER_JOURNALMODE_OFF      ? "off" :
++        p->journalMode==PAGER_JOURNALMODE_DELETE   ? "delete" :
++        p->journalMode==PAGER_JOURNALMODE_PERSIST  ? "persist" :
++        p->journalMode==PAGER_JOURNALMODE_TRUNCATE ? "truncate" :
++        p->journalMode==PAGER_JOURNALMODE_WAL      ? "wal" : "?error?"
++      , (int)p->tempFile, (int)p->memDb, (int)p->useJournal
++      , p->journalOff, p->journalHdr
++      , (int)p->dbSize, (int)p->dbOrigSize, (int)p->dbFileSize
++  );
++
++  return zRet;
 +}
++#endif
 +
-+SQLITE_PRIVATE sqlite3_file *sqlite3Pager_get_fd(Pager *pPager) {
-+  return (isOpen(pPager->fd)) ? pPager->fd : NULL;
++/*
++** Return true if it is necessary to write page *pPg into the sub-journal.
++** A page needs to be written into the sub-journal if there exists one
++** or more open savepoints for which:
++**
++**   * The page-number is less than or equal to PagerSavepoint.nOrig, and
++**   * The bit corresponding to the page-number is not set in
++**     PagerSavepoint.pInSavepoint.
++*/
++static int subjRequiresPage(PgHdr *pPg){
++  Pager *pPager = pPg->pPager;
++  PagerSavepoint *p;
++  Pgno pgno = pPg->pgno;
++  int i;
++  for(i=0; i<pPager->nSavepoint; i++){
++    p = &pPager->aSavepoint[i];
++    if( p->nOrig>=pgno && 0==sqlite3BitvecTest(p->pInSavepoint, pgno) ){
++      return 1;
+     }
+-    zJournal += (sqlite3Strlen30(zJournal)+1);
+   }
+- 
+-  sqlite3OsClose(pMaster);
+-  rc = sqlite3OsDelete(pVfs, zMaster, 0);
++  return 0;
++}
+ 
+-delmaster_out:
+-  sqlite3_free(zMasterJournal);
+-  if( pMaster ){
+-    sqlite3OsClose(pMaster);
+-    assert( !isOpen(pJournal) );
+-    sqlite3_free(pMaster);
++/*
++** Return true if the page is already in the journal file.
++*/
++static int pageInJournal(Pager *pPager, PgHdr *pPg){
++  return sqlite3BitvecTest(pPager->pInJournal, pPg->pgno);
 +}
 +
-+SQLITE_PRIVATE void sqlite3pager_sqlite3PagerSetCodec(
-+  Pager *pPager,
-+  void *(*xCodec)(void*,void*,Pgno,int),
-+  void (*xCodecSizeChng)(void*,int,int),
-+  void (*xCodecFree)(void*),
-+  void *pCodec
++/*
++** Read a 32-bit integer from the given file descriptor.  Store the integer
++** that is read in *pRes.  Return SQLITE_OK if everything worked, or an
++** error code is something goes wrong.
++**
++** All values are stored on disk as big-endian.
++*/
++static int read32bits(sqlite3_file *fd, i64 offset, u32 *pRes){
++  unsigned char ac[4];
++  int rc = sqlite3OsRead(fd, ac, sizeof(ac), offset);
++  if( rc==SQLITE_OK ){
++    *pRes = sqlite3Get4byte(ac);
++  }
++  return rc;
++}
++
++/*
++** Write a 32-bit integer into a string buffer in big-endian byte order.
++*/
++#define put32bits(A,B)  sqlite3Put4byte((u8*)A,B)
++
++
++/*
++** Write a 32-bit integer into the given file descriptor.  Return SQLITE_OK
++** on success or an error code is something goes wrong.
++*/
++static int write32bits(sqlite3_file *fd, i64 offset, u32 val){
++  char ac[4];
++  put32bits(ac, val);
++  return sqlite3OsWrite(fd, ac, 4, offset);
++}
++
++/*
++** Unlock the database file to level eLock, which must be either NO_LOCK
++** or SHARED_LOCK. Regardless of whether or not the call to xUnlock()
++** succeeds, set the Pager.eLock variable to match the (attempted) new lock.
++**
++** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is
++** called, do not modify it. See the comment above the #define of 
++** UNKNOWN_LOCK for an explanation of this.
++*/
++static int pagerUnlockDb(Pager *pPager, int eLock){
++  int rc = SQLITE_OK;
++
++  assert( !pPager->exclusiveMode || pPager->eLock==eLock );
++  assert( eLock==NO_LOCK || eLock==SHARED_LOCK );
++  assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 );
++  if( isOpen(pPager->fd) ){
++    assert( pPager->eLock>=eLock );
++    rc = pPager->noLock ? SQLITE_OK : sqlite3OsUnlock(pPager->fd, eLock);
++    if( pPager->eLock!=UNKNOWN_LOCK ){
++      pPager->eLock = (u8)eLock;
++    }
++    IOTRACE(("UNLOCK %p %d\n", pPager, eLock))
+   }
+   return rc;
+ }
+ 
++/*
++** Lock the database file to level eLock, which must be either SHARED_LOCK,
++** RESERVED_LOCK or EXCLUSIVE_LOCK. If the caller is successful, set the
++** Pager.eLock variable to the new locking state. 
++**
++** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is 
++** called, do not modify it unless the new locking state is EXCLUSIVE_LOCK. 
++** See the comment above the #define of UNKNOWN_LOCK for an explanation 
++** of this.
++*/
++static int pagerLockDb(Pager *pPager, int eLock){
++  int rc = SQLITE_OK;
++
++  assert( eLock==SHARED_LOCK || eLock==RESERVED_LOCK || eLock==EXCLUSIVE_LOCK );
++  if( pPager->eLock<eLock || pPager->eLock==UNKNOWN_LOCK ){
++    rc = pPager->noLock ? SQLITE_OK : sqlite3OsLock(pPager->fd, eLock);
++    if( rc==SQLITE_OK && (pPager->eLock!=UNKNOWN_LOCK||eLock==EXCLUSIVE_LOCK) ){
++      pPager->eLock = (u8)eLock;
++      IOTRACE(("LOCK %p %d\n", pPager, eLock))
++    }
++  }
++  return rc;
++}
+ 
+ /*
+-** This function is used to change the actual size of the database 
+-** file in the file-system. This only happens when committing a transaction,
+-** or rolling back a transaction (including rolling back a hot-journal).
++** This function determines whether or not the atomic-write optimization
++** can be used with this pager. The optimization can be used if:
+ **
+-** If the main database file is not open, or the pager is not in either
+-** DBMOD or OPEN state, this function is a no-op. Otherwise, the size 
+-** of the file is changed to nPage pages (nPage*pPager->pageSize bytes). 
+-** If the file on disk is currently larger than nPage pages, then use the VFS
+-** xTruncate() method to truncate it.
++**  (a) the value returned by OsDeviceCharacteristics() indicates that
++**      a database page may be written atomically, and
++**  (b) the value returned by OsSectorSize() is less than or equal
++**      to the page size.
+ **
+-** Or, it might be the case that the file on disk is smaller than 
+-** nPage pages. Some operating system implementations can get confused if 
+-** you try to truncate a file to some size that is larger than it 
+-** currently is, so detect this case and write a single zero byte to 
+-** the end of the new file instead.
++** The optimization is also always enabled for temporary files. It is
++** an error to call this function if pPager is opened on an in-memory
++** database.
+ **
+-** If successful, return SQLITE_OK. If an IO error occurs while modifying
+-** the database file, return the error code to the caller.
++** If the optimization cannot be used, 0 is returned. If it can be used,
++** then the value returned is the size of the journal file when it
++** contains rollback data for exactly one page.
+ */
+-static int pager_truncate(Pager *pPager, Pgno nPage){
+-  int rc = SQLITE_OK;
+-  assert( pPager->eState!=PAGER_ERROR );
+-  assert( pPager->eState!=PAGER_READER );
+-  
+-  if( isOpen(pPager->fd) 
+-   && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) 
+-  ){
+-    i64 currentSize, newSize;
+-    int szPage = pPager->pageSize;
+-    assert( pPager->eLock==EXCLUSIVE_LOCK );
+-    /* TODO: Is it safe to use Pager.dbFileSize here? */
+-    rc = sqlite3OsFileSize(pPager->fd, &currentSize);
+-    newSize = szPage*(i64)nPage;
+-    if( rc==SQLITE_OK && currentSize!=newSize ){
+-      if( currentSize>newSize ){
+-        rc = sqlite3OsTruncate(pPager->fd, newSize);
+-      }else if( (currentSize+szPage)<=newSize ){
+-        char *pTmp = pPager->pTmpSpace;
+-        memset(pTmp, 0, szPage);
+-        testcase( (newSize-szPage) == currentSize );
+-        testcase( (newSize-szPage) >  currentSize );
+-        rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, newSize-szPage);
+-      }
+-      if( rc==SQLITE_OK ){
+-        pPager->dbFileSize = nPage;
+-      }
++#ifdef SQLITE_ENABLE_ATOMIC_WRITE
++static int jrnlBufferSize(Pager *pPager){
++  assert( !MEMDB );
++  if( !pPager->tempFile ){
++    int dc;                           /* Device characteristics */
++    int nSector;                      /* Sector size */
++    int szPage;                       /* Page size */
++
++    assert( isOpen(pPager->fd) );
++    dc = sqlite3OsDeviceCharacteristics(pPager->fd);
++    nSector = pPager->sectorSize;
++    szPage = pPager->pageSize;
++
++    assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
++    assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
++    if( 0==(dc&(SQLITE_IOCAP_ATOMIC|(szPage>>8)) || nSector>szPage) ){
++      return 0;
+     }
+   }
+-  return rc;
++
++  return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager);
+ }
++#endif
+ 
+ /*
+-** Return a sanitized version of the sector-size of OS file pFile. The
+-** return value is guaranteed to lie between 32 and MAX_SECTOR_SIZE.
++** If SQLITE_CHECK_PAGES is defined then we do some sanity checking
++** on the cache using a hash function.  This is used for testing
++** and debugging only.
+ */
+-SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *pFile){
+-  int iRet = sqlite3OsSectorSize(pFile);
+-  if( iRet<32 ){
+-    iRet = 512;
+-  }else if( iRet>MAX_SECTOR_SIZE ){
+-    assert( MAX_SECTOR_SIZE>=512 );
+-    iRet = MAX_SECTOR_SIZE;
++#ifdef SQLITE_CHECK_PAGES
++/*
++** Return a 32-bit hash of the page data for pPage.
++*/
++static u32 pager_datahash(int nByte, unsigned char *pData){
++  u32 hash = 0;
++  int i;
++  for(i=0; i<nByte; i++){
++    hash = (hash*1039) + pData[i];
+   }
+-  return iRet;
++  return hash;
++}
++static u32 pager_pagehash(PgHdr *pPage){
++  return pager_datahash(pPage->pPager->pageSize, (unsigned char *)pPage->pData);
++}
++static void pager_set_pagehash(PgHdr *pPage){
++  pPage->pageHash = pager_pagehash(pPage);
+ }
+ 
+ /*
+-** Set the value of the Pager.sectorSize variable for the given
+-** pager based on the value returned by the xSectorSize method
+-** of the open database file. The sector size will be used 
+-** to determine the size and alignment of journal header and 
+-** master journal pointers within created journal files.
+-**
+-** For temporary files the effective sector size is always 512 bytes.
+-**
+-** Otherwise, for non-temporary files, the effective sector size is
+-** the value returned by the xSectorSize() method rounded up to 32 if
+-** it is less than 32, or rounded down to MAX_SECTOR_SIZE if it
+-** is greater than MAX_SECTOR_SIZE.
+-**
+-** If the file has the SQLITE_IOCAP_POWERSAFE_OVERWRITE property, then set
+-** the effective sector size to its minimum value (512).  The purpose of
+-** pPager->sectorSize is to define the "blast radius" of bytes that
+-** might change if a crash occurs while writing to a single byte in
+-** that range.  But with POWERSAFE_OVERWRITE, the blast radius is zero
+-** (that is what POWERSAFE_OVERWRITE means), so we minimize the sector
+-** size.  For backwards compatibility of the rollback journal file format,
+-** we cannot reduce the effective sector size below 512.
++** The CHECK_PAGE macro takes a PgHdr* as an argument. If SQLITE_CHECK_PAGES
++** is defined, and NDEBUG is not defined, an assert() statement checks
++** that the page is either dirty or still matches the calculated page-hash.
+ */
+-static void setSectorSize(Pager *pPager){
+-  assert( isOpen(pPager->fd) || pPager->tempFile );
+-
+-  if( pPager->tempFile
+-   || (sqlite3OsDeviceCharacteristics(pPager->fd) & 
+-              SQLITE_IOCAP_POWERSAFE_OVERWRITE)!=0
+-  ){
+-    /* Sector size doesn't matter for temporary files. Also, the file
+-    ** may not have been opened yet, in which case the OsSectorSize()
+-    ** call will segfault. */
+-    pPager->sectorSize = 512;
+-  }else{
+-    pPager->sectorSize = sqlite3SectorSize(pPager->fd);
+-  }
++#define CHECK_PAGE(x) checkPage(x)
++static void checkPage(PgHdr *pPg){
++  Pager *pPager = pPg->pPager;
++  assert( pPager->eState!=PAGER_ERROR );
++  assert( (pPg->flags&PGHDR_DIRTY) || pPg->pageHash==pager_pagehash(pPg) );
+ }
+ 
++#else
++#define pager_datahash(X,Y)  0
++#define pager_pagehash(X)  0
++#define pager_set_pagehash(X)
++#define CHECK_PAGE(x)
++#endif  /* SQLITE_CHECK_PAGES */
++
+ /*
+-** Playback the journal and thus restore the database file to
+-** the state it was in before we started making changes.  
+-**
+-** The journal file format is as follows: 
+-**
+-**  (1)  8 byte prefix.  A copy of aJournalMagic[].
+-**  (2)  4 byte big-endian integer which is the number of valid page records
+-**       in the journal.  If this value is 0xffffffff, then compute the
+-**       number of page records from the journal size.
+-**  (3)  4 byte big-endian integer which is the initial value for the 
+-**       sanity checksum.
+-**  (4)  4 byte integer which is the number of pages to truncate the
+-**       database to during a rollback.
+-**  (5)  4 byte big-endian integer which is the sector size.  The header
+-**       is this many bytes in size.
+-**  (6)  4 byte big-endian integer which is the page size.
+-**  (7)  zero padding out to the next sector size.
+-**  (8)  Zero or more pages instances, each as follows:
+-**        +  4 byte page number.
+-**        +  pPager->pageSize bytes of data.
+-**        +  4 byte checksum
+-**
+-** When we speak of the journal header, we mean the first 7 items above.
+-** Each entry in the journal is an instance of the 8th item.
+-**
+-** Call the value from the second bullet "nRec".  nRec is the number of
+-** valid page entries in the journal.  In most cases, you can compute the
+-** value of nRec from the size of the journal file.  But if a power
+-** failure occurred while the journal was being written, it could be the
+-** case that the size of the journal file had already been increased but
+-** the extra entries had not yet made it safely to disk.  In such a case,
+-** the value of nRec computed from the file size would be too large.  For
+-** that reason, we always use the nRec value in the header.
++** When this is called the journal file for pager pPager must be open.
++** This function attempts to read a master journal file name from the 
++** end of the file and, if successful, copies it into memory supplied 
++** by the caller. See comments above writeMasterJournal() for the format
++** used to store a master journal file name at the end of a journal file.
+ **
+-** If the nRec value is 0xffffffff it means that nRec should be computed
+-** from the file size.  This value is used when the user selects the
+-** no-sync option for the journal.  A power failure could lead to corruption
+-** in this case.  But for things like temporary table (which will be
+-** deleted when the power is restored) we don't care.  
++** zMaster must point to a buffer of at least nMaster bytes allocated by
++** the caller. This should be sqlite3_vfs.mxPathname+1 (to ensure there is
++** enough space to write the master journal name). If the master journal
++** name in the journal is longer than nMaster bytes (including a
++** nul-terminator), then this is handled as if no master journal name
++** were present in the journal.
+ **
+-** If the file opened as the journal file is not a well-formed
+-** journal file then all pages up to the first corrupted page are rolled
+-** back (or no pages if the journal header is corrupted). The journal file
+-** is then deleted and SQLITE_OK returned, just as if no corruption had
+-** been encountered.
++** If a master journal file name is present at the end of the journal
++** file, then it is copied into the buffer pointed to by zMaster. A
++** nul-terminator byte is appended to the buffer following the master
++** journal file name.
+ **
+-** If an I/O or malloc() error occurs, the journal-file is not deleted
+-** and an error code is returned.
++** If it is determined that no master journal file name is present 
++** zMaster[0] is set to 0 and SQLITE_OK returned.
+ **
+-** The isHot parameter indicates that we are trying to rollback a journal
+-** that might be a hot journal.  Or, it could be that the journal is 
+-** preserved because of JOURNALMODE_PERSIST or JOURNALMODE_TRUNCATE.
+-** If the journal really is hot, reset the pager cache prior rolling
+-** back any content.  If the journal is merely persistent, no reset is
+-** needed.
++** If an error occurs while reading from the journal file, an SQLite
++** error code is returned.
+ */
+-static int pager_playback(Pager *pPager, int isHot){
+-  sqlite3_vfs *pVfs = pPager->pVfs;
+-  i64 szJ;                 /* Size of the journal file in bytes */
+-  u32 nRec;                /* Number of Records in the journal */
+-  u32 u;                   /* Unsigned loop counter */
+-  Pgno mxPg = 0;           /* Size of the original file in pages */
+-  int rc;                  /* Result code of a subroutine */
+-  int res = 1;             /* Value returned by sqlite3OsAccess() */
+-  char *zMaster = 0;       /* Name of master journal file if any */
+-  int needPagerReset;      /* True to reset page prior to first page rollback */
+-  int nPlayback = 0;       /* Total number of pages restored from journal */
+-
+-  /* Figure out how many records are in the journal.  Abort early if
+-  ** the journal is empty.
+-  */
+-  assert( isOpen(pPager->jfd) );
+-  rc = sqlite3OsFileSize(pPager->jfd, &szJ);
+-  if( rc!=SQLITE_OK ){
+-    goto end_playback;
+-  }
+-
+-  /* Read the master journal name from the journal, if it is present.
+-  ** If a master journal file name is specified, but the file is not
+-  ** present on disk, then the journal is not hot and does not need to be
+-  ** played back.
+-  **
+-  ** TODO: Technically the following is an error because it assumes that
+-  ** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that
+-  ** (pPager->pageSize >= pPager->pVfs->mxPathname+1). Using os_unix.c,
+-  **  mxPathname is 512, which is the same as the minimum allowable value
+-  ** for pageSize.
+-  */
+-  zMaster = pPager->pTmpSpace;
+-  rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
+-  if( rc==SQLITE_OK && zMaster[0] ){
+-    rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res);
+-  }
+-  zMaster = 0;
+-  if( rc!=SQLITE_OK || !res ){
+-    goto end_playback;
+-  }
+-  pPager->journalOff = 0;
+-  needPagerReset = isHot;
+-
+-  /* This loop terminates either when a readJournalHdr() or 
+-  ** pager_playback_one_page() call returns SQLITE_DONE or an IO error 
+-  ** occurs. 
+-  */
+-  while( 1 ){
+-    /* Read the next journal header from the journal file.  If there are
+-    ** not enough bytes left in the journal file for a complete header, or
+-    ** it is corrupted, then a process must have failed while writing it.
+-    ** This indicates nothing more needs to be rolled back.
+-    */
+-    rc = readJournalHdr(pPager, isHot, szJ, &nRec, &mxPg);
+-    if( rc!=SQLITE_OK ){ 
+-      if( rc==SQLITE_DONE ){
+-        rc = SQLITE_OK;
+-      }
+-      goto end_playback;
+-    }
+-
+-    /* If nRec is 0xffffffff, then this journal was created by a process
+-    ** working in no-sync mode. This means that the rest of the journal
+-    ** file consists of pages, there are no more journal headers. Compute
+-    ** the value of nRec based on this assumption.
+-    */
+-    if( nRec==0xffffffff ){
+-      assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) );
+-      nRec = (int)((szJ - JOURNAL_HDR_SZ(pPager))/JOURNAL_PG_SZ(pPager));
+-    }
+-
+-    /* If nRec is 0 and this rollback is of a transaction created by this
+-    ** process and if this is the final header in the journal, then it means
+-    ** that this part of the journal was being filled but has not yet been
+-    ** synced to disk.  Compute the number of pages based on the remaining
+-    ** size of the file.
+-    **
+-    ** The third term of the test was added to fix ticket #2565.
+-    ** When rolling back a hot journal, nRec==0 always means that the next
+-    ** chunk of the journal contains zero pages to be rolled back.  But
+-    ** when doing a ROLLBACK and the nRec==0 chunk is the last chunk in
+-    ** the journal, it means that the journal might contain additional
+-    ** pages that need to be rolled back and that the number of pages 
+-    ** should be computed based on the journal file size.
+-    */
+-    if( nRec==0 && !isHot &&
+-        pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){
+-      nRec = (int)((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager));
+-    }
+-
+-    /* If this is the first header read from the journal, truncate the
+-    ** database file back to its original size.
+-    */
+-    if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){
+-      rc = pager_truncate(pPager, mxPg);
+-      if( rc!=SQLITE_OK ){
+-        goto end_playback;
+-      }
+-      pPager->dbSize = mxPg;
+-    }
+-
+-    /* Copy original pages out of the journal and back into the 
+-    ** database file and/or page cache.
+-    */
+-    for(u=0; u<nRec; u++){
+-      if( needPagerReset ){
+-        pager_reset(pPager);
+-        needPagerReset = 0;
+-      }
+-      rc = pager_playback_one_page(pPager,&pPager->journalOff,0,1,0);
+-      if( rc==SQLITE_OK ){
+-        nPlayback++;
+-      }else{
+-        if( rc==SQLITE_DONE ){
+-          pPager->journalOff = szJ;
+-          break;
+-        }else if( rc==SQLITE_IOERR_SHORT_READ ){
+-          /* If the journal has been truncated, simply stop reading and
+-          ** processing the journal. This might happen if the journal was
+-          ** not completely written and synced prior to a crash.  In that
+-          ** case, the database should have never been written in the
+-          ** first place so it is OK to simply abandon the rollback. */
+-          rc = SQLITE_OK;
+-          goto end_playback;
+-        }else{
+-          /* If we are unable to rollback, quit and return the error
+-          ** code.  This will cause the pager to enter the error state
+-          ** so that no further harm will be done.  Perhaps the next
+-          ** process to come along will be able to rollback the database.
+-          */
+-          goto end_playback;
+-        }
+-      }
+-    }
+-  }
+-  /*NOTREACHED*/
+-  assert( 0 );
+-
+-end_playback:
+-  /* Following a rollback, the database file should be back in its original
+-  ** state prior to the start of the transaction, so invoke the
+-  ** SQLITE_FCNTL_DB_UNCHANGED file-control method to disable the
+-  ** assertion that the transaction counter was modified.
+-  */
+-#ifdef SQLITE_DEBUG
+-  if( pPager->fd->pMethods ){
+-    sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0);
+-  }
+-#endif
+-
+-  /* If this playback is happening automatically as a result of an IO or 
+-  ** malloc error that occurred after the change-counter was updated but 
+-  ** before the transaction was committed, then the change-counter 
+-  ** modification may just have been reverted. If this happens in exclusive 
+-  ** mode, then subsequent transactions performed by the connection will not
+-  ** update the change-counter at all. This may lead to cache inconsistency
+-  ** problems for other processes at some point in the future. So, just
+-  ** in case this has happened, clear the changeCountDone flag now.
+-  */
+-  pPager->changeCountDone = pPager->tempFile;
++static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){
++  int rc;                    /* Return code */
++  u32 len;                   /* Length in bytes of master journal name */
++  i64 szJ;                   /* Total size in bytes of journal file pJrnl */
++  u32 cksum;                 /* MJ checksum value read from journal */
++  u32 u;                     /* Unsigned loop counter */
++  unsigned char aMagic[8];   /* A buffer to hold the magic header */
++  zMaster[0] = '\0';
+ 
+-  if( rc==SQLITE_OK ){
+-    zMaster = pPager->pTmpSpace;
+-    rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
+-    testcase( rc!=SQLITE_OK );
+-  }
+-  if( rc==SQLITE_OK
+-   && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
++  if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ))
++   || szJ<16
++   || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len))
++   || len>=nMaster 
++   || len==0 
++   || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum))
++   || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8))
++   || memcmp(aMagic, aJournalMagic, 8)
++   || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, zMaster, len, szJ-16-len))
+   ){
+-    rc = sqlite3PagerSync(pPager, 0);
++    return rc;
+   }
+-  if( rc==SQLITE_OK ){
+-    rc = pager_end_transaction(pPager, zMaster[0]!='\0', 0);
+-    testcase( rc!=SQLITE_OK );
++
++  /* See if the checksum matches the master journal name */
++  for(u=0; u<len; u++){
++    cksum -= zMaster[u];
+   }
+-  if( rc==SQLITE_OK && zMaster[0] && res ){
+-    /* If there was a master journal and this routine will return success,
+-    ** see if it is possible to delete the master journal.
++  if( cksum ){
++    /* If the checksum doesn't add up, then one or more of the disk sectors
++    ** containing the master journal filename is corrupted. This means
++    ** definitely roll back, so just return SQLITE_OK and report a (nul)
++    ** master-journal filename.
+     */
+-    rc = pager_delmaster(pPager, zMaster);
+-    testcase( rc!=SQLITE_OK );
+-  }
+-  if( isHot && nPlayback ){
+-    sqlite3_log(SQLITE_NOTICE_RECOVER_ROLLBACK, "recovered %d pages from %s",
+-                nPlayback, pPager->zJournal);
++    len = 0;
+   }
+-
+-  /* The Pager.sectorSize variable may have been updated while rolling
+-  ** back a journal created by a process with a different sector size
+-  ** value. Reset it to the correct value for this process.
+-  */
+-  setSectorSize(pPager);
+-  return rc;
++  zMaster[len] = '\0';
++   
++  return SQLITE_OK;
+ }
+ 
+-
+ /*
+-** Read the content for page pPg out of the database file and into 
+-** pPg->pData. A shared lock or greater must be held on the database
+-** file before this function is called.
++** Return the offset of the sector boundary at or immediately 
++** following the value in pPager->journalOff, assuming a sector 
++** size of pPager->sectorSize bytes.
+ **
+-** If page 1 is read, then the value of Pager.dbFileVers[] is set to
+-** the value read from the database file.
++** i.e for a sector size of 512:
+ **
+-** If an IO error occurs, then the IO error is returned to the caller.
+-** Otherwise, SQLITE_OK is returned.
++**   Pager.journalOff          Return value
++**   ---------------------------------------
++**   0                         0
++**   512                       512
++**   100                       512
++**   2000                      2048
++** 
+ */
+-static int readDbPage(PgHdr *pPg, u32 iFrame){
+-  Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */
+-  Pgno pgno = pPg->pgno;       /* Page number to read */
+-  int rc = SQLITE_OK;          /* Return code */
+-  int pgsz = pPager->pageSize; /* Number of bytes to read */
+-
+-  assert( pPager->eState>=PAGER_READER && !MEMDB );
+-  assert( isOpen(pPager->fd) );
+-
+-#ifndef SQLITE_OMIT_WAL
+-  if( iFrame ){
+-    /* Try to pull the page from the write-ahead log. */
+-    rc = sqlite3WalReadFrame(pPager->pWal, iFrame, pgsz, pPg->pData);
+-  }else
+-#endif
+-  {
+-    i64 iOffset = (pgno-1)*(i64)pPager->pageSize;
+-    rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset);
+-    if( rc==SQLITE_IOERR_SHORT_READ ){
+-      rc = SQLITE_OK;
+-    }
+-  }
+-
+-  if( pgno==1 ){
+-    if( rc ){
+-      /* If the read is unsuccessful, set the dbFileVers[] to something
+-      ** that will never be a valid file version.  dbFileVers[] is a copy
+-      ** of bytes 24..39 of the database.  Bytes 28..31 should always be
+-      ** zero or the size of the database in page. Bytes 32..35 and 35..39
+-      ** should be page numbers which are never 0xffffffff.  So filling
+-      ** pPager->dbFileVers[] with all 0xff bytes should suffice.
+-      **
+-      ** For an encrypted database, the situation is more complex:  bytes
+-      ** 24..39 of the database are white noise.  But the probability of
+-      ** white noise equaling 16 bytes of 0xff is vanishingly small so
+-      ** we should still be ok.
+-      */
+-      memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers));
+-    }else{
+-      u8 *dbFileVers = &((u8*)pPg->pData)[24];
+-      memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers));
+-    }
++static i64 journalHdrOffset(Pager *pPager){
++  i64 offset = 0;
++  i64 c = pPager->journalOff;
++  if( c ){
++    offset = ((c-1)/JOURNAL_HDR_SZ(pPager) + 1) * JOURNAL_HDR_SZ(pPager);
+   }
+-  CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM);
+-
+-  PAGER_INCR(sqlite3_pager_readdb_count);
+-  PAGER_INCR(pPager->nRead);
+-  IOTRACE(("PGIN %p %d\n", pPager, pgno));
+-  PAGERTRACE(("FETCH %d page %d hash(%08x)\n",
+-               PAGERID(pPager), pgno, pager_pagehash(pPg)));
+-
+-  return rc;
++  assert( offset%JOURNAL_HDR_SZ(pPager)==0 );
++  assert( offset>=c );
++  assert( (offset-c)<JOURNAL_HDR_SZ(pPager) );
++  return offset;
+ }
+ 
+ /*
+-** Update the value of the change-counter at offsets 24 and 92 in
+-** the header and the sqlite version number at offset 96.
++** The journal file must be open when this function is called.
+ **
+-** This is an unconditional update.  See also the pager_incr_changecounter()
+-** routine which only updates the change-counter if the update is actually
+-** needed, as determined by the pPager->changeCountDone state variable.
++** This function is a no-op if the journal file has not been written to
++** within the current transaction (i.e. if Pager.journalOff==0).
++**
++** If doTruncate is non-zero or the Pager.journalSizeLimit variable is
++** set to 0, then truncate the journal file to zero bytes in size. Otherwise,
++** zero the 28-byte header at the start of the journal file. In either case, 
++** if the pager is not in no-sync mode, sync the journal file immediately 
++** after writing or truncating it.
++**
++** If Pager.journalSizeLimit is set to a positive, non-zero value, and
++** following the truncation or zeroing described above the size of the 
++** journal file in bytes is larger than this value, then truncate the
++** journal file to Pager.journalSizeLimit bytes. The journal file does
++** not need to be synced following this operation.
++**
++** If an IO error occurs, abandon processing and return the IO error code.
++** Otherwise, return SQLITE_OK.
+ */
+-static void pager_write_changecounter(PgHdr *pPg){
+-  u32 change_counter;
++static int zeroJournalHdr(Pager *pPager, int doTruncate){
++  int rc = SQLITE_OK;                               /* Return code */
++  assert( isOpen(pPager->jfd) );
++  if( pPager->journalOff ){
++    const i64 iLimit = pPager->journalSizeLimit;    /* Local cache of jsl */
+ 
+-  /* Increment the value just read and write it back to byte 24. */
+-  change_counter = sqlite3Get4byte((u8*)pPg->pPager->dbFileVers)+1;
+-  put32bits(((char*)pPg->pData)+24, change_counter);
++    IOTRACE(("JZEROHDR %p\n", pPager))
++    if( doTruncate || iLimit==0 ){
++      rc = sqlite3OsTruncate(pPager->jfd, 0);
++    }else{
++      static const char zeroHdr[28] = {0};
++      rc = sqlite3OsWrite(pPager->jfd, zeroHdr, sizeof(zeroHdr), 0);
++    }
++    if( rc==SQLITE_OK && !pPager->noSync ){
++      rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_DATAONLY|pPager->syncFlags);
++    }
+ 
+-  /* Also store the SQLite version number in bytes 96..99 and in
+-  ** bytes 92..95 store the change counter for which the version number
+-  ** is valid. */
+-  put32bits(((char*)pPg->pData)+92, change_counter);
+-  put32bits(((char*)pPg->pData)+96, SQLITE_VERSION_NUMBER);
++    /* At this point the transaction is committed but the write lock 
++    ** is still held on the file. If there is a size limit configured for 
++    ** the persistent journal and the journal file currently consumes more
++    ** space than that limit allows for, truncate it now. There is no need
++    ** to sync the file following this operation.
++    */
++    if( rc==SQLITE_OK && iLimit>0 ){
++      i64 sz;
++      rc = sqlite3OsFileSize(pPager->jfd, &sz);
++      if( rc==SQLITE_OK && sz>iLimit ){
++        rc = sqlite3OsTruncate(pPager->jfd, iLimit);
++      }
++    }
++  }
++  return rc;
+ }
+ 
+-#ifndef SQLITE_OMIT_WAL
+ /*
+-** This function is invoked once for each page that has already been 
+-** written into the log file when a WAL transaction is rolled back.
+-** Parameter iPg is the page number of said page. The pCtx argument 
+-** is actually a pointer to the Pager structure.
++** The journal file must be open when this routine is called. A journal
++** header (JOURNAL_HDR_SZ bytes) is written into the journal file at the
++** current location.
+ **
+-** If page iPg is present in the cache, and has no outstanding references,
+-** it is discarded. Otherwise, if there are one or more outstanding
+-** references, the page content is reloaded from the database. If the
+-** attempt to reload content from the database is required and fails, 
+-** return an SQLite error code. Otherwise, SQLITE_OK.
++** The format for the journal header is as follows:
++** - 8 bytes: Magic identifying journal format.
++** - 4 bytes: Number of records in journal, or -1 no-sync mode is on.
++** - 4 bytes: Random number used for page hash.
++** - 4 bytes: Initial database page count.
++** - 4 bytes: Sector size used by the process that wrote this journal.
++** - 4 bytes: Database page size.
++** 
++** Followed by (JOURNAL_HDR_SZ - 28) bytes of unused space.
+ */
+-static int pagerUndoCallback(void *pCtx, Pgno iPg){
+-  int rc = SQLITE_OK;
+-  Pager *pPager = (Pager *)pCtx;
+-  PgHdr *pPg;
++static int writeJournalHdr(Pager *pPager){
++  int rc = SQLITE_OK;                 /* Return code */
++  char *zHeader = pPager->pTmpSpace;  /* Temporary space used to build header */
++  u32 nHeader = (u32)pPager->pageSize;/* Size of buffer pointed to by zHeader */
++  u32 nWrite;                         /* Bytes of header sector written */
++  int ii;                             /* Loop counter */
+ 
+-  assert( pagerUseWal(pPager) );
+-  pPg = sqlite3PagerLookup(pPager, iPg);
+-  if( pPg ){
+-    if( sqlite3PcachePageRefcount(pPg)==1 ){
+-      sqlite3PcacheDrop(pPg);
+-    }else{
+-      u32 iFrame = 0;
+-      rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame);
+-      if( rc==SQLITE_OK ){
+-        rc = readDbPage(pPg, iFrame);
+-      }
+-      if( rc==SQLITE_OK ){
+-        pPager->xReiniter(pPg);
+-      }
+-      sqlite3PagerUnrefNotNull(pPg);
++  assert( isOpen(pPager->jfd) );      /* Journal file must be open. */
++
++  if( nHeader>JOURNAL_HDR_SZ(pPager) ){
++    nHeader = JOURNAL_HDR_SZ(pPager);
++  }
++
++  /* If there are active savepoints and any of them were created 
++  ** since the most recent journal header was written, update the 
++  ** PagerSavepoint.iHdrOffset fields now.
++  */
++  for(ii=0; ii<pPager->nSavepoint; ii++){
++    if( pPager->aSavepoint[ii].iHdrOffset==0 ){
++      pPager->aSavepoint[ii].iHdrOffset = pPager->journalOff;
+     }
+   }
+ 
+-  /* Normally, if a transaction is rolled back, any backup processes are
+-  ** updated as data is copied out of the rollback journal and into the
+-  ** database. This is not generally possible with a WAL database, as
+-  ** rollback involves simply truncating the log file. Therefore, if one
+-  ** or more frames have already been written to the log (and therefore 
+-  ** also copied into the backup databases) as part of this transaction,
+-  ** the backups must be restarted.
++  pPager->journalHdr = pPager->journalOff = journalHdrOffset(pPager);
++
++  /* 
++  ** Write the nRec Field - the number of page records that follow this
++  ** journal header. Normally, zero is written to this value at this time.
++  ** After the records are added to the journal (and the journal synced, 
++  ** if in full-sync mode), the zero is overwritten with the true number
++  ** of records (see syncJournal()).
++  **
++  ** A faster alternative is to write 0xFFFFFFFF to the nRec field. When
++  ** reading the journal this value tells SQLite to assume that the
++  ** rest of the journal file contains valid page records. This assumption
++  ** is dangerous, as if a failure occurred whilst writing to the journal
++  ** file it may contain some garbage data. There are two scenarios
++  ** where this risk can be ignored:
++  **
++  **   * When the pager is in no-sync mode. Corruption can follow a
++  **     power failure in this case anyway.
++  **
++  **   * When the SQLITE_IOCAP_SAFE_APPEND flag is set. This guarantees
++  **     that garbage data is never appended to the journal file.
+   */
+-  sqlite3BackupRestart(pPager->pBackup);
++  assert( isOpen(pPager->fd) || pPager->noSync );
++  if( pPager->noSync || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY)
++   || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) 
++  ){
++    memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic));
++    put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff);
++  }else{
++    memset(zHeader, 0, sizeof(aJournalMagic)+4);
++  }
+ 
+-  return rc;
+-}
++  /* The random check-hash initializer */ 
++  sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit);
++  put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit);
++  /* The initial database size */
++  put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbOrigSize);
++  /* The assumed sector size for this process */
++  put32bits(&zHeader[sizeof(aJournalMagic)+12], pPager->sectorSize);
+ 
+-/*
+-** This function is called to rollback a transaction on a WAL database.
+-*/
+-static int pagerRollbackWal(Pager *pPager){
+-  int rc;                         /* Return Code */
+-  PgHdr *pList;                   /* List of dirty pages to revert */
++  /* The page size */
++  put32bits(&zHeader[sizeof(aJournalMagic)+16], pPager->pageSize);
+ 
+-  /* For all pages in the cache that are currently dirty or have already
+-  ** been written (but not committed) to the log file, do one of the 
+-  ** following:
+-  **
+-  **   + Discard the cached page (if refcount==0), or
+-  **   + Reload page content from the database (if refcount>0).
++  /* Initializing the tail of the buffer is not necessary.  Everything
++  ** works find if the following memset() is omitted.  But initializing
++  ** the memory prevents valgrind from complaining, so we are willing to
++  ** take the performance hit.
+   */
+-  pPager->dbSize = pPager->dbOrigSize;
+-  rc = sqlite3WalUndo(pPager->pWal, pagerUndoCallback, (void *)pPager);
+-  pList = sqlite3PcacheDirtyList(pPager->pPCache);
+-  while( pList && rc==SQLITE_OK ){
+-    PgHdr *pNext = pList->pDirty;
+-    rc = pagerUndoCallback((void *)pPager, pList->pgno);
+-    pList = pNext;
++  memset(&zHeader[sizeof(aJournalMagic)+20], 0,
++         nHeader-(sizeof(aJournalMagic)+20));
++
++  /* In theory, it is only necessary to write the 28 bytes that the 
++  ** journal header consumes to the journal file here. Then increment the 
++  ** Pager.journalOff variable by JOURNAL_HDR_SZ so that the next 
++  ** record is written to the following sector (leaving a gap in the file
++  ** that will be implicitly filled in by the OS).
++  **
++  ** However it has been discovered that on some systems this pattern can 
++  ** be significantly slower than contiguously writing data to the file,
++  ** even if that means explicitly writing data to the block of 
++  ** (JOURNAL_HDR_SZ - 28) bytes that will not be used. So that is what
++  ** is done. 
++  **
++  ** The loop is required here in case the sector-size is larger than the 
++  ** database page size. Since the zHeader buffer is only Pager.pageSize
++  ** bytes in size, more than one call to sqlite3OsWrite() may be required
++  ** to populate the entire journal header sector.
++  */ 
++  for(nWrite=0; rc==SQLITE_OK&&nWrite<JOURNAL_HDR_SZ(pPager); nWrite+=nHeader){
++    IOTRACE(("JHDR %p %lld %d\n", pPager, pPager->journalHdr, nHeader))
++    rc = sqlite3OsWrite(pPager->jfd, zHeader, nHeader, pPager->journalOff);
++    assert( pPager->journalHdr <= pPager->journalOff );
++    pPager->journalOff += nHeader;
+   }
+ 
+   return rc;
+ }
+ 
+ /*
+-** This function is a wrapper around sqlite3WalFrames(). As well as logging
+-** the contents of the list of pages headed by pList (connected by pDirty),
+-** this function notifies any active backup processes that the pages have
+-** changed. 
++** The journal file must be open when this is called. A journal header file
++** (JOURNAL_HDR_SZ bytes) is read from the current location in the journal
++** file. The current location in the journal file is given by
++** pPager->journalOff. See comments above function writeJournalHdr() for
++** a description of the journal header format.
+ **
+-** The list of pages passed into this routine is always sorted by page number.
+-** Hence, if page 1 appears anywhere on the list, it will be the first page.
+-*/ 
+-static int pagerWalFrames(
+-  Pager *pPager,                  /* Pager object */
+-  PgHdr *pList,                   /* List of frames to log */
+-  Pgno nTruncate,                 /* Database size after this commit */
+-  int isCommit                    /* True if this is a commit */
++** If the header is read successfully, *pNRec is set to the number of
++** page records following this header and *pDbSize is set to the size of the
++** database before the transaction began, in pages. Also, pPager->cksumInit
++** is set to the value read from the journal header. SQLITE_OK is returned
++** in this case.
++**
++** If the journal header file appears to be corrupted, SQLITE_DONE is
++** returned and *pNRec and *PDbSize are undefined.  If JOURNAL_HDR_SZ bytes
++** cannot be read from the journal file an error code is returned.
++*/
++static int readJournalHdr(
++  Pager *pPager,               /* Pager object */
++  int isHot,
++  i64 journalSize,             /* Size of the open journal file in bytes */
++  u32 *pNRec,                  /* OUT: Value read from the nRec field */
++  u32 *pDbSize                 /* OUT: Value of original database size field */
+ ){
+-  int rc;                         /* Return code */
+-  int nList;                      /* Number of pages in pList */
+-  PgHdr *p;                       /* For looping over pages */
++  int rc;                      /* Return code */
++  unsigned char aMagic[8];     /* A buffer to hold the magic header */
++  i64 iHdrOff;                 /* Offset of journal header being read */
+ 
+-  assert( pPager->pWal );
+-  assert( pList );
+-#ifdef SQLITE_DEBUG
+-  /* Verify that the page list is in accending order */
+-  for(p=pList; p && p->pDirty; p=p->pDirty){
+-    assert( p->pgno < p->pDirty->pgno );
+-  }
+-#endif
++  assert( isOpen(pPager->jfd) );      /* Journal file must be open. */
+ 
+-  assert( pList->pDirty==0 || isCommit );
+-  if( isCommit ){
+-    /* If a WAL transaction is being committed, there is no point in writing
+-    ** any pages with page numbers greater than nTruncate into the WAL file.
+-    ** They will never be read by any client. So remove them from the pDirty
+-    ** list here. */
+-    PgHdr **ppNext = &pList;
+-    nList = 0;
+-    for(p=pList; (*ppNext = p)!=0; p=p->pDirty){
+-      if( p->pgno<=nTruncate ){
+-        ppNext = &p->pDirty;
+-        nList++;
+-      }
+-    }
+-    assert( pList );
+-  }else{
+-    nList = 1;
++  /* Advance Pager.journalOff to the start of the next sector. If the
++  ** journal file is too small for there to be a header stored at this
++  ** point, return SQLITE_DONE.
++  */
++  pPager->journalOff = journalHdrOffset(pPager);
++  if( pPager->journalOff+JOURNAL_HDR_SZ(pPager) > journalSize ){
++    return SQLITE_DONE;
+   }
+-  pPager->aStat[PAGER_STAT_WRITE] += nList;
++  iHdrOff = pPager->journalOff;
+ 
+-  if( pList->pgno==1 ) pager_write_changecounter(pList);
+-  rc = sqlite3WalFrames(pPager->pWal, 
+-      pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags
+-  );
+-  if( rc==SQLITE_OK && pPager->pBackup ){
+-    for(p=pList; p; p=p->pDirty){
+-      sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData);
++  /* Read in the first 8 bytes of the journal header. If they do not match
++  ** the  magic string found at the start of each journal header, return
++  ** SQLITE_DONE. If an IO error occurs, return an error code. Otherwise,
++  ** proceed.
++  */
++  if( isHot || iHdrOff!=pPager->journalHdr ){
++    rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic), iHdrOff);
++    if( rc ){
++      return rc;
++    }
++    if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){
++      return SQLITE_DONE;
+     }
+   }
+ 
+-#ifdef SQLITE_CHECK_PAGES
+-  pList = sqlite3PcacheDirtyList(pPager->pPCache);
+-  for(p=pList; p; p=p->pDirty){
+-    pager_set_pagehash(p);
++  /* Read the first three 32-bit fields of the journal header: The nRec
++  ** field, the checksum-initializer and the database size at the start
++  ** of the transaction. Return an error code if anything goes wrong.
++  */
++  if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+8, pNRec))
++   || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+12, &pPager->cksumInit))
++   || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+16, pDbSize))
++  ){
++    return rc;
+   }
+-#endif
+ 
+-  return rc;
+-}
++  if( pPager->journalOff==0 ){
++    u32 iPageSize;               /* Page-size field of journal header */
++    u32 iSectorSize;             /* Sector-size field of journal header */
+ 
+-/*
+-** Begin a read transaction on the WAL.
+-**
+-** This routine used to be called "pagerOpenSnapshot()" because it essentially
+-** makes a snapshot of the database at the current point in time and preserves
+-** that snapshot for use by the reader in spite of concurrently changes by
+-** other writers or checkpointers.
+-*/
+-static int pagerBeginReadTransaction(Pager *pPager){
+-  int rc;                         /* Return code */
+-  int changed = 0;                /* True if cache must be reset */
++    /* Read the page-size and sector-size journal header fields. */
++    if( SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+20, &iSectorSize))
++     || SQLITE_OK!=(rc = read32bits(pPager->jfd, iHdrOff+24, &iPageSize))
++    ){
++      return rc;
++    }
+ 
+-  assert( pagerUseWal(pPager) );
+-  assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER );
++    /* Versions of SQLite prior to 3.5.8 set the page-size field of the
++    ** journal header to zero. In this case, assume that the Pager.pageSize
++    ** variable is already set to the correct page size.
++    */
++    if( iPageSize==0 ){
++      iPageSize = pPager->pageSize;
++    }
+ 
+-  /* sqlite3WalEndReadTransaction() was not called for the previous
+-  ** transaction in locking_mode=EXCLUSIVE.  So call it now.  If we
+-  ** are in locking_mode=NORMAL and EndRead() was previously called,
+-  ** the duplicate call is harmless.
+-  */
+-  sqlite3WalEndReadTransaction(pPager->pWal);
++    /* Check that the values read from the page-size and sector-size fields
++    ** are within range. To be 'in range', both values need to be a power
++    ** of two greater than or equal to 512 or 32, and not greater than their 
++    ** respective compile time maximum limits.
++    */
++    if( iPageSize<512                  || iSectorSize<32
++     || iPageSize>SQLITE_MAX_PAGE_SIZE || iSectorSize>MAX_SECTOR_SIZE
++     || ((iPageSize-1)&iPageSize)!=0   || ((iSectorSize-1)&iSectorSize)!=0 
++    ){
++      /* If the either the page-size or sector-size in the journal-header is 
++      ** invalid, then the process that wrote the journal-header must have 
++      ** crashed before the header was synced. In this case stop reading 
++      ** the journal file here.
++      */
++      return SQLITE_DONE;
++    }
+ 
+-  rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed);
+-  if( rc!=SQLITE_OK || changed ){
+-    pager_reset(pPager);
+-    if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
++    /* Update the page-size to match the value read from the journal. 
++    ** Use a testcase() macro to make sure that malloc failure within 
++    ** PagerSetPagesize() is tested.
++    */
++    rc = sqlite3PagerSetPagesize(pPager, &iPageSize, -1);
++    testcase( rc!=SQLITE_OK );
++
++    /* Update the assumed sector-size to match the value used by 
++    ** the process that created this journal. If this journal was
++    ** created by a process other than this one, then this routine
++    ** is being called from within pager_playback(). The local value
++    ** of Pager.sectorSize is restored at the end of that routine.
++    */
++    pPager->sectorSize = iSectorSize;
+   }
+ 
++  pPager->journalOff += JOURNAL_HDR_SZ(pPager);
+   return rc;
+ }
+-#endif
++
+ 
+ /*
+-** This function is called as part of the transition from PAGER_OPEN
+-** to PAGER_READER state to determine the size of the database file
+-** in pages (assuming the page size currently stored in Pager.pageSize).
++** Write the supplied master journal name into the journal file for pager
++** pPager at the current location. The master journal name must be the last
++** thing written to a journal file. If the pager is in full-sync mode, the
++** journal file descriptor is advanced to the next sector boundary before
++** anything is written. The format is:
+ **
+-** If no error occurs, SQLITE_OK is returned and the size of the database
+-** in pages is stored in *pnPage. Otherwise, an error code (perhaps
+-** SQLITE_IOERR_FSTAT) is returned and *pnPage is left unmodified.
++**   + 4 bytes: PAGER_MJ_PGNO.
++**   + N bytes: Master journal filename in utf-8.
++**   + 4 bytes: N (length of master journal name in bytes, no nul-terminator).
++**   + 4 bytes: Master journal name checksum.
++**   + 8 bytes: aJournalMagic[].
++**
++** The master journal page checksum is the sum of the bytes in the master
++** journal name, where each byte is interpreted as a signed 8-bit integer.
++**
++** If zMaster is a NULL pointer (occurs for a single database transaction), 
++** this call is a no-op.
+ */
+-static int pagerPagecount(Pager *pPager, Pgno *pnPage){
+-  Pgno nPage;                     /* Value to return via *pnPage */
++static int writeMasterJournal(Pager *pPager, const char *zMaster){
++  int rc;                          /* Return code */
++  int nMaster;                     /* Length of string zMaster */
++  i64 iHdrOff;                     /* Offset of header in journal file */
++  i64 jrnlSize;                    /* Size of journal file on disk */
++  u32 cksum = 0;                   /* Checksum of string zMaster */
+ 
+-  /* Query the WAL sub-system for the database size. The WalDbsize()
+-  ** function returns zero if the WAL is not open (i.e. Pager.pWal==0), or
+-  ** if the database size is not available. The database size is not
+-  ** available from the WAL sub-system if the log file is empty or
+-  ** contains no valid committed transactions.
+-  */
+-  assert( pPager->eState==PAGER_OPEN );
+-  assert( pPager->eLock>=SHARED_LOCK );
+-  nPage = sqlite3WalDbsize(pPager->pWal);
++  assert( pPager->setMaster==0 );
++  assert( !pagerUseWal(pPager) );
+ 
+-  /* If the database size was not available from the WAL sub-system,
+-  ** determine it based on the size of the database file. If the size
+-  ** of the database file is not an integer multiple of the page-size,
+-  ** round down to the nearest page. Except, any file larger than 0
+-  ** bytes in size is considered to contain at least one page.
++  if( !zMaster 
++   || pPager->journalMode==PAGER_JOURNALMODE_MEMORY 
++   || !isOpen(pPager->jfd)
++  ){
++    return SQLITE_OK;
++  }
++  pPager->setMaster = 1;
++  assert( pPager->journalHdr <= pPager->journalOff );
++
++  /* Calculate the length in bytes and the checksum of zMaster */
++  for(nMaster=0; zMaster[nMaster]; nMaster++){
++    cksum += zMaster[nMaster];
++  }
++
++  /* If in full-sync mode, advance to the next disk sector before writing
++  ** the master journal name. This is in case the previous page written to
++  ** the journal has already been synced.
+   */
+-  if( nPage==0 ){
+-    i64 n = 0;                    /* Size of db file in bytes */
+-    assert( isOpen(pPager->fd) || pPager->tempFile );
+-    if( isOpen(pPager->fd) ){
+-      int rc = sqlite3OsFileSize(pPager->fd, &n);
+-      if( rc!=SQLITE_OK ){
+-        return rc;
+-      }
+-    }
+-    nPage = (Pgno)((n+pPager->pageSize-1) / pPager->pageSize);
++  if( pPager->fullSync ){
++    pPager->journalOff = journalHdrOffset(pPager);
+   }
++  iHdrOff = pPager->journalOff;
+ 
+-  /* If the current number of pages in the file is greater than the
+-  ** configured maximum pager number, increase the allowed limit so
+-  ** that the file can be read.
++  /* Write the master journal data to the end of the journal file. If
++  ** an error occurs, return the error code to the caller.
+   */
+-  if( nPage>pPager->mxPgno ){
+-    pPager->mxPgno = (Pgno)nPage;
++  if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_MJ_PGNO(pPager))))
++   || (0 != (rc = sqlite3OsWrite(pPager->jfd, zMaster, nMaster, iHdrOff+4)))
++   || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster, nMaster)))
++   || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster+4, cksum)))
++   || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, iHdrOff+4+nMaster+8)))
++  ){
++    return rc;
+   }
++  pPager->journalOff += (nMaster+20);
+ 
+-  *pnPage = nPage;
+-  return SQLITE_OK;
++  /* If the pager is in peristent-journal mode, then the physical 
++  ** journal-file may extend past the end of the master-journal name
++  ** and 8 bytes of magic data just written to the file. This is 
++  ** dangerous because the code to rollback a hot-journal file
++  ** will not be able to find the master-journal name to determine 
++  ** whether or not the journal is hot. 
++  **
++  ** Easiest thing to do in this scenario is to truncate the journal 
++  ** file to the required size.
++  */ 
++  if( SQLITE_OK==(rc = sqlite3OsFileSize(pPager->jfd, &jrnlSize))
++   && jrnlSize>pPager->journalOff
++  ){
++    rc = sqlite3OsTruncate(pPager->jfd, pPager->journalOff);
++  }
++  return rc;
+ }
+ 
+-#ifndef SQLITE_OMIT_WAL
+ /*
+-** Check if the *-wal file that corresponds to the database opened by pPager
+-** exists if the database is not empy, or verify that the *-wal file does
+-** not exist (by deleting it) if the database file is empty.
+-**
+-** If the database is not empty and the *-wal file exists, open the pager
+-** in WAL mode.  If the database is empty or if no *-wal file exists and
+-** if no error occurs, make sure Pager.journalMode is not set to
+-** PAGER_JOURNALMODE_WAL.
+-**
+-** Return SQLITE_OK or an error code.
+-**
+-** The caller must hold a SHARED lock on the database file to call this
+-** function. Because an EXCLUSIVE lock on the db file is required to delete 
+-** a WAL on a none-empty database, this ensures there is no race condition 
+-** between the xAccess() below and an xDelete() being executed by some 
+-** other connection.
++** Discard the entire contents of the in-memory page-cache.
+ */
+-static int pagerOpenWalIfPresent(Pager *pPager){
+-  int rc = SQLITE_OK;
+-  assert( pPager->eState==PAGER_OPEN );
+-  assert( pPager->eLock>=SHARED_LOCK );
++static void pager_reset(Pager *pPager){
++  pPager->iDataVersion++;
++  sqlite3BackupRestart(pPager->pBackup);
++  sqlite3PcacheClear(pPager->pPCache);
++}
+ 
+-  if( !pPager->tempFile ){
+-    int isWal;                    /* True if WAL file exists */
+-    Pgno nPage;                   /* Size of the database file */
++/*
++** Return the pPager->iDataVersion value
++*/
++SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager *pPager){
++  assert( pPager->eState>PAGER_OPEN );
++  return pPager->iDataVersion;
++}
++
++/*
++** Free all structures in the Pager.aSavepoint[] array and set both
++** Pager.aSavepoint and Pager.nSavepoint to zero. Close the sub-journal
++** if it is open and the pager is not in exclusive mode.
++*/
++static void releaseAllSavepoints(Pager *pPager){
++  int ii;               /* Iterator for looping through Pager.aSavepoint */
++  for(ii=0; ii<pPager->nSavepoint; ii++){
++    sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
++  }
++  if( !pPager->exclusiveMode || sqlite3IsMemJournal(pPager->sjfd) ){
++    sqlite3OsClose(pPager->sjfd);
++  }
++  sqlite3_free(pPager->aSavepoint);
++  pPager->aSavepoint = 0;
++  pPager->nSavepoint = 0;
++  pPager->nSubRec = 0;
++}
++
++/*
++** Set the bit number pgno in the PagerSavepoint.pInSavepoint 
++** bitvecs of all open savepoints. Return SQLITE_OK if successful
++** or SQLITE_NOMEM if a malloc failure occurs.
++*/
++static int addToSavepointBitvecs(Pager *pPager, Pgno pgno){
++  int ii;                   /* Loop counter */
++  int rc = SQLITE_OK;       /* Result code */
+ 
+-    rc = pagerPagecount(pPager, &nPage);
+-    if( rc ) return rc;
+-    if( nPage==0 ){
+-      rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0);
+-      if( rc==SQLITE_IOERR_DELETE_NOENT ) rc = SQLITE_OK;
+-      isWal = 0;
+-    }else{
+-      rc = sqlite3OsAccess(
+-          pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal
+-      );
+-    }
+-    if( rc==SQLITE_OK ){
+-      if( isWal ){
+-        testcase( sqlite3PcachePagecount(pPager->pPCache)==0 );
+-        rc = sqlite3PagerOpenWal(pPager, 0);
+-      }else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){
+-        pPager->journalMode = PAGER_JOURNALMODE_DELETE;
+-      }
++  for(ii=0; ii<pPager->nSavepoint; ii++){
++    PagerSavepoint *p = &pPager->aSavepoint[ii];
++    if( pgno<=p->nOrig ){
++      rc |= sqlite3BitvecSet(p->pInSavepoint, pgno);
++      testcase( rc==SQLITE_NOMEM );
++      assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
+     }
+   }
+   return rc;
+ }
+-#endif
+ 
+ /*
+-** Playback savepoint pSavepoint. Or, if pSavepoint==NULL, then playback
+-** the entire master journal file. The case pSavepoint==NULL occurs when 
+-** a ROLLBACK TO command is invoked on a SAVEPOINT that is a transaction 
+-** savepoint.
+-**
+-** When pSavepoint is not NULL (meaning a non-transaction savepoint is 
+-** being rolled back), then the rollback consists of up to three stages,
+-** performed in the order specified:
+-**
+-**   * Pages are played back from the main journal starting at byte
+-**     offset PagerSavepoint.iOffset and continuing to 
+-**     PagerSavepoint.iHdrOffset, or to the end of the main journal
+-**     file if PagerSavepoint.iHdrOffset is zero.
+-**
+-**   * If PagerSavepoint.iHdrOffset is not zero, then pages are played
+-**     back starting from the journal header immediately following 
+-**     PagerSavepoint.iHdrOffset to the end of the main journal file.
+-**
+-**   * Pages are then played back from the sub-journal file, starting
+-**     with the PagerSavepoint.iSubRec and continuing to the end of
+-**     the journal file.
+-**
+-** Throughout the rollback process, each time a page is rolled back, the
+-** corresponding bit is set in a bitvec structure (variable pDone in the
+-** implementation below). This is used to ensure that a page is only
+-** rolled back the first time it is encountered in either journal.
++** This function is a no-op if the pager is in exclusive mode and not
++** in the ERROR state. Otherwise, it switches the pager to PAGER_OPEN
++** state.
+ **
+-** If pSavepoint is NULL, then pages are only played back from the main
+-** journal file. There is no need for a bitvec in this case.
++** If the pager is not in exclusive-access mode, the database file is
++** completely unlocked. If the file is unlocked and the file-system does
++** not exhibit the UNDELETABLE_WHEN_OPEN property, the journal file is
++** closed (if it is open).
+ **
+-** In either case, before playback commences the Pager.dbSize variable
+-** is reset to the value that it held at the start of the savepoint 
+-** (or transaction). No page with a page-number greater than this value
+-** is played back. If one is encountered it is simply skipped.
++** If the pager is in ERROR state when this function is called, the 
++** contents of the pager cache are discarded before switching back to 
++** the OPEN state. Regardless of whether the pager is in exclusive-mode
++** or not, any journal file left in the file-system will be treated
++** as a hot-journal and rolled back the next time a read-transaction
++** is opened (by this or by any other connection).
+ */
+-static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){
+-  i64 szJ;                 /* Effective size of the main journal */
+-  i64 iHdrOff;             /* End of first segment of main-journal records */
+-  int rc = SQLITE_OK;      /* Return code */
+-  Bitvec *pDone = 0;       /* Bitvec to ensure pages played back only once */
+-
+-  assert( pPager->eState!=PAGER_ERROR );
+-  assert( pPager->eState>=PAGER_WRITER_LOCKED );
+-
+-  /* Allocate a bitvec to use to store the set of pages rolled back */
+-  if( pSavepoint ){
+-    pDone = sqlite3BitvecCreate(pSavepoint->nOrig);
+-    if( !pDone ){
+-      return SQLITE_NOMEM;
+-    }
+-  }
+-
+-  /* Set the database size back to the value it was before the savepoint 
+-  ** being reverted was opened.
+-  */
+-  pPager->dbSize = pSavepoint ? pSavepoint->nOrig : pPager->dbOrigSize;
+-  pPager->changeCountDone = pPager->tempFile;
+-
+-  if( !pSavepoint && pagerUseWal(pPager) ){
+-    return pagerRollbackWal(pPager);
+-  }
++static void pager_unlock(Pager *pPager){
+ 
+-  /* Use pPager->journalOff as the effective size of the main rollback
+-  ** journal.  The actual file might be larger than this in
+-  ** PAGER_JOURNALMODE_TRUNCATE or PAGER_JOURNALMODE_PERSIST.  But anything
+-  ** past pPager->journalOff is off-limits to us.
+-  */
+-  szJ = pPager->journalOff;
+-  assert( pagerUseWal(pPager)==0 || szJ==0 );
++  assert( pPager->eState==PAGER_READER 
++       || pPager->eState==PAGER_OPEN 
++       || pPager->eState==PAGER_ERROR 
++  );
+ 
+-  /* Begin by rolling back records from the main journal starting at
+-  ** PagerSavepoint.iOffset and continuing to the next journal header.
+-  ** There might be records in the main journal that have a page number
+-  ** greater than the current database size (pPager->dbSize) but those
+-  ** will be skipped automatically.  Pages are added to pDone as they
+-  ** are played back.
+-  */
+-  if( pSavepoint && !pagerUseWal(pPager) ){
+-    iHdrOff = pSavepoint->iHdrOffset ? pSavepoint->iHdrOffset : szJ;
+-    pPager->journalOff = pSavepoint->iOffset;
+-    while( rc==SQLITE_OK && pPager->journalOff<iHdrOff ){
+-      rc = pager_playback_one_page(pPager, &pPager->journalOff, pDone, 1, 1);
+-    }
+-    assert( rc!=SQLITE_DONE );
+-  }else{
+-    pPager->journalOff = 0;
+-  }
++  sqlite3BitvecDestroy(pPager->pInJournal);
++  pPager->pInJournal = 0;
++  releaseAllSavepoints(pPager);
+ 
+-  /* Continue rolling back records out of the main journal starting at
+-  ** the first journal header seen and continuing until the effective end
+-  ** of the main journal file.  Continue to skip out-of-range pages and
+-  ** continue adding pages rolled back to pDone.
+-  */
+-  while( rc==SQLITE_OK && pPager->journalOff<szJ ){
+-    u32 ii;            /* Loop counter */
+-    u32 nJRec = 0;     /* Number of Journal Records */
+-    u32 dummy;
+-    rc = readJournalHdr(pPager, 0, szJ, &nJRec, &dummy);
+-    assert( rc!=SQLITE_DONE );
++  if( pagerUseWal(pPager) ){
++    assert( !isOpen(pPager->jfd) );
++    sqlite3WalEndReadTransaction(pPager->pWal);
++    pPager->eState = PAGER_OPEN;
++  }else if( !pPager->exclusiveMode ){
++    int rc;                       /* Error code returned by pagerUnlockDb() */
++    int iDc = isOpen(pPager->fd)?sqlite3OsDeviceCharacteristics(pPager->fd):0;
+ 
+-    /*
+-    ** The "pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff"
+-    ** test is related to ticket #2565.  See the discussion in the
+-    ** pager_playback() function for additional information.
++    /* If the operating system support deletion of open files, then
++    ** close the journal file when dropping the database lock.  Otherwise
++    ** another connection with journal_mode=delete might delete the file
++    ** out from under us.
+     */
+-    if( nJRec==0 
+-     && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff
++    assert( (PAGER_JOURNALMODE_MEMORY   & 5)!=1 );
++    assert( (PAGER_JOURNALMODE_OFF      & 5)!=1 );
++    assert( (PAGER_JOURNALMODE_WAL      & 5)!=1 );
++    assert( (PAGER_JOURNALMODE_DELETE   & 5)!=1 );
++    assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 );
++    assert( (PAGER_JOURNALMODE_PERSIST  & 5)==1 );
++    if( 0==(iDc & SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN)
++     || 1!=(pPager->journalMode & 5)
+     ){
+-      nJRec = (u32)((szJ - pPager->journalOff)/JOURNAL_PG_SZ(pPager));
+-    }
+-    for(ii=0; rc==SQLITE_OK && ii<nJRec && pPager->journalOff<szJ; ii++){
+-      rc = pager_playback_one_page(pPager, &pPager->journalOff, pDone, 1, 1);
++      sqlite3OsClose(pPager->jfd);
+     }
+-    assert( rc!=SQLITE_DONE );
+-  }
+-  assert( rc!=SQLITE_OK || pPager->journalOff>=szJ );
+-
+-  /* Finally,  rollback pages from the sub-journal.  Page that were
+-  ** previously rolled back out of the main journal (and are hence in pDone)
+-  ** will be skipped.  Out-of-range pages are also skipped.
+-  */
+-  if( pSavepoint ){
+-    u32 ii;            /* Loop counter */
+-    i64 offset = (i64)pSavepoint->iSubRec*(4+pPager->pageSize);
+ 
+-    if( pagerUseWal(pPager) ){
+-      rc = sqlite3WalSavepointUndo(pPager->pWal, pSavepoint->aWalData);
+-    }
+-    for(ii=pSavepoint->iSubRec; rc==SQLITE_OK && ii<pPager->nSubRec; ii++){
+-      assert( offset==(i64)ii*(4+pPager->pageSize) );
+-      rc = pager_playback_one_page(pPager, &offset, pDone, 0, 1);
++    /* If the pager is in the ERROR state and the call to unlock the database
++    ** file fails, set the current lock to UNKNOWN_LOCK. See the comment
++    ** above the #define for UNKNOWN_LOCK for an explanation of why this
++    ** is necessary.
++    */
++    rc = pagerUnlockDb(pPager, NO_LOCK);
++    if( rc!=SQLITE_OK && pPager->eState==PAGER_ERROR ){
++      pPager->eLock = UNKNOWN_LOCK;
+     }
+-    assert( rc!=SQLITE_DONE );
+-  }
+ 
+-  sqlite3BitvecDestroy(pDone);
+-  if( rc==SQLITE_OK ){
+-    pPager->journalOff = szJ;
++    /* The pager state may be changed from PAGER_ERROR to PAGER_OPEN here
++    ** without clearing the error code. This is intentional - the error
++    ** code is cleared and the cache reset in the block below.
++    */
++    assert( pPager->errCode || pPager->eState!=PAGER_ERROR );
++    pPager->changeCountDone = 0;
++    pPager->eState = PAGER_OPEN;
+   }
+ 
+-  return rc;
+-}
++  /* If Pager.errCode is set, the contents of the pager cache cannot be
++  ** trusted. Now that there are no outstanding references to the pager,
++  ** it can safely move back to PAGER_OPEN state. This happens in both
++  ** normal and exclusive-locking mode.
++  */
++  if( pPager->errCode ){
++    assert( !MEMDB );
++    pager_reset(pPager);
++    pPager->changeCountDone = pPager->tempFile;
++    pPager->eState = PAGER_OPEN;
++    pPager->errCode = SQLITE_OK;
++    if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
++  }
+ 
+-/*
+-** Change the maximum number of in-memory pages that are allowed.
+-*/
+-SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
+-  sqlite3PcacheSetCachesize(pPager->pPCache, mxPage);
++  pPager->journalOff = 0;
++  pPager->journalHdr = 0;
++  pPager->setMaster = 0;
+ }
+ 
+ /*
+-** Invoke SQLITE_FCNTL_MMAP_SIZE based on the current value of szMmap.
++** This function is called whenever an IOERR or FULL error that requires
++** the pager to transition into the ERROR state may ahve occurred.
++** The first argument is a pointer to the pager structure, the second 
++** the error-code about to be returned by a pager API function. The 
++** value returned is a copy of the second argument to this function. 
++**
++** If the second argument is SQLITE_FULL, SQLITE_IOERR or one of the
++** IOERR sub-codes, the pager enters the ERROR state and the error code
++** is stored in Pager.errCode. While the pager remains in the ERROR state,
++** all major API calls on the Pager will immediately return Pager.errCode.
++**
++** The ERROR state indicates that the contents of the pager-cache 
++** cannot be trusted. This state can be cleared by completely discarding 
++** the contents of the pager-cache. If a transaction was active when
++** the persistent error occurred, then the rollback journal may need
++** to be replayed to restore the contents of the database file (as if
++** it were a hot-journal).
+ */
+-static void pagerFixMaplimit(Pager *pPager){
+-#if SQLITE_MAX_MMAP_SIZE>0
+-  sqlite3_file *fd = pPager->fd;
+-  if( isOpen(fd) && fd->pMethods->iVersion>=3 ){
+-    sqlite3_int64 sz;
+-    sz = pPager->szMmap;
+-    pPager->bUseFetch = (sz>0);
+-    sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz);
++static int pager_error(Pager *pPager, int rc){
++  int rc2 = rc & 0xff;
++  assert( rc==SQLITE_OK || !MEMDB );
++  assert(
++       pPager->errCode==SQLITE_FULL ||
++       pPager->errCode==SQLITE_OK ||
++       (pPager->errCode & 0xff)==SQLITE_IOERR
++  );
++  if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){
++    pPager->errCode = rc;
++    pPager->eState = PAGER_ERROR;
+   }
+-#endif
+-}
+-
+-/*
+-** Change the maximum size of any memory mapping made of the database file.
+-*/
+-SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *pPager, sqlite3_int64 szMmap){
+-  pPager->szMmap = szMmap;
+-  pagerFixMaplimit(pPager);
++  return rc;
+ }
+ 
+-/*
+-** Free as much memory as possible from the pager.
+-*/
+-SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
+-  sqlite3PcacheShrink(pPager->pPCache);
+-}
++static int pager_truncate(Pager *pPager, Pgno nPage);
+ 
+ /*
+-** Adjust settings of the pager to those specified in the pgFlags parameter.
++** This routine ends a transaction. A transaction is usually ended by 
++** either a COMMIT or a ROLLBACK operation. This routine may be called 
++** after rollback of a hot-journal, or if an error occurs while opening
++** the journal file or writing the very first journal-header of a
++** database transaction.
++** 
++** This routine is never called in PAGER_ERROR state. If it is called
++** in PAGER_NONE or PAGER_SHARED state and the lock held is less
++** exclusive than a RESERVED lock, it is a no-op.
+ **
+-** The "level" in pgFlags & PAGER_SYNCHRONOUS_MASK sets the robustness
+-** of the database to damage due to OS crashes or power failures by
+-** changing the number of syncs()s when writing the journals.
+-** There are three levels:
++** Otherwise, any active savepoints are released.
+ **
+-**    OFF       sqlite3OsSync() is never called.  This is the default
+-**              for temporary and transient files.
++** If the journal file is open, then it is "finalized". Once a journal 
++** file has been finalized it is not possible to use it to roll back a 
++** transaction. Nor will it be considered to be a hot-journal by this
++** or any other database connection. Exactly how a journal is finalized
++** depends on whether or not the pager is running in exclusive mode and
++** the current journal-mode (Pager.journalMode value), as follows:
+ **
+-**    NORMAL    The journal is synced once before writes begin on the
+-**              database.  This is normally adequate protection, but
+-**              it is theoretically possible, though very unlikely,
+-**              that an inopertune power failure could leave the journal
+-**              in a state which would cause damage to the database
+-**              when it is rolled back.
++**   journalMode==MEMORY
++**     Journal file descriptor is simply closed. This destroys an 
++**     in-memory journal.
+ **
+-**    FULL      The journal is synced twice before writes begin on the
+-**              database (with some additional information - the nRec field
+-**              of the journal header - being written in between the two
+-**              syncs).  If we assume that writing a
+-**              single disk sector is atomic, then this mode provides
+-**              assurance that the journal will not be corrupted to the
+-**              point of causing damage to the database during rollback.
++**   journalMode==TRUNCATE
++**     Journal file is truncated to zero bytes in size.
+ **
+-** The above is for a rollback-journal mode.  For WAL mode, OFF continues
+-** to mean that no syncs ever occur.  NORMAL means that the WAL is synced
+-** prior to the start of checkpoint and that the database file is synced
+-** at the conclusion of the checkpoint if the entire content of the WAL
+-** was written back into the database.  But no sync operations occur for
+-** an ordinary commit in NORMAL mode with WAL.  FULL means that the WAL
+-** file is synced following each commit operation, in addition to the
+-** syncs associated with NORMAL.
++**   journalMode==PERSIST
++**     The first 28 bytes of the journal file are zeroed. This invalidates
++**     the first journal header in the file, and hence the entire journal
++**     file. An invalid journal file cannot be rolled back.
+ **
+-** Do not confuse synchronous=FULL with SQLITE_SYNC_FULL.  The
+-** SQLITE_SYNC_FULL macro means to use the MacOSX-style full-fsync
+-** using fcntl(F_FULLFSYNC).  SQLITE_SYNC_NORMAL means to do an
+-** ordinary fsync() call.  There is no difference between SQLITE_SYNC_FULL
+-** and SQLITE_SYNC_NORMAL on platforms other than MacOSX.  But the
+-** synchronous=FULL versus synchronous=NORMAL setting determines when
+-** the xSync primitive is called and is relevant to all platforms.
++**   journalMode==DELETE
++**     The journal file is closed and deleted using sqlite3OsDelete().
+ **
+-** Numeric values associated with these states are OFF==1, NORMAL=2,
+-** and FULL=3.
++**     If the pager is running in exclusive mode, this method of finalizing
++**     the journal file is never used. Instead, if the journalMode is
++**     DELETE and the pager is in exclusive mode, the method described under
++**     journalMode==PERSIST is used instead.
++**
++** After the journal is finalized, the pager moves to PAGER_READER state.
++** If running in non-exclusive rollback mode, the lock on the file is 
++** downgraded to a SHARED_LOCK.
++**
++** SQLITE_OK is returned if no error occurs. If an error occurs during
++** any of the IO operations to finalize the journal file or unlock the
++** database then the IO error code is returned to the user. If the 
++** operation to finalize the journal file fails, then the code still
++** tries to unlock the database file if not in exclusive mode. If the
++** unlock operation fails as well, then the first error code related
++** to the first error encountered (the journal finalization one) is
++** returned.
+ */
+-#ifndef SQLITE_OMIT_PAGER_PRAGMAS
+-SQLITE_PRIVATE void sqlite3PagerSetFlags(
+-  Pager *pPager,        /* The pager to set safety level for */
+-  unsigned pgFlags      /* Various flags */
+-){
+-  unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK;
+-  assert( level>=1 && level<=3 );
+-  pPager->noSync =  (level==1 || pPager->tempFile) ?1:0;
+-  pPager->fullSync = (level==3 && !pPager->tempFile) ?1:0;
+-  if( pPager->noSync ){
+-    pPager->syncFlags = 0;
+-    pPager->ckptSyncFlags = 0;
+-  }else if( pgFlags & PAGER_FULLFSYNC ){
+-    pPager->syncFlags = SQLITE_SYNC_FULL;
+-    pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
+-  }else if( pgFlags & PAGER_CKPT_FULLFSYNC ){
+-    pPager->syncFlags = SQLITE_SYNC_NORMAL;
+-    pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
+-  }else{
+-    pPager->syncFlags = SQLITE_SYNC_NORMAL;
+-    pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL;
++static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){
++  int rc = SQLITE_OK;      /* Error code from journal finalization operation */
++  int rc2 = SQLITE_OK;     /* Error code from db file unlock operation */
++
++  /* Do nothing if the pager does not have an open write transaction
++  ** or at least a RESERVED lock. This function may be called when there
++  ** is no write-transaction active but a RESERVED or greater lock is
++  ** held under two circumstances:
++  **
++  **   1. After a successful hot-journal rollback, it is called with
++  **      eState==PAGER_NONE and eLock==EXCLUSIVE_LOCK.
++  **
++  **   2. If a connection with locking_mode=exclusive holding an EXCLUSIVE 
++  **      lock switches back to locking_mode=normal and then executes a
++  **      read-transaction, this function is called with eState==PAGER_READER 
++  **      and eLock==EXCLUSIVE_LOCK when the read-transaction is closed.
++  */
++  assert( assert_pager_state(pPager) );
++  assert( pPager->eState!=PAGER_ERROR );
++  if( pPager->eState<PAGER_WRITER_LOCKED && pPager->eLock<RESERVED_LOCK ){
++    return SQLITE_OK;
+   }
+-  pPager->walSyncFlags = pPager->syncFlags;
+-  if( pPager->fullSync ){
+-    pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS;
++
++  releaseAllSavepoints(pPager);
++  assert( isOpen(pPager->jfd) || pPager->pInJournal==0 );
++  if( isOpen(pPager->jfd) ){
++    assert( !pagerUseWal(pPager) );
++
++    /* Finalize the journal file. */
++    if( sqlite3IsMemJournal(pPager->jfd) ){
++      assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY );
++      sqlite3OsClose(pPager->jfd);
++    }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){
++      if( pPager->journalOff==0 ){
++        rc = SQLITE_OK;
++      }else{
++        rc = sqlite3OsTruncate(pPager->jfd, 0);
++        if( rc==SQLITE_OK && pPager->fullSync ){
++          /* Make sure the new file size is written into the inode right away.
++          ** Otherwise the journal might resurrect following a power loss and
++          ** cause the last transaction to roll back.  See
++          ** https://bugzilla.mozilla.org/show_bug.cgi?id=1072773
++          */
++          rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags);
++        }
++      }
++      pPager->journalOff = 0;
++    }else if( pPager->journalMode==PAGER_JOURNALMODE_PERSIST
++      || (pPager->exclusiveMode && pPager->journalMode!=PAGER_JOURNALMODE_WAL)
++    ){
++      rc = zeroJournalHdr(pPager, hasMaster);
++      pPager->journalOff = 0;
++    }else{
++      /* This branch may be executed with Pager.journalMode==MEMORY if
++      ** a hot-journal was just rolled back. In this case the journal
++      ** file should be closed and deleted. If this connection writes to
++      ** the database file, it will do so using an in-memory journal. 
++      */
++      int bDelete = (!pPager->tempFile && sqlite3JournalExists(pPager->jfd));
++      assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE 
++           || pPager->journalMode==PAGER_JOURNALMODE_MEMORY 
++           || pPager->journalMode==PAGER_JOURNALMODE_WAL 
++      );
++      sqlite3OsClose(pPager->jfd);
++      if( bDelete ){
++        rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
++      }
++    }
+   }
+-  if( pgFlags & PAGER_CACHESPILL ){
+-    pPager->doNotSpill &= ~SPILLFLAG_OFF;
+-  }else{
+-    pPager->doNotSpill |= SPILLFLAG_OFF;
++
++#ifdef SQLITE_CHECK_PAGES
++  sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash);
++  if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){
++    PgHdr *p = sqlite3PagerLookup(pPager, 1);
++    if( p ){
++      p->pageHash = 0;
++      sqlite3PagerUnrefNotNull(p);
++    }
++  }
++#endif
++
++  sqlite3BitvecDestroy(pPager->pInJournal);
++  pPager->pInJournal = 0;
++  pPager->nRec = 0;
++  sqlite3PcacheCleanAll(pPager->pPCache);
++  sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize);
++
++  if( pagerUseWal(pPager) ){
++    /* Drop the WAL write-lock, if any. Also, if the connection was in 
++    ** locking_mode=exclusive mode but is no longer, drop the EXCLUSIVE 
++    ** lock held on the database file.
++    */
++    rc2 = sqlite3WalEndWriteTransaction(pPager->pWal);
++    assert( rc2==SQLITE_OK );
++  }else if( rc==SQLITE_OK && bCommit && pPager->dbFileSize>pPager->dbSize ){
++    /* This branch is taken when committing a transaction in rollback-journal
++    ** mode if the database file on disk is larger than the database image.
++    ** At this point the journal has been finalized and the transaction 
++    ** successfully committed, but the EXCLUSIVE lock is still held on the
++    ** file. So it is safe to truncate the database file to its minimum
++    ** required size.  */
++    assert( pPager->eLock==EXCLUSIVE_LOCK );
++    rc = pager_truncate(pPager, pPager->dbSize);
++  }
++
++  if( rc==SQLITE_OK && bCommit && isOpen(pPager->fd) ){
++    rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_COMMIT_PHASETWO, 0);
++    if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
+   }
++
++  if( !pPager->exclusiveMode 
++   && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0))
++  ){
++    rc2 = pagerUnlockDb(pPager, SHARED_LOCK);
++    pPager->changeCountDone = 0;
++  }
++  pPager->eState = PAGER_READER;
++  pPager->setMaster = 0;
++
++  return (rc==SQLITE_OK?rc2:rc);
+ }
+-#endif
+ 
+ /*
+-** The following global variable is incremented whenever the library
+-** attempts to open a temporary file.  This information is used for
+-** testing and analysis only.  
++** Execute a rollback if a transaction is active and unlock the 
++** database file. 
++**
++** If the pager has already entered the ERROR state, do not attempt 
++** the rollback at this time. Instead, pager_unlock() is called. The
++** call to pager_unlock() will discard all in-memory pages, unlock
++** the database file and move the pager back to OPEN state. If this 
++** means that there is a hot-journal left in the file-system, the next 
++** connection to obtain a shared lock on the pager (which may be this one) 
++** will roll it back.
++**
++** If the pager has not already entered the ERROR state, but an IO or
++** malloc error occurs during a rollback, then this will itself cause 
++** the pager to enter the ERROR state. Which will be cleared by the
++** call to pager_unlock(), as described above.
+ */
+-#ifdef SQLITE_TEST
+-SQLITE_API int sqlite3_opentemp_count = 0;
+-#endif
++static void pagerUnlockAndRollback(Pager *pPager){
++  if( pPager->eState!=PAGER_ERROR && pPager->eState!=PAGER_OPEN ){
++    assert( assert_pager_state(pPager) );
++    if( pPager->eState>=PAGER_WRITER_LOCKED ){
++      sqlite3BeginBenignMalloc();
++      sqlite3PagerRollback(pPager);
++      sqlite3EndBenignMalloc();
++    }else if( !pPager->exclusiveMode ){
++      assert( pPager->eState==PAGER_READER );
++      pager_end_transaction(pPager, 0, 0);
++    }
++  }
++  pager_unlock(pPager);
++}
+ 
+ /*
+-** Open a temporary file.
++** Parameter aData must point to a buffer of pPager->pageSize bytes
++** of data. Compute and return a checksum based ont the contents of the 
++** page of data and the current value of pPager->cksumInit.
+ **
+-** Write the file descriptor into *pFile. Return SQLITE_OK on success 
+-** or some other error code if we fail. The OS will automatically 
+-** delete the temporary file when it is closed.
++** This is not a real checksum. It is really just the sum of the 
++** random initial value (pPager->cksumInit) and every 200th byte
++** of the page data, starting with byte offset (pPager->pageSize%200).
++** Each byte is interpreted as an 8-bit unsigned integer.
+ **
+-** The flags passed to the VFS layer xOpen() call are those specified
+-** by parameter vfsFlags ORed with the following:
++** Changing the formula used to compute this checksum results in an
++** incompatible journal file format.
+ **
+-**     SQLITE_OPEN_READWRITE
+-**     SQLITE_OPEN_CREATE
+-**     SQLITE_OPEN_EXCLUSIVE
+-**     SQLITE_OPEN_DELETEONCLOSE
++** If journal corruption occurs due to a power failure, the most likely 
++** scenario is that one end or the other of the record will be changed. 
++** It is much less likely that the two ends of the journal record will be
++** correct and the middle be corrupt.  Thus, this "checksum" scheme,
++** though fast and simple, catches the mostly likely kind of corruption.
+ */
+-static int pagerOpentemp(
+-  Pager *pPager,        /* The pager object */
+-  sqlite3_file *pFile,  /* Write the file descriptor here */
+-  int vfsFlags          /* Flags passed through to the VFS */
+-){
+-  int rc;               /* Return code */
+-
+-#ifdef SQLITE_TEST
+-  sqlite3_opentemp_count++;  /* Used for testing and analysis only */
+-#endif
++static u32 pager_cksum(Pager *pPager, const u8 *aData){
++  u32 cksum = pPager->cksumInit;         /* Checksum value to return */
++  int i = pPager->pageSize-200;          /* Loop counter */
++  while( i>0 ){
++    cksum += aData[i];
++    i -= 200;
++  }
++  return cksum;
++}
+ 
+-  vfsFlags |=  SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
+-            SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE;
+-  rc = sqlite3OsOpen(pPager->pVfs, 0, pFile, vfsFlags, 0);
+-  assert( rc!=SQLITE_OK || isOpen(pFile) );
+-  return rc;
++/*
++** Report the current page size and number of reserved bytes back
++** to the codec.
++*/
++#ifdef SQLITE_HAS_CODEC
++static void pagerReportSize(Pager *pPager){
++  if( pPager->xCodecSizeChng ){
++    pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize,
++                           (int)pPager->nReserve);
++  }
+ }
++#else
++# define pagerReportSize(X)     /* No-op if we do not support a codec */
++#endif
+ 
+ /*
+-** Set the busy handler function.
++** Read a single page from either the journal file (if isMainJrnl==1) or
++** from the sub-journal (if isMainJrnl==0) and playback that page.
++** The page begins at offset *pOffset into the file. The *pOffset
++** value is increased to the start of the next page in the journal.
+ **
+-** The pager invokes the busy-handler if sqlite3OsLock() returns 
+-** SQLITE_BUSY when trying to upgrade from no-lock to a SHARED lock,
+-** or when trying to upgrade from a RESERVED lock to an EXCLUSIVE 
+-** lock. It does *not* invoke the busy handler when upgrading from
+-** SHARED to RESERVED, or when upgrading from SHARED to EXCLUSIVE
+-** (which occurs during hot-journal rollback). Summary:
++** The main rollback journal uses checksums - the statement journal does 
++** not.
+ **
+-**   Transition                        | Invokes xBusyHandler
+-**   --------------------------------------------------------
+-**   NO_LOCK       -> SHARED_LOCK      | Yes
+-**   SHARED_LOCK   -> RESERVED_LOCK    | No
+-**   SHARED_LOCK   -> EXCLUSIVE_LOCK   | No
+-**   RESERVED_LOCK -> EXCLUSIVE_LOCK   | Yes
++** If the page number of the page record read from the (sub-)journal file
++** is greater than the current value of Pager.dbSize, then playback is
++** skipped and SQLITE_OK is returned.
+ **
+-** If the busy-handler callback returns non-zero, the lock is 
+-** retried. If it returns zero, then the SQLITE_BUSY error is
+-** returned to the caller of the pager API function.
++** If pDone is not NULL, then it is a record of pages that have already
++** been played back.  If the page at *pOffset has already been played back
++** (if the corresponding pDone bit is set) then skip the playback.
++** Make sure the pDone bit corresponding to the *pOffset page is set
++** prior to returning.
++**
++** If the page record is successfully read from the (sub-)journal file
++** and played back, then SQLITE_OK is returned. If an IO error occurs
++** while reading the record from the (sub-)journal file or while writing
++** to the database file, then the IO error code is returned. If data
++** is successfully read from the (sub-)journal file but appears to be
++** corrupted, SQLITE_DONE is returned. Data is considered corrupted in
++** two circumstances:
++** 
++**   * If the record page-number is illegal (0 or PAGER_MJ_PGNO), or
++**   * If the record is being rolled back from the main journal file
++**     and the checksum field does not match the record content.
++**
++** Neither of these two scenarios are possible during a savepoint rollback.
++**
++** If this is a savepoint rollback, then memory may have to be dynamically
++** allocated by this function. If this is the case and an allocation fails,
++** SQLITE_NOMEM is returned.
+ */
+-SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(
+-  Pager *pPager,                       /* Pager object */
+-  int (*xBusyHandler)(void *),         /* Pointer to busy-handler function */
+-  void *pBusyHandlerArg                /* Argument to pass to xBusyHandler */
++static int pager_playback_one_page(
++  Pager *pPager,                /* The pager being played back */
++  i64 *pOffset,                 /* Offset of record to playback */
++  Bitvec *pDone,                /* Bitvec of pages already played back */
++  int isMainJrnl,               /* 1 -> main journal. 0 -> sub-journal. */
++  int isSavepnt                 /* True for a savepoint rollback */
+ ){
+-  pPager->xBusyHandler = xBusyHandler;
+-  pPager->pBusyHandlerArg = pBusyHandlerArg;
++  int rc;
++  PgHdr *pPg;                   /* An existing page in the cache */
++  Pgno pgno;                    /* The page number of a page in journal */
++  u32 cksum;                    /* Checksum used for sanity checking */
++  char *aData;                  /* Temporary storage for the page */
++  sqlite3_file *jfd;            /* The file descriptor for the journal file */
++  int isSynced;                 /* True if journal page is synced */
+ 
+-  if( isOpen(pPager->fd) ){
+-    void **ap = (void **)&pPager->xBusyHandler;
+-    assert( ((int(*)(void *))(ap[0]))==xBusyHandler );
+-    assert( ap[1]==pBusyHandlerArg );
+-    sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap);
++  assert( (isMainJrnl&~1)==0 );      /* isMainJrnl is 0 or 1 */
++  assert( (isSavepnt&~1)==0 );       /* isSavepnt is 0 or 1 */
++  assert( isMainJrnl || pDone );     /* pDone always used on sub-journals */
++  assert( isSavepnt || pDone==0 );   /* pDone never used on non-savepoint */
++
++  aData = pPager->pTmpSpace;
++  assert( aData );         /* Temp storage must have already been allocated */
++  assert( pagerUseWal(pPager)==0 || (!isMainJrnl && isSavepnt) );
++
++  /* Either the state is greater than PAGER_WRITER_CACHEMOD (a transaction 
++  ** or savepoint rollback done at the request of the caller) or this is
++  ** a hot-journal rollback. If it is a hot-journal rollback, the pager
++  ** is in state OPEN and holds an EXCLUSIVE lock. Hot-journal rollback
++  ** only reads from the main journal, not the sub-journal.
++  */
++  assert( pPager->eState>=PAGER_WRITER_CACHEMOD
++       || (pPager->eState==PAGER_OPEN && pPager->eLock==EXCLUSIVE_LOCK)
++  );
++  assert( pPager->eState>=PAGER_WRITER_CACHEMOD || isMainJrnl );
++
++  /* Read the page number and page data from the journal or sub-journal
++  ** file. Return an error code to the caller if an IO error occurs.
++  */
++  jfd = isMainJrnl ? pPager->jfd : pPager->sjfd;
++  rc = read32bits(jfd, *pOffset, &pgno);
++  if( rc!=SQLITE_OK ) return rc;
++  rc = sqlite3OsRead(jfd, (u8*)aData, pPager->pageSize, (*pOffset)+4);
++  if( rc!=SQLITE_OK ) return rc;
++  *pOffset += pPager->pageSize + 4 + isMainJrnl*4;
++
++  /* Sanity checking on the page.  This is more important that I originally
++  ** thought.  If a power failure occurs while the journal is being written,
++  ** it could cause invalid data to be written into the journal.  We need to
++  ** detect this invalid data (with high probability) and ignore it.
++  */
++  if( pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){
++    assert( !isSavepnt );
++    return SQLITE_DONE;
++  }
++  if( pgno>(Pgno)pPager->dbSize || sqlite3BitvecTest(pDone, pgno) ){
++    return SQLITE_OK;
++  }
++  if( isMainJrnl ){
++    rc = read32bits(jfd, (*pOffset)-4, &cksum);
++    if( rc ) return rc;
++    if( !isSavepnt && pager_cksum(pPager, (u8*)aData)!=cksum ){
++      return SQLITE_DONE;
++    }
++  }
++
++  /* If this page has already been played by before during the current
++  ** rollback, then don't bother to play it back again.
++  */
++  if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){
++    return rc;
++  }
++
++  /* When playing back page 1, restore the nReserve setting
++  */
++  if( pgno==1 && pPager->nReserve!=((u8*)aData)[20] ){
++    pPager->nReserve = ((u8*)aData)[20];
++    pagerReportSize(pPager);
++  }
++
++  /* If the pager is in CACHEMOD state, then there must be a copy of this
++  ** page in the pager cache. In this case just update the pager cache,
++  ** not the database file. The page is left marked dirty in this case.
++  **
++  ** An exception to the above rule: If the database is in no-sync mode
++  ** and a page is moved during an incremental vacuum then the page may
++  ** not be in the pager cache. Later: if a malloc() or IO error occurs
++  ** during a Movepage() call, then the page may not be in the cache
++  ** either. So the condition described in the above paragraph is not
++  ** assert()able.
++  **
++  ** If in WRITER_DBMOD, WRITER_FINISHED or OPEN state, then we update the
++  ** pager cache if it exists and the main file. The page is then marked 
++  ** not dirty. Since this code is only executed in PAGER_OPEN state for
++  ** a hot-journal rollback, it is guaranteed that the page-cache is empty
++  ** if the pager is in OPEN state.
++  **
++  ** Ticket #1171:  The statement journal might contain page content that is
++  ** different from the page content at the start of the transaction.
++  ** This occurs when a page is changed prior to the start of a statement
++  ** then changed again within the statement.  When rolling back such a
++  ** statement we must not write to the original database unless we know
++  ** for certain that original page contents are synced into the main rollback
++  ** journal.  Otherwise, a power loss might leave modified data in the
++  ** database file without an entry in the rollback journal that can
++  ** restore the database to its original form.  Two conditions must be
++  ** met before writing to the database files. (1) the database must be
++  ** locked.  (2) we know that the original page content is fully synced
++  ** in the main journal either because the page is not in cache or else
++  ** the page is marked as needSync==0.
++  **
++  ** 2008-04-14:  When attempting to vacuum a corrupt database file, it
++  ** is possible to fail a statement on a database that does not yet exist.
++  ** Do not attempt to write if database file has never been opened.
++  */
++  if( pagerUseWal(pPager) ){
++    pPg = 0;
++  }else{
++    pPg = sqlite3PagerLookup(pPager, pgno);
++  }
++  assert( pPg || !MEMDB );
++  assert( pPager->eState!=PAGER_OPEN || pPg==0 );
++  PAGERTRACE(("PLAYBACK %d page %d hash(%08x) %s\n",
++           PAGERID(pPager), pgno, pager_datahash(pPager->pageSize, (u8*)aData),
++           (isMainJrnl?"main-journal":"sub-journal")
++  ));
++  if( isMainJrnl ){
++    isSynced = pPager->noSync || (*pOffset <= pPager->journalHdr);
++  }else{
++    isSynced = (pPg==0 || 0==(pPg->flags & PGHDR_NEED_SYNC));
++  }
++  if( isOpen(pPager->fd)
++   && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
++   && isSynced
++  ){
++    i64 ofst = (pgno-1)*(i64)pPager->pageSize;
++    testcase( !isSavepnt && pPg!=0 && (pPg->flags&PGHDR_NEED_SYNC)!=0 );
++    assert( !pagerUseWal(pPager) );
++    rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst);
++    if( pgno>pPager->dbFileSize ){
++      pPager->dbFileSize = pgno;
++    }
++    if( pPager->pBackup ){
++      CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM);
++      sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData);
++      CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM, aData);
++    }
++  }else if( !isMainJrnl && pPg==0 ){
++    /* If this is a rollback of a savepoint and data was not written to
++    ** the database and the page is not in-memory, there is a potential
++    ** problem. When the page is next fetched by the b-tree layer, it 
++    ** will be read from the database file, which may or may not be 
++    ** current. 
++    **
++    ** There are a couple of different ways this can happen. All are quite
++    ** obscure. When running in synchronous mode, this can only happen 
++    ** if the page is on the free-list at the start of the transaction, then
++    ** populated, then moved using sqlite3PagerMovepage().
++    **
++    ** The solution is to add an in-memory page to the cache containing
++    ** the data just read from the sub-journal. Mark the page as dirty 
++    ** and if the pager requires a journal-sync, then mark the page as 
++    ** requiring a journal-sync before it is written.
++    */
++    assert( isSavepnt );
++    assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 );
++    pPager->doNotSpill |= SPILLFLAG_ROLLBACK;
++    rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1);
++    assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 );
++    pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK;
++    if( rc!=SQLITE_OK ) return rc;
++    pPg->flags &= ~PGHDR_NEED_READ;
++    sqlite3PcacheMakeDirty(pPg);
++  }
++  if( pPg ){
++    /* No page should ever be explicitly rolled back that is in use, except
++    ** for page 1 which is held in use in order to keep the lock on the
++    ** database active. However such a page may be rolled back as a result
++    ** of an internal error resulting in an automatic call to
++    ** sqlite3PagerRollback().
++    */
++    void *pData;
++    pData = pPg->pData;
++    memcpy(pData, (u8*)aData, pPager->pageSize);
++    pPager->xReiniter(pPg);
++    if( isMainJrnl && (!isSavepnt || *pOffset<=pPager->journalHdr) ){
++      /* If the contents of this page were just restored from the main 
++      ** journal file, then its content must be as they were when the 
++      ** transaction was first opened. In this case we can mark the page
++      ** as clean, since there will be no need to write it out to the
++      ** database.
++      **
++      ** There is one exception to this rule. If the page is being rolled
++      ** back as part of a savepoint (or statement) rollback from an 
++      ** unsynced portion of the main journal file, then it is not safe
++      ** to mark the page as clean. This is because marking the page as
++      ** clean will clear the PGHDR_NEED_SYNC flag. Since the page is
++      ** already in the journal file (recorded in Pager.pInJournal) and
++      ** the PGHDR_NEED_SYNC flag is cleared, if the page is written to
++      ** again within this transaction, it will be marked as dirty but
++      ** the PGHDR_NEED_SYNC flag will not be set. It could then potentially
++      ** be written out into the database file before its journal file
++      ** segment is synced. If a crash occurs during or following this,
++      ** database corruption may ensue.
++      */
++      assert( !pagerUseWal(pPager) );
++      sqlite3PcacheMakeClean(pPg);
++    }
++    pager_set_pagehash(pPg);
++
++    /* If this was page 1, then restore the value of Pager.dbFileVers.
++    ** Do this before any decoding. */
++    if( pgno==1 ){
++      memcpy(&pPager->dbFileVers, &((u8*)pData)[24],sizeof(pPager->dbFileVers));
++    }
++
++    /* Decode the page just read from disk */
++    CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM);
++    sqlite3PcacheRelease(pPg);
+   }
++  return rc;
+ }
+ 
+ /*
+-** Change the page size used by the Pager object. The new page size 
+-** is passed in *pPageSize.
++** Parameter zMaster is the name of a master journal file. A single journal
++** file that referred to the master journal file has just been rolled back.
++** This routine checks if it is possible to delete the master journal file,
++** and does so if it is.
+ **
+-** If the pager is in the error state when this function is called, it
+-** is a no-op. The value returned is the error state error code (i.e. 
+-** one of SQLITE_IOERR, an SQLITE_IOERR_xxx sub-code or SQLITE_FULL).
++** Argument zMaster may point to Pager.pTmpSpace. So that buffer is not 
++** available for use within this function.
+ **
+-** Otherwise, if all of the following are true:
++** When a master journal file is created, it is populated with the names 
++** of all of its child journals, one after another, formatted as utf-8 
++** encoded text. The end of each child journal file is marked with a 
++** nul-terminator byte (0x00). i.e. the entire contents of a master journal
++** file for a transaction involving two databases might be:
+ **
+-**   * the new page size (value of *pPageSize) is valid (a power 
+-**     of two between 512 and SQLITE_MAX_PAGE_SIZE, inclusive), and
++**   "/home/bill/a.db-journal\x00/home/bill/b.db-journal\x00"
+ **
+-**   * there are no outstanding page references, and
++** A master journal file may only be deleted once all of its child 
++** journals have been rolled back.
+ **
+-**   * the database is either not an in-memory database or it is
+-**     an in-memory database that currently consists of zero pages.
++** This function reads the contents of the master-journal file into 
++** memory and loops through each of the child journal names. For
++** each child journal, it checks if:
+ **
+-** then the pager object page size is set to *pPageSize.
++**   * if the child journal exists, and if so
++**   * if the child journal contains a reference to master journal 
++**     file zMaster
+ **
+-** If the page size is changed, then this function uses sqlite3PagerMalloc() 
+-** to obtain a new Pager.pTmpSpace buffer. If this allocation attempt 
+-** fails, SQLITE_NOMEM is returned and the page size remains unchanged. 
+-** In all other cases, SQLITE_OK is returned.
++** If a child journal can be found that matches both of the criteria
++** above, this function returns without doing anything. Otherwise, if
++** no such child journal can be found, file zMaster is deleted from
++** the file-system using sqlite3OsDelete().
+ **
+-** If the page size is not changed, either because one of the enumerated
+-** conditions above is not true, the pager was in error state when this
+-** function was called, or because the memory allocation attempt failed, 
+-** then *pPageSize is set to the old, retained page size before returning.
++** If an IO error within this function, an error code is returned. This
++** function allocates memory by calling sqlite3Malloc(). If an allocation
++** fails, SQLITE_NOMEM is returned. Otherwise, if no IO or malloc errors 
++** occur, SQLITE_OK is returned.
++**
++** TODO: This function allocates a single block of memory to load
++** the entire contents of the master journal file. This could be
++** a couple of kilobytes or so - potentially larger than the page 
++** size.
+ */
+-SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){
+-  int rc = SQLITE_OK;
++static int pager_delmaster(Pager *pPager, const char *zMaster){
++  sqlite3_vfs *pVfs = pPager->pVfs;
++  int rc;                   /* Return code */
++  sqlite3_file *pMaster;    /* Malloc'd master-journal file descriptor */
++  sqlite3_file *pJournal;   /* Malloc'd child-journal file descriptor */
++  char *zMasterJournal = 0; /* Contents of master journal file */
++  i64 nMasterJournal;       /* Size of master journal file */
++  char *zJournal;           /* Pointer to one journal within MJ file */
++  char *zMasterPtr;         /* Space to hold MJ filename from a journal file */
++  int nMasterPtr;           /* Amount of space allocated to zMasterPtr[] */
+ 
+-  /* It is not possible to do a full assert_pager_state() here, as this
+-  ** function may be called from within PagerOpen(), before the state
+-  ** of the Pager object is internally consistent.
+-  **
+-  ** At one point this function returned an error if the pager was in 
+-  ** PAGER_ERROR state. But since PAGER_ERROR state guarantees that
+-  ** there is at least one outstanding page reference, this function
+-  ** is a no-op for that case anyhow.
++  /* Allocate space for both the pJournal and pMaster file descriptors.
++  ** If successful, open the master journal file for reading.
+   */
++  pMaster = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2);
++  pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile);
++  if( !pMaster ){
++    rc = SQLITE_NOMEM;
++  }else{
++    const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL);
++    rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0);
++  }
++  if( rc!=SQLITE_OK ) goto delmaster_out;
+ 
+-  u32 pageSize = *pPageSize;
+-  assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) );
+-  if( (pPager->memDb==0 || pPager->dbSize==0)
+-   && sqlite3PcacheRefCount(pPager->pPCache)==0 
+-   && pageSize && pageSize!=(u32)pPager->pageSize 
+-  ){
+-    char *pNew = NULL;             /* New temp space */
+-    i64 nByte = 0;
++  /* Load the entire master journal file into space obtained from
++  ** sqlite3_malloc() and pointed to by zMasterJournal.   Also obtain
++  ** sufficient space (in zMasterPtr) to hold the names of master
++  ** journal files extracted from regular rollback-journals.
++  */
++  rc = sqlite3OsFileSize(pMaster, &nMasterJournal);
++  if( rc!=SQLITE_OK ) goto delmaster_out;
++  nMasterPtr = pVfs->mxPathname+1;
++  zMasterJournal = sqlite3Malloc(nMasterJournal + nMasterPtr + 1);
++  if( !zMasterJournal ){
++    rc = SQLITE_NOMEM;
++    goto delmaster_out;
++  }
++  zMasterPtr = &zMasterJournal[nMasterJournal+1];
++  rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0);
++  if( rc!=SQLITE_OK ) goto delmaster_out;
++  zMasterJournal[nMasterJournal] = 0;
+ 
+-    if( pPager->eState>PAGER_OPEN && isOpen(pPager->fd) ){
+-      rc = sqlite3OsFileSize(pPager->fd, &nByte);
+-    }
+-    if( rc==SQLITE_OK ){
+-      pNew = (char *)sqlite3PageMalloc(pageSize);
+-      if( !pNew ) rc = SQLITE_NOMEM;
++  zJournal = zMasterJournal;
++  while( (zJournal-zMasterJournal)<nMasterJournal ){
++    int exists;
++    rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS, &exists);
++    if( rc!=SQLITE_OK ){
++      goto delmaster_out;
+     }
++    if( exists ){
++      /* One of the journals pointed to by the master journal exists.
++      ** Open it and check if it points at the master journal. If
++      ** so, return without deleting the master journal file.
++      */
++      int c;
++      int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL);
++      rc = sqlite3OsOpen(pVfs, zJournal, pJournal, flags, 0);
++      if( rc!=SQLITE_OK ){
++        goto delmaster_out;
++      }
++
++      rc = readMasterJournal(pJournal, zMasterPtr, nMasterPtr);
++      sqlite3OsClose(pJournal);
++      if( rc!=SQLITE_OK ){
++        goto delmaster_out;
++      }
+ 
+-    if( rc==SQLITE_OK ){
+-      pager_reset(pPager);
+-      rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
+-    }
+-    if( rc==SQLITE_OK ){
+-      sqlite3PageFree(pPager->pTmpSpace);
+-      pPager->pTmpSpace = pNew;
+-      pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
+-      pPager->pageSize = pageSize;
+-    }else{
+-      sqlite3PageFree(pNew);
++      c = zMasterPtr[0]!=0 && strcmp(zMasterPtr, zMaster)==0;
++      if( c ){
++        /* We have a match. Do not delete the master journal file. */
++        goto delmaster_out;
++      }
+     }
++    zJournal += (sqlite3Strlen30(zJournal)+1);
+   }
++ 
++  sqlite3OsClose(pMaster);
++  rc = sqlite3OsDelete(pVfs, zMaster, 0);
+ 
+-  *pPageSize = pPager->pageSize;
+-  if( rc==SQLITE_OK ){
+-    if( nReserve<0 ) nReserve = pPager->nReserve;
+-    assert( nReserve>=0 && nReserve<1000 );
+-    pPager->nReserve = (i16)nReserve;
+-    pagerReportSize(pPager);
+-    pagerFixMaplimit(pPager);
++delmaster_out:
++  sqlite3_free(zMasterJournal);
++  if( pMaster ){
++    sqlite3OsClose(pMaster);
++    assert( !isOpen(pJournal) );
++    sqlite3_free(pMaster);
+   }
+   return rc;
+ }
+ 
+-/*
+-** Return a pointer to the "temporary page" buffer held internally
+-** by the pager.  This is a buffer that is big enough to hold the
+-** entire content of a database page.  This buffer is used internally
+-** during rollback and will be overwritten whenever a rollback
+-** occurs.  But other modules are free to use it too, as long as
+-** no rollbacks are happening.
+-*/
+-SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager *pPager){
+-  return pPager->pTmpSpace;
+-}
+-
+-/*
+-** Attempt to set the maximum database page count if mxPage is positive. 
+-** Make no changes if mxPage is zero or negative.  And never reduce the
+-** maximum page count below the current size of the database.
+-**
+-** Regardless of mxPage, return the current maximum page count.
+-*/
+-SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager *pPager, int mxPage){
+-  if( mxPage>0 ){
+-    pPager->mxPgno = mxPage;
+-  }
+-  assert( pPager->eState!=PAGER_OPEN );      /* Called only by OP_MaxPgcnt */
+-  assert( pPager->mxPgno>=pPager->dbSize );  /* OP_MaxPgcnt enforces this */
+-  return pPager->mxPgno;
+-}
+ 
+ /*
+-** The following set of routines are used to disable the simulated
+-** I/O error mechanism.  These routines are used to avoid simulated
+-** errors in places where we do not care about errors.
++** This function is used to change the actual size of the database 
++** file in the file-system. This only happens when committing a transaction,
++** or rolling back a transaction (including rolling back a hot-journal).
+ **
+-** Unless -DSQLITE_TEST=1 is used, these routines are all no-ops
+-** and generate no code.
+-*/
+-#ifdef SQLITE_TEST
+-SQLITE_API extern int sqlite3_io_error_pending;
+-SQLITE_API extern int sqlite3_io_error_hit;
+-static int saved_cnt;
+-void disable_simulated_io_errors(void){
+-  saved_cnt = sqlite3_io_error_pending;
+-  sqlite3_io_error_pending = -1;
+-}
+-void enable_simulated_io_errors(void){
+-  sqlite3_io_error_pending = saved_cnt;
+-}
+-#else
+-# define disable_simulated_io_errors()
+-# define enable_simulated_io_errors()
+-#endif
+-
+-/*
+-** Read the first N bytes from the beginning of the file into memory
+-** that pDest points to. 
++** If the main database file is not open, or the pager is not in either
++** DBMOD or OPEN state, this function is a no-op. Otherwise, the size 
++** of the file is changed to nPage pages (nPage*pPager->pageSize bytes). 
++** If the file on disk is currently larger than nPage pages, then use the VFS
++** xTruncate() method to truncate it.
+ **
+-** If the pager was opened on a transient file (zFilename==""), or
+-** opened on a file less than N bytes in size, the output buffer is
+-** zeroed and SQLITE_OK returned. The rationale for this is that this 
+-** function is used to read database headers, and a new transient or
+-** zero sized database has a header than consists entirely of zeroes.
++** Or, it might be the case that the file on disk is smaller than 
++** nPage pages. Some operating system implementations can get confused if 
++** you try to truncate a file to some size that is larger than it 
++** currently is, so detect this case and write a single zero byte to 
++** the end of the new file instead.
+ **
+-** If any IO error apart from SQLITE_IOERR_SHORT_READ is encountered,
+-** the error code is returned to the caller and the contents of the
+-** output buffer undefined.
++** If successful, return SQLITE_OK. If an IO error occurs while modifying
++** the database file, return the error code to the caller.
+ */
+-SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){
++static int pager_truncate(Pager *pPager, Pgno nPage){
+   int rc = SQLITE_OK;
+-  memset(pDest, 0, N);
+-  assert( isOpen(pPager->fd) || pPager->tempFile );
+-
+-  /* This routine is only called by btree immediately after creating
+-  ** the Pager object.  There has not been an opportunity to transition
+-  ** to WAL mode yet.
+-  */
+-  assert( !pagerUseWal(pPager) );
+-
+-  if( isOpen(pPager->fd) ){
+-    IOTRACE(("DBHDR %p 0 %d\n", pPager, N))
+-    rc = sqlite3OsRead(pPager->fd, pDest, N, 0);
+-    if( rc==SQLITE_IOERR_SHORT_READ ){
+-      rc = SQLITE_OK;
++  assert( pPager->eState!=PAGER_ERROR );
++  assert( pPager->eState!=PAGER_READER );
++  
++  if( isOpen(pPager->fd) 
++   && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) 
++  ){
++    i64 currentSize, newSize;
++    int szPage = pPager->pageSize;
++    assert( pPager->eLock==EXCLUSIVE_LOCK );
++    /* TODO: Is it safe to use Pager.dbFileSize here? */
++    rc = sqlite3OsFileSize(pPager->fd, &currentSize);
++    newSize = szPage*(i64)nPage;
++    if( rc==SQLITE_OK && currentSize!=newSize ){
++      if( currentSize>newSize ){
++        rc = sqlite3OsTruncate(pPager->fd, newSize);
++      }else if( (currentSize+szPage)<=newSize ){
++        char *pTmp = pPager->pTmpSpace;
++        memset(pTmp, 0, szPage);
++        testcase( (newSize-szPage) == currentSize );
++        testcase( (newSize-szPage) >  currentSize );
++        rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, newSize-szPage);
++      }
++      if( rc==SQLITE_OK ){
++        pPager->dbFileSize = nPage;
++      }
+     }
+   }
+   return rc;
+ }
+ 
+ /*
+-** This function may only be called when a read-transaction is open on
+-** the pager. It returns the total number of pages in the database.
+-**
+-** However, if the file is between 1 and <page-size> bytes in size, then 
+-** this is considered a 1 page file.
++** Return a sanitized version of the sector-size of OS file pFile. The
++** return value is guaranteed to lie between 32 and MAX_SECTOR_SIZE.
+ */
+-SQLITE_PRIVATE void sqlite3PagerPagecount(Pager *pPager, int *pnPage){
+-  assert( pPager->eState>=PAGER_READER );
+-  assert( pPager->eState!=PAGER_WRITER_FINISHED );
+-  *pnPage = (int)pPager->dbSize;
++SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *pFile){
++  int iRet = sqlite3OsSectorSize(pFile);
++  if( iRet<32 ){
++    iRet = 512;
++  }else if( iRet>MAX_SECTOR_SIZE ){
++    assert( MAX_SECTOR_SIZE>=512 );
++    iRet = MAX_SECTOR_SIZE;
++  }
++  return iRet;
+ }
+ 
+-
+ /*
+-** Try to obtain a lock of type locktype on the database file. If
+-** a similar or greater lock is already held, this function is a no-op
+-** (returning SQLITE_OK immediately).
++** Set the value of the Pager.sectorSize variable for the given
++** pager based on the value returned by the xSectorSize method
++** of the open database file. The sector size will be used 
++** to determine the size and alignment of journal header and 
++** master journal pointers within created journal files.
+ **
+-** Otherwise, attempt to obtain the lock using sqlite3OsLock(). Invoke 
+-** the busy callback if the lock is currently not available. Repeat 
+-** until the busy callback returns false or until the attempt to 
+-** obtain the lock succeeds.
++** For temporary files the effective sector size is always 512 bytes.
+ **
+-** Return SQLITE_OK on success and an error code if we cannot obtain
+-** the lock. If the lock is obtained successfully, set the Pager.state 
+-** variable to locktype before returning.
++** Otherwise, for non-temporary files, the effective sector size is
++** the value returned by the xSectorSize() method rounded up to 32 if
++** it is less than 32, or rounded down to MAX_SECTOR_SIZE if it
++** is greater than MAX_SECTOR_SIZE.
++**
++** If the file has the SQLITE_IOCAP_POWERSAFE_OVERWRITE property, then set
++** the effective sector size to its minimum value (512).  The purpose of
++** pPager->sectorSize is to define the "blast radius" of bytes that
++** might change if a crash occurs while writing to a single byte in
++** that range.  But with POWERSAFE_OVERWRITE, the blast radius is zero
++** (that is what POWERSAFE_OVERWRITE means), so we minimize the sector
++** size.  For backwards compatibility of the rollback journal file format,
++** we cannot reduce the effective sector size below 512.
+ */
+-static int pager_wait_on_lock(Pager *pPager, int locktype){
+-  int rc;                              /* Return code */
+-
+-  /* Check that this is either a no-op (because the requested lock is 
+-  ** already held), or one of the transitions that the busy-handler
+-  ** may be invoked during, according to the comment above
+-  ** sqlite3PagerSetBusyhandler().
+-  */
+-  assert( (pPager->eLock>=locktype)
+-       || (pPager->eLock==NO_LOCK && locktype==SHARED_LOCK)
+-       || (pPager->eLock==RESERVED_LOCK && locktype==EXCLUSIVE_LOCK)
+-  );
++static void setSectorSize(Pager *pPager){
++  assert( isOpen(pPager->fd) || pPager->tempFile );
+ 
+-  do {
+-    rc = pagerLockDb(pPager, locktype);
+-  }while( rc==SQLITE_BUSY && pPager->xBusyHandler(pPager->pBusyHandlerArg) );
+-  return rc;
++  if( pPager->tempFile
++   || (sqlite3OsDeviceCharacteristics(pPager->fd) & 
++              SQLITE_IOCAP_POWERSAFE_OVERWRITE)!=0
++  ){
++    /* Sector size doesn't matter for temporary files. Also, the file
++    ** may not have been opened yet, in which case the OsSectorSize()
++    ** call will segfault. */
++    pPager->sectorSize = 512;
++  }else{
++    pPager->sectorSize = sqlite3SectorSize(pPager->fd);
++  }
+ }
+ 
+ /*
+-** Function assertTruncateConstraint(pPager) checks that one of the 
+-** following is true for all dirty pages currently in the page-cache:
++** Playback the journal and thus restore the database file to
++** the state it was in before we started making changes.  
+ **
+-**   a) The page number is less than or equal to the size of the 
+-**      current database image, in pages, OR
++** The journal file format is as follows: 
+ **
+-**   b) if the page content were written at this time, it would not
+-**      be necessary to write the current content out to the sub-journal
+-**      (as determined by function subjRequiresPage()).
++**  (1)  8 byte prefix.  A copy of aJournalMagic[].
++**  (2)  4 byte big-endian integer which is the number of valid page records
++**       in the journal.  If this value is 0xffffffff, then compute the
++**       number of page records from the journal size.
++**  (3)  4 byte big-endian integer which is the initial value for the 
++**       sanity checksum.
++**  (4)  4 byte integer which is the number of pages to truncate the
++**       database to during a rollback.
++**  (5)  4 byte big-endian integer which is the sector size.  The header
++**       is this many bytes in size.
++**  (6)  4 byte big-endian integer which is the page size.
++**  (7)  zero padding out to the next sector size.
++**  (8)  Zero or more pages instances, each as follows:
++**        +  4 byte page number.
++**        +  pPager->pageSize bytes of data.
++**        +  4 byte checksum
+ **
+-** If the condition asserted by this function were not true, and the
+-** dirty page were to be discarded from the cache via the pagerStress()
+-** routine, pagerStress() would not write the current page content to
+-** the database file. If a savepoint transaction were rolled back after
+-** this happened, the correct behavior would be to restore the current
+-** content of the page. However, since this content is not present in either
+-** the database file or the portion of the rollback journal and 
+-** sub-journal rolled back the content could not be restored and the
+-** database image would become corrupt. It is therefore fortunate that 
+-** this circumstance cannot arise.
+-*/
+-#if defined(SQLITE_DEBUG)
+-static void assertTruncateConstraintCb(PgHdr *pPg){
+-  assert( pPg->flags&PGHDR_DIRTY );
+-  assert( !subjRequiresPage(pPg) || pPg->pgno<=pPg->pPager->dbSize );
+-}
+-static void assertTruncateConstraint(Pager *pPager){
+-  sqlite3PcacheIterateDirty(pPager->pPCache, assertTruncateConstraintCb);
+-}
+-#else
+-# define assertTruncateConstraint(pPager)
+-#endif
+-
+-/*
+-** Truncate the in-memory database file image to nPage pages. This 
+-** function does not actually modify the database file on disk. It 
+-** just sets the internal state of the pager object so that the 
+-** truncation will be done when the current transaction is committed.
++** When we speak of the journal header, we mean the first 7 items above.
++** Each entry in the journal is an instance of the 8th item.
+ **
+-** This function is only called right before committing a transaction.
+-** Once this function has been called, the transaction must either be
+-** rolled back or committed. It is not safe to call this function and
+-** then continue writing to the database.
+-*/
+-SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){
+-  assert( pPager->dbSize>=nPage );
+-  assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
+-  pPager->dbSize = nPage;
+-
+-  /* At one point the code here called assertTruncateConstraint() to
+-  ** ensure that all pages being truncated away by this operation are,
+-  ** if one or more savepoints are open, present in the savepoint 
+-  ** journal so that they can be restored if the savepoint is rolled
+-  ** back. This is no longer necessary as this function is now only
+-  ** called right before committing a transaction. So although the 
+-  ** Pager object may still have open savepoints (Pager.nSavepoint!=0), 
+-  ** they cannot be rolled back. So the assertTruncateConstraint() call
+-  ** is no longer correct. */
+-}
+-
+-
+-/*
+-** This function is called before attempting a hot-journal rollback. It
+-** syncs the journal file to disk, then sets pPager->journalHdr to the
+-** size of the journal file so that the pager_playback() routine knows
+-** that the entire journal file has been synced.
++** Call the value from the second bullet "nRec".  nRec is the number of
++** valid page entries in the journal.  In most cases, you can compute the
++** value of nRec from the size of the journal file.  But if a power
++** failure occurred while the journal was being written, it could be the
++** case that the size of the journal file had already been increased but
++** the extra entries had not yet made it safely to disk.  In such a case,
++** the value of nRec computed from the file size would be too large.  For
++** that reason, we always use the nRec value in the header.
+ **
+-** Syncing a hot-journal to disk before attempting to roll it back ensures 
+-** that if a power-failure occurs during the rollback, the process that
+-** attempts rollback following system recovery sees the same journal
+-** content as this process.
++** If the nRec value is 0xffffffff it means that nRec should be computed
++** from the file size.  This value is used when the user selects the
++** no-sync option for the journal.  A power failure could lead to corruption
++** in this case.  But for things like temporary table (which will be
++** deleted when the power is restored) we don't care.  
+ **
+-** If everything goes as planned, SQLITE_OK is returned. Otherwise, 
+-** an SQLite error code.
++** If the file opened as the journal file is not a well-formed
++** journal file then all pages up to the first corrupted page are rolled
++** back (or no pages if the journal header is corrupted). The journal file
++** is then deleted and SQLITE_OK returned, just as if no corruption had
++** been encountered.
++**
++** If an I/O or malloc() error occurs, the journal-file is not deleted
++** and an error code is returned.
++**
++** The isHot parameter indicates that we are trying to rollback a journal
++** that might be a hot journal.  Or, it could be that the journal is 
++** preserved because of JOURNALMODE_PERSIST or JOURNALMODE_TRUNCATE.
++** If the journal really is hot, reset the pager cache prior rolling
++** back any content.  If the journal is merely persistent, no reset is
++** needed.
+ */
+-static int pagerSyncHotJournal(Pager *pPager){
+-  int rc = SQLITE_OK;
+-  if( !pPager->noSync ){
+-    rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_NORMAL);
++static int pager_playback(Pager *pPager, int isHot){
++  sqlite3_vfs *pVfs = pPager->pVfs;
++  i64 szJ;                 /* Size of the journal file in bytes */
++  u32 nRec;                /* Number of Records in the journal */
++  u32 u;                   /* Unsigned loop counter */
++  Pgno mxPg = 0;           /* Size of the original file in pages */
++  int rc;                  /* Result code of a subroutine */
++  int res = 1;             /* Value returned by sqlite3OsAccess() */
++  char *zMaster = 0;       /* Name of master journal file if any */
++  int needPagerReset;      /* True to reset page prior to first page rollback */
++  int nPlayback = 0;       /* Total number of pages restored from journal */
++
++  /* Figure out how many records are in the journal.  Abort early if
++  ** the journal is empty.
++  */
++  assert( isOpen(pPager->jfd) );
++  rc = sqlite3OsFileSize(pPager->jfd, &szJ);
++  if( rc!=SQLITE_OK ){
++    goto end_playback;
+   }
+-  if( rc==SQLITE_OK ){
+-    rc = sqlite3OsFileSize(pPager->jfd, &pPager->journalHdr);
++
++  /* Read the master journal name from the journal, if it is present.
++  ** If a master journal file name is specified, but the file is not
++  ** present on disk, then the journal is not hot and does not need to be
++  ** played back.
++  **
++  ** TODO: Technically the following is an error because it assumes that
++  ** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that
++  ** (pPager->pageSize >= pPager->pVfs->mxPathname+1). Using os_unix.c,
++  **  mxPathname is 512, which is the same as the minimum allowable value
++  ** for pageSize.
++  */
++  zMaster = pPager->pTmpSpace;
++  rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
++  if( rc==SQLITE_OK && zMaster[0] ){
++    rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res);
+   }
+-  return rc;
+-}
++  zMaster = 0;
++  if( rc!=SQLITE_OK || !res ){
++    goto end_playback;
++  }
++  pPager->journalOff = 0;
++  needPagerReset = isHot;
+ 
+-/*
+-** Obtain a reference to a memory mapped page object for page number pgno. 
+-** The new object will use the pointer pData, obtained from xFetch().
+-** If successful, set *ppPage to point to the new page reference
+-** and return SQLITE_OK. Otherwise, return an SQLite error code and set
+-** *ppPage to zero.
+-**
+-** Page references obtained by calling this function should be released
+-** by calling pagerReleaseMapPage().
+-*/
+-static int pagerAcquireMapPage(
+-  Pager *pPager,                  /* Pager object */
+-  Pgno pgno,                      /* Page number */
+-  void *pData,                    /* xFetch()'d data for this page */
+-  PgHdr **ppPage                  /* OUT: Acquired page object */
+-){
+-  PgHdr *p;                       /* Memory mapped page to return */
+-  
+-  if( pPager->pMmapFreelist ){
+-    *ppPage = p = pPager->pMmapFreelist;
+-    pPager->pMmapFreelist = p->pDirty;
+-    p->pDirty = 0;
+-    memset(p->pExtra, 0, pPager->nExtra);
+-  }else{
+-    *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra);
+-    if( p==0 ){
+-      sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData);
+-      return SQLITE_NOMEM;
++  /* This loop terminates either when a readJournalHdr() or 
++  ** pager_playback_one_page() call returns SQLITE_DONE or an IO error 
++  ** occurs. 
++  */
++  while( 1 ){
++    /* Read the next journal header from the journal file.  If there are
++    ** not enough bytes left in the journal file for a complete header, or
++    ** it is corrupted, then a process must have failed while writing it.
++    ** This indicates nothing more needs to be rolled back.
++    */
++    rc = readJournalHdr(pPager, isHot, szJ, &nRec, &mxPg);
++    if( rc!=SQLITE_OK ){ 
++      if( rc==SQLITE_DONE ){
++        rc = SQLITE_OK;
++      }
++      goto end_playback;
++    }
++
++    /* If nRec is 0xffffffff, then this journal was created by a process
++    ** working in no-sync mode. This means that the rest of the journal
++    ** file consists of pages, there are no more journal headers. Compute
++    ** the value of nRec based on this assumption.
++    */
++    if( nRec==0xffffffff ){
++      assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) );
++      nRec = (int)((szJ - JOURNAL_HDR_SZ(pPager))/JOURNAL_PG_SZ(pPager));
++    }
++
++    /* If nRec is 0 and this rollback is of a transaction created by this
++    ** process and if this is the final header in the journal, then it means
++    ** that this part of the journal was being filled but has not yet been
++    ** synced to disk.  Compute the number of pages based on the remaining
++    ** size of the file.
++    **
++    ** The third term of the test was added to fix ticket #2565.
++    ** When rolling back a hot journal, nRec==0 always means that the next
++    ** chunk of the journal contains zero pages to be rolled back.  But
++    ** when doing a ROLLBACK and the nRec==0 chunk is the last chunk in
++    ** the journal, it means that the journal might contain additional
++    ** pages that need to be rolled back and that the number of pages 
++    ** should be computed based on the journal file size.
++    */
++    if( nRec==0 && !isHot &&
++        pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){
++      nRec = (int)((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager));
++    }
++
++    /* If this is the first header read from the journal, truncate the
++    ** database file back to its original size.
++    */
++    if( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ){
++      rc = pager_truncate(pPager, mxPg);
++      if( rc!=SQLITE_OK ){
++        goto end_playback;
++      }
++      pPager->dbSize = mxPg;
++    }
++
++    /* Copy original pages out of the journal and back into the 
++    ** database file and/or page cache.
++    */
++    for(u=0; u<nRec; u++){
++      if( needPagerReset ){
++        pager_reset(pPager);
++        needPagerReset = 0;
++      }
++      rc = pager_playback_one_page(pPager,&pPager->journalOff,0,1,0);
++      if( rc==SQLITE_OK ){
++        nPlayback++;
++      }else{
++        if( rc==SQLITE_DONE ){
++          pPager->journalOff = szJ;
++          break;
++        }else if( rc==SQLITE_IOERR_SHORT_READ ){
++          /* If the journal has been truncated, simply stop reading and
++          ** processing the journal. This might happen if the journal was
++          ** not completely written and synced prior to a crash.  In that
++          ** case, the database should have never been written in the
++          ** first place so it is OK to simply abandon the rollback. */
++          rc = SQLITE_OK;
++          goto end_playback;
++        }else{
++          /* If we are unable to rollback, quit and return the error
++          ** code.  This will cause the pager to enter the error state
++          ** so that no further harm will be done.  Perhaps the next
++          ** process to come along will be able to rollback the database.
++          */
++          goto end_playback;
++        }
++      }
+     }
+-    p->pExtra = (void *)&p[1];
+-    p->flags = PGHDR_MMAP;
+-    p->nRef = 1;
+-    p->pPager = pPager;
+   }
++  /*NOTREACHED*/
++  assert( 0 );
+ 
+-  assert( p->pExtra==(void *)&p[1] );
+-  assert( p->pPage==0 );
+-  assert( p->flags==PGHDR_MMAP );
+-  assert( p->pPager==pPager );
+-  assert( p->nRef==1 );
+-
+-  p->pgno = pgno;
+-  p->pData = pData;
+-  pPager->nMmapOut++;
+-
+-  return SQLITE_OK;
+-}
+-
+-/*
+-** Release a reference to page pPg. pPg must have been returned by an 
+-** earlier call to pagerAcquireMapPage().
+-*/
+-static void pagerReleaseMapPage(PgHdr *pPg){
+-  Pager *pPager = pPg->pPager;
+-  pPager->nMmapOut--;
+-  pPg->pDirty = pPager->pMmapFreelist;
+-  pPager->pMmapFreelist = pPg;
++end_playback:
++  /* Following a rollback, the database file should be back in its original
++  ** state prior to the start of the transaction, so invoke the
++  ** SQLITE_FCNTL_DB_UNCHANGED file-control method to disable the
++  ** assertion that the transaction counter was modified.
++  */
++#ifdef SQLITE_DEBUG
++  if( pPager->fd->pMethods ){
++    sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0);
++  }
++#endif
+ 
+-  assert( pPager->fd->pMethods->iVersion>=3 );
+-  sqlite3OsUnfetch(pPager->fd, (i64)(pPg->pgno-1)*pPager->pageSize, pPg->pData);
+-}
++  /* If this playback is happening automatically as a result of an IO or 
++  ** malloc error that occurred after the change-counter was updated but 
++  ** before the transaction was committed, then the change-counter 
++  ** modification may just have been reverted. If this happens in exclusive 
++  ** mode, then subsequent transactions performed by the connection will not
++  ** update the change-counter at all. This may lead to cache inconsistency
++  ** problems for other processes at some point in the future. So, just
++  ** in case this has happened, clear the changeCountDone flag now.
++  */
++  pPager->changeCountDone = pPager->tempFile;
+ 
+-/*
+-** Free all PgHdr objects stored in the Pager.pMmapFreelist list.
+-*/
+-static void pagerFreeMapHdrs(Pager *pPager){
+-  PgHdr *p;
+-  PgHdr *pNext;
+-  for(p=pPager->pMmapFreelist; p; p=pNext){
+-    pNext = p->pDirty;
+-    sqlite3_free(p);
++  if( rc==SQLITE_OK ){
++    zMaster = pPager->pTmpSpace;
++    rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
++    testcase( rc!=SQLITE_OK );
++  }
++  if( rc==SQLITE_OK
++   && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN)
++  ){
++    rc = sqlite3PagerSync(pPager, 0);
++  }
++  if( rc==SQLITE_OK ){
++    rc = pager_end_transaction(pPager, zMaster[0]!='\0', 0);
++    testcase( rc!=SQLITE_OK );
++  }
++  if( rc==SQLITE_OK && zMaster[0] && res ){
++    /* If there was a master journal and this routine will return success,
++    ** see if it is possible to delete the master journal.
++    */
++    rc = pager_delmaster(pPager, zMaster);
++    testcase( rc!=SQLITE_OK );
++  }
++  if( isHot && nPlayback ){
++    sqlite3_log(SQLITE_NOTICE_RECOVER_ROLLBACK, "recovered %d pages from %s",
++                nPlayback, pPager->zJournal);
+   }
++
++  /* The Pager.sectorSize variable may have been updated while rolling
++  ** back a journal created by a process with a different sector size
++  ** value. Reset it to the correct value for this process.
++  */
++  setSectorSize(pPager);
++  return rc;
+ }
+ 
+ 
+ /*
+-** Shutdown the page cache.  Free all memory and close all files.
++** Read the content for page pPg out of the database file and into 
++** pPg->pData. A shared lock or greater must be held on the database
++** file before this function is called.
+ **
+-** If a transaction was in progress when this routine is called, that
+-** transaction is rolled back.  All outstanding pages are invalidated
+-** and their memory is freed.  Any attempt to use a page associated
+-** with this page cache after this function returns will likely
+-** result in a coredump.
++** If page 1 is read, then the value of Pager.dbFileVers[] is set to
++** the value read from the database file.
+ **
+-** This function always succeeds. If a transaction is active an attempt
+-** is made to roll it back. If an error occurs during the rollback 
+-** a hot journal may be left in the filesystem but no error is returned
+-** to the caller.
++** If an IO error occurs, then the IO error is returned to the caller.
++** Otherwise, SQLITE_OK is returned.
+ */
+-SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager){
+-  u8 *pTmp = (u8 *)pPager->pTmpSpace;
++static int readDbPage(PgHdr *pPg, u32 iFrame){
++  Pager *pPager = pPg->pPager; /* Pager object associated with page pPg */
++  Pgno pgno = pPg->pgno;       /* Page number to read */
++  int rc = SQLITE_OK;          /* Return code */
++  int pgsz = pPager->pageSize; /* Number of bytes to read */
++
++  assert( pPager->eState>=PAGER_READER && !MEMDB );
++  assert( isOpen(pPager->fd) );
+ 
+-  assert( assert_pager_state(pPager) );
+-  disable_simulated_io_errors();
+-  sqlite3BeginBenignMalloc();
+-  pagerFreeMapHdrs(pPager);
+-  /* pPager->errCode = 0; */
+-  pPager->exclusiveMode = 0;
+ #ifndef SQLITE_OMIT_WAL
+-  sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, pPager->pageSize, pTmp);
+-  pPager->pWal = 0;
++  if( iFrame ){
++    /* Try to pull the page from the write-ahead log. */
++    rc = sqlite3WalReadFrame(pPager->pWal, iFrame, pgsz, pPg->pData);
++  }else
+ #endif
+-  pager_reset(pPager);
+-  if( MEMDB ){
+-    pager_unlock(pPager);
+-  }else{
+-    /* If it is open, sync the journal file before calling UnlockAndRollback.
+-    ** If this is not done, then an unsynced portion of the open journal 
+-    ** file may be played back into the database. If a power failure occurs 
+-    ** while this is happening, the database could become corrupt.
+-    **
+-    ** If an error occurs while trying to sync the journal, shift the pager
+-    ** into the ERROR state. This causes UnlockAndRollback to unlock the
+-    ** database and close the journal file without attempting to roll it
+-    ** back or finalize it. The next database user will have to do hot-journal
+-    ** rollback before accessing the database file.
+-    */
+-    if( isOpen(pPager->jfd) ){
+-      pager_error(pPager, pagerSyncHotJournal(pPager));
++  {
++    i64 iOffset = (pgno-1)*(i64)pPager->pageSize;
++    rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset);
++    if( rc==SQLITE_IOERR_SHORT_READ ){
++      rc = SQLITE_OK;
+     }
+-    pagerUnlockAndRollback(pPager);
+   }
+-  sqlite3EndBenignMalloc();
+-  enable_simulated_io_errors();
+-  PAGERTRACE(("CLOSE %d\n", PAGERID(pPager)));
+-  IOTRACE(("CLOSE %p\n", pPager))
+-  sqlite3OsClose(pPager->jfd);
+-  sqlite3OsClose(pPager->fd);
+-  sqlite3PageFree(pTmp);
+-  sqlite3PcacheClose(pPager->pPCache);
+ 
+-#ifdef SQLITE_HAS_CODEC
+-  if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
+-#endif
++  if( pgno==1 ){
++    if( rc ){
++      /* If the read is unsuccessful, set the dbFileVers[] to something
++      ** that will never be a valid file version.  dbFileVers[] is a copy
++      ** of bytes 24..39 of the database.  Bytes 28..31 should always be
++      ** zero or the size of the database in page. Bytes 32..35 and 35..39
++      ** should be page numbers which are never 0xffffffff.  So filling
++      ** pPager->dbFileVers[] with all 0xff bytes should suffice.
++      **
++      ** For an encrypted database, the situation is more complex:  bytes
++      ** 24..39 of the database are white noise.  But the probability of
++      ** white noise equaling 16 bytes of 0xff is vanishingly small so
++      ** we should still be ok.
++      */
++      memset(pPager->dbFileVers, 0xff, sizeof(pPager->dbFileVers));
++    }else{
++      u8 *dbFileVers = &((u8*)pPg->pData)[24];
++      memcpy(&pPager->dbFileVers, dbFileVers, sizeof(pPager->dbFileVers));
++    }
++  }
++  CODEC1(pPager, pPg->pData, pgno, 3, rc = SQLITE_NOMEM);
+ 
+-  assert( !pPager->aSavepoint && !pPager->pInJournal );
+-  assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) );
++  PAGER_INCR(sqlite3_pager_readdb_count);
++  PAGER_INCR(pPager->nRead);
++  IOTRACE(("PGIN %p %d\n", pPager, pgno));
++  PAGERTRACE(("FETCH %d page %d hash(%08x)\n",
++               PAGERID(pPager), pgno, pager_pagehash(pPg)));
+ 
+-  sqlite3_free(pPager);
+-  return SQLITE_OK;
++  return rc;
+ }
+ 
+-#if !defined(NDEBUG) || defined(SQLITE_TEST)
+ /*
+-** Return the page number for page pPg.
++** Update the value of the change-counter at offsets 24 and 92 in
++** the header and the sqlite version number at offset 96.
++**
++** This is an unconditional update.  See also the pager_incr_changecounter()
++** routine which only updates the change-counter if the update is actually
++** needed, as determined by the pPager->changeCountDone state variable.
+ */
+-SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage *pPg){
+-  return pPg->pgno;
+-}
+-#endif
++static void pager_write_changecounter(PgHdr *pPg){
++  u32 change_counter;
+ 
+-/*
+-** Increment the reference count for page pPg.
+-*/
+-SQLITE_PRIVATE void sqlite3PagerRef(DbPage *pPg){
+-  sqlite3PcacheRef(pPg);
++  /* Increment the value just read and write it back to byte 24. */
++  change_counter = sqlite3Get4byte((u8*)pPg->pPager->dbFileVers)+1;
++  put32bits(((char*)pPg->pData)+24, change_counter);
++
++  /* Also store the SQLite version number in bytes 96..99 and in
++  ** bytes 92..95 store the change counter for which the version number
++  ** is valid. */
++  put32bits(((char*)pPg->pData)+92, change_counter);
++  put32bits(((char*)pPg->pData)+96, SQLITE_VERSION_NUMBER);
+ }
+ 
++#ifndef SQLITE_OMIT_WAL
+ /*
+-** Sync the journal. In other words, make sure all the pages that have
+-** been written to the journal have actually reached the surface of the
+-** disk and can be restored in the event of a hot-journal rollback.
+-**
+-** If the Pager.noSync flag is set, then this function is a no-op.
+-** Otherwise, the actions required depend on the journal-mode and the 
+-** device characteristics of the file-system, as follows:
+-**
+-**   * If the journal file is an in-memory journal file, no action need
+-**     be taken.
+-**
+-**   * Otherwise, if the device does not support the SAFE_APPEND property,
+-**     then the nRec field of the most recently written journal header
+-**     is updated to contain the number of journal records that have
+-**     been written following it. If the pager is operating in full-sync
+-**     mode, then the journal file is synced before this field is updated.
+-**
+-**   * If the device does not support the SEQUENTIAL property, then 
+-**     journal file is synced.
+-**
+-** Or, in pseudo-code:
+-**
+-**   if( NOT <in-memory journal> ){
+-**     if( NOT SAFE_APPEND ){
+-**       if( <full-sync mode> ) xSync(<journal file>);
+-**       <update nRec field>
+-**     } 
+-**     if( NOT SEQUENTIAL ) xSync(<journal file>);
+-**   }
++** This function is invoked once for each page that has already been 
++** written into the log file when a WAL transaction is rolled back.
++** Parameter iPg is the page number of said page. The pCtx argument 
++** is actually a pointer to the Pager structure.
+ **
+-** If successful, this routine clears the PGHDR_NEED_SYNC flag of every 
+-** page currently held in memory before returning SQLITE_OK. If an IO
+-** error is encountered, then the IO error code is returned to the caller.
++** If page iPg is present in the cache, and has no outstanding references,
++** it is discarded. Otherwise, if there are one or more outstanding
++** references, the page content is reloaded from the database. If the
++** attempt to reload content from the database is required and fails, 
++** return an SQLite error code. Otherwise, SQLITE_OK.
+ */
+-static int syncJournal(Pager *pPager, int newHdr){
+-  int rc;                         /* Return code */
+-
+-  assert( pPager->eState==PAGER_WRITER_CACHEMOD
+-       || pPager->eState==PAGER_WRITER_DBMOD
+-  );
+-  assert( assert_pager_state(pPager) );
+-  assert( !pagerUseWal(pPager) );
+-
+-  rc = sqlite3PagerExclusiveLock(pPager);
+-  if( rc!=SQLITE_OK ) return rc;
+-
+-  if( !pPager->noSync ){
+-    assert( !pPager->tempFile );
+-    if( isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){
+-      const int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
+-      assert( isOpen(pPager->jfd) );
+-
+-      if( 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){
+-        /* This block deals with an obscure problem. If the last connection
+-        ** that wrote to this database was operating in persistent-journal
+-        ** mode, then the journal file may at this point actually be larger
+-        ** than Pager.journalOff bytes. If the next thing in the journal
+-        ** file happens to be a journal-header (written as part of the
+-        ** previous connection's transaction), and a crash or power-failure 
+-        ** occurs after nRec is updated but before this connection writes 
+-        ** anything else to the journal file (or commits/rolls back its 
+-        ** transaction), then SQLite may become confused when doing the 
+-        ** hot-journal rollback following recovery. It may roll back all
+-        ** of this connections data, then proceed to rolling back the old,
+-        ** out-of-date data that follows it. Database corruption.
+-        **
+-        ** To work around this, if the journal file does appear to contain
+-        ** a valid header following Pager.journalOff, then write a 0x00
+-        ** byte to the start of it to prevent it from being recognized.
+-        **
+-        ** Variable iNextHdrOffset is set to the offset at which this
+-        ** problematic header will occur, if it exists. aMagic is used 
+-        ** as a temporary buffer to inspect the first couple of bytes of
+-        ** the potential journal header.
+-        */
+-        i64 iNextHdrOffset;
+-        u8 aMagic[8];
+-        u8 zHeader[sizeof(aJournalMagic)+4];
+-
+-        memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic));
+-        put32bits(&zHeader[sizeof(aJournalMagic)], pPager->nRec);
+-
+-        iNextHdrOffset = journalHdrOffset(pPager);
+-        rc = sqlite3OsRead(pPager->jfd, aMagic, 8, iNextHdrOffset);
+-        if( rc==SQLITE_OK && 0==memcmp(aMagic, aJournalMagic, 8) ){
+-          static const u8 zerobyte = 0;
+-          rc = sqlite3OsWrite(pPager->jfd, &zerobyte, 1, iNextHdrOffset);
+-        }
+-        if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
+-          return rc;
+-        }
++static int pagerUndoCallback(void *pCtx, Pgno iPg){
++  int rc = SQLITE_OK;
++  Pager *pPager = (Pager *)pCtx;
++  PgHdr *pPg;
+ 
+-        /* Write the nRec value into the journal file header. If in
+-        ** full-synchronous mode, sync the journal first. This ensures that
+-        ** all data has really hit the disk before nRec is updated to mark
+-        ** it as a candidate for rollback.
+-        **
+-        ** This is not required if the persistent media supports the
+-        ** SAFE_APPEND property. Because in this case it is not possible 
+-        ** for garbage data to be appended to the file, the nRec field
+-        ** is populated with 0xFFFFFFFF when the journal header is written
+-        ** and never needs to be updated.
+-        */
+-        if( pPager->fullSync && 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){
+-          PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager)));
+-          IOTRACE(("JSYNC %p\n", pPager))
+-          rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags);
+-          if( rc!=SQLITE_OK ) return rc;
+-        }
+-        IOTRACE(("JHDR %p %lld\n", pPager, pPager->journalHdr));
+-        rc = sqlite3OsWrite(
+-            pPager->jfd, zHeader, sizeof(zHeader), pPager->journalHdr
+-        );
+-        if( rc!=SQLITE_OK ) return rc;
+-      }
+-      if( 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){
+-        PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager)));
+-        IOTRACE(("JSYNC %p\n", pPager))
+-        rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags| 
+-          (pPager->syncFlags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0)
+-        );
+-        if( rc!=SQLITE_OK ) return rc;
++  assert( pagerUseWal(pPager) );
++  pPg = sqlite3PagerLookup(pPager, iPg);
++  if( pPg ){
++    if( sqlite3PcachePageRefcount(pPg)==1 ){
++      sqlite3PcacheDrop(pPg);
++    }else{
++      u32 iFrame = 0;
++      rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame);
++      if( rc==SQLITE_OK ){
++        rc = readDbPage(pPg, iFrame);
+       }
+-
+-      pPager->journalHdr = pPager->journalOff;
+-      if( newHdr && 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){
+-        pPager->nRec = 0;
+-        rc = writeJournalHdr(pPager);
+-        if( rc!=SQLITE_OK ) return rc;
++      if( rc==SQLITE_OK ){
++        pPager->xReiniter(pPg);
+       }
+-    }else{
+-      pPager->journalHdr = pPager->journalOff;
++      sqlite3PagerUnrefNotNull(pPg);
+     }
+   }
+ 
+-  /* Unless the pager is in noSync mode, the journal file was just 
+-  ** successfully synced. Either way, clear the PGHDR_NEED_SYNC flag on 
+-  ** all pages.
++  /* Normally, if a transaction is rolled back, any backup processes are
++  ** updated as data is copied out of the rollback journal and into the
++  ** database. This is not generally possible with a WAL database, as
++  ** rollback involves simply truncating the log file. Therefore, if one
++  ** or more frames have already been written to the log (and therefore 
++  ** also copied into the backup databases) as part of this transaction,
++  ** the backups must be restarted.
+   */
+-  sqlite3PcacheClearSyncFlags(pPager->pPCache);
+-  pPager->eState = PAGER_WRITER_DBMOD;
+-  assert( assert_pager_state(pPager) );
+-  return SQLITE_OK;
++  sqlite3BackupRestart(pPager->pBackup);
++
++  return rc;
+ }
+ 
+ /*
+-** The argument is the first in a linked list of dirty pages connected
+-** by the PgHdr.pDirty pointer. This function writes each one of the
+-** in-memory pages in the list to the database file. The argument may
+-** be NULL, representing an empty list. In this case this function is
+-** a no-op.
+-**
+-** The pager must hold at least a RESERVED lock when this function
+-** is called. Before writing anything to the database file, this lock
+-** is upgraded to an EXCLUSIVE lock. If the lock cannot be obtained,
+-** SQLITE_BUSY is returned and no data is written to the database file.
+-** 
+-** If the pager is a temp-file pager and the actual file-system file
+-** is not yet open, it is created and opened before any data is 
+-** written out.
+-**
+-** Once the lock has been upgraded and, if necessary, the file opened,
+-** the pages are written out to the database file in list order. Writing
+-** a page is skipped if it meets either of the following criteria:
+-**
+-**   * The page number is greater than Pager.dbSize, or
+-**   * The PGHDR_DONT_WRITE flag is set on the page.
+-**
+-** If writing out a page causes the database file to grow, Pager.dbFileSize
+-** is updated accordingly. If page 1 is written out, then the value cached
+-** in Pager.dbFileVers[] is updated to match the new value stored in
+-** the database file.
+-**
+-** If everything is successful, SQLITE_OK is returned. If an IO error 
+-** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot
+-** be obtained, SQLITE_BUSY is returned.
++** This function is called to rollback a transaction on a WAL database.
+ */
+-static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
+-  int rc = SQLITE_OK;                  /* Return code */
+-
+-  /* This function is only called for rollback pagers in WRITER_DBMOD state. */
+-  assert( !pagerUseWal(pPager) );
+-  assert( pPager->eState==PAGER_WRITER_DBMOD );
+-  assert( pPager->eLock==EXCLUSIVE_LOCK );
+-
+-  /* If the file is a temp-file has not yet been opened, open it now. It
+-  ** is not possible for rc to be other than SQLITE_OK if this branch
+-  ** is taken, as pager_wait_on_lock() is a no-op for temp-files.
+-  */
+-  if( !isOpen(pPager->fd) ){
+-    assert( pPager->tempFile && rc==SQLITE_OK );
+-    rc = pagerOpentemp(pPager, pPager->fd, pPager->vfsFlags);
+-  }
++static int pagerRollbackWal(Pager *pPager){
++  int rc;                         /* Return Code */
++  PgHdr *pList;                   /* List of dirty pages to revert */
+ 
+-  /* Before the first write, give the VFS a hint of what the final
+-  ** file size will be.
++  /* For all pages in the cache that are currently dirty or have already
++  ** been written (but not committed) to the log file, do one of the 
++  ** following:
++  **
++  **   + Discard the cached page (if refcount==0), or
++  **   + Reload page content from the database (if refcount>0).
+   */
+-  assert( rc!=SQLITE_OK || isOpen(pPager->fd) );
+-  if( rc==SQLITE_OK 
+-   && pPager->dbHintSize<pPager->dbSize
+-   && (pList->pDirty || pList->pgno>pPager->dbHintSize)
+-  ){
+-    sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize;
+-    sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile);
+-    pPager->dbHintSize = pPager->dbSize;
++  pPager->dbSize = pPager->dbOrigSize;
++  rc = sqlite3WalUndo(pPager->pWal, pagerUndoCallback, (void *)pPager);
++  pList = sqlite3PcacheDirtyList(pPager->pPCache);
++  while( pList && rc==SQLITE_OK ){
++    PgHdr *pNext = pList->pDirty;
++    rc = pagerUndoCallback((void *)pPager, pList->pgno);
++    pList = pNext;
+   }
+ 
+-  while( rc==SQLITE_OK && pList ){
+-    Pgno pgno = pList->pgno;
+-
+-    /* If there are dirty pages in the page cache with page numbers greater
+-    ** than Pager.dbSize, this means sqlite3PagerTruncateImage() was called to
+-    ** make the file smaller (presumably by auto-vacuum code). Do not write
+-    ** any such pages to the file.
+-    **
+-    ** Also, do not write out any page that has the PGHDR_DONT_WRITE flag
+-    ** set (set by sqlite3PagerDontWrite()).
+-    */
+-    if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){
+-      i64 offset = (pgno-1)*(i64)pPager->pageSize;   /* Offset to write */
+-      char *pData;                                   /* Data to write */    
+-
+-      assert( (pList->flags&PGHDR_NEED_SYNC)==0 );
+-      if( pList->pgno==1 ) pager_write_changecounter(pList);
+-
+-      /* Encode the database */
+-      CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData);
++  return rc;
++}
+ 
+-      /* Write out the page data. */
+-      rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
++/*
++** This function is a wrapper around sqlite3WalFrames(). As well as logging
++** the contents of the list of pages headed by pList (connected by pDirty),
++** this function notifies any active backup processes that the pages have
++** changed. 
++**
++** The list of pages passed into this routine is always sorted by page number.
++** Hence, if page 1 appears anywhere on the list, it will be the first page.
++*/ 
++static int pagerWalFrames(
++  Pager *pPager,                  /* Pager object */
++  PgHdr *pList,                   /* List of frames to log */
++  Pgno nTruncate,                 /* Database size after this commit */
++  int isCommit                    /* True if this is a commit */
 +){
-+  sqlite3PagerSetCodec(pPager, xCodec, xCodecSizeChng, xCodecFree, pCodec); 
++  int rc;                         /* Return code */
++  int nList;                      /* Number of pages in pList */
++  PgHdr *p;                       /* For looping over pages */
+ 
+-      /* If page 1 was just written, update Pager.dbFileVers to match
+-      ** the value now stored in the database file. If writing this 
+-      ** page caused the database file to grow, update dbFileSize. 
+-      */
+-      if( pgno==1 ){
+-        memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers));
+-      }
+-      if( pgno>pPager->dbFileSize ){
+-        pPager->dbFileSize = pgno;
+-      }
+-      pPager->aStat[PAGER_STAT_WRITE]++;
++  assert( pPager->pWal );
++  assert( pList );
++#ifdef SQLITE_DEBUG
++  /* Verify that the page list is in accending order */
++  for(p=pList; p && p->pDirty; p=p->pDirty){
++    assert( p->pgno < p->pDirty->pgno );
++  }
++#endif
+ 
+-      /* Update any backup objects copying the contents of this pager. */
+-      sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)pList->pData);
++  assert( pList->pDirty==0 || isCommit );
++  if( isCommit ){
++    /* If a WAL transaction is being committed, there is no point in writing
++    ** any pages with page numbers greater than nTruncate into the WAL file.
++    ** They will never be read by any client. So remove them from the pDirty
++    ** list here. */
++    PgHdr **ppNext = &pList;
++    nList = 0;
++    for(p=pList; (*ppNext = p)!=0; p=p->pDirty){
++      if( p->pgno<=nTruncate ){
++        ppNext = &p->pDirty;
++        nList++;
++      }
++    }
++    assert( pList );
++  }else{
++    nList = 1;
++  }
++  pPager->aStat[PAGER_STAT_WRITE] += nList;
+ 
+-      PAGERTRACE(("STORE %d page %d hash(%08x)\n",
+-                   PAGERID(pPager), pgno, pager_pagehash(pList)));
+-      IOTRACE(("PGOUT %p %d\n", pPager, pgno));
+-      PAGER_INCR(sqlite3_pager_writedb_count);
+-    }else{
+-      PAGERTRACE(("NOSTORE %d page %d\n", PAGERID(pPager), pgno));
++  if( pList->pgno==1 ) pager_write_changecounter(pList);
++  rc = sqlite3WalFrames(pPager->pWal, 
++      pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags
++  );
++  if( rc==SQLITE_OK && pPager->pBackup ){
++    for(p=pList; p; p=p->pDirty){
++      sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData);
+     }
+-    pager_set_pagehash(pList);
+-    pList = pList->pDirty;
+   }
+ 
++#ifdef SQLITE_CHECK_PAGES
++  pList = sqlite3PcacheDirtyList(pPager->pPCache);
++  for(p=pList; p; p=p->pDirty){
++    pager_set_pagehash(p);
++  }
++#endif
++
+   return rc;
+ }
+ 
+ /*
+-** Ensure that the sub-journal file is open. If it is already open, this 
+-** function is a no-op.
++** Begin a read transaction on the WAL.
+ **
+-** SQLITE_OK is returned if everything goes according to plan. An 
+-** SQLITE_IOERR_XXX error code is returned if a call to sqlite3OsOpen() 
+-** fails.
++** This routine used to be called "pagerOpenSnapshot()" because it essentially
++** makes a snapshot of the database at the current point in time and preserves
++** that snapshot for use by the reader in spite of concurrently changes by
++** other writers or checkpointers.
+ */
+-static int openSubJournal(Pager *pPager){
+-  int rc = SQLITE_OK;
+-  if( !isOpen(pPager->sjfd) ){
+-    if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){
+-      sqlite3MemJournalOpen(pPager->sjfd);
+-    }else{
+-      rc = pagerOpentemp(pPager, pPager->sjfd, SQLITE_OPEN_SUBJOURNAL);
+-    }
++static int pagerBeginReadTransaction(Pager *pPager){
++  int rc;                         /* Return code */
++  int changed = 0;                /* True if cache must be reset */
++
++  assert( pagerUseWal(pPager) );
++  assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER );
++
++  /* sqlite3WalEndReadTransaction() was not called for the previous
++  ** transaction in locking_mode=EXCLUSIVE.  So call it now.  If we
++  ** are in locking_mode=NORMAL and EndRead() was previously called,
++  ** the duplicate call is harmless.
++  */
++  sqlite3WalEndReadTransaction(pPager->pWal);
++
++  rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed);
++  if( rc!=SQLITE_OK || changed ){
++    pager_reset(pPager);
++    if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0);
+   }
++
+   return rc;
+ }
++#endif
+ 
+ /*
+-** Append a record of the current state of page pPg to the sub-journal. 
+-** It is the callers responsibility to use subjRequiresPage() to check 
+-** that it is really required before calling this function.
+-**
+-** If successful, set the bit corresponding to pPg->pgno in the bitvecs
+-** for all open savepoints before returning.
++** This function is called as part of the transition from PAGER_OPEN
++** to PAGER_READER state to determine the size of the database file
++** in pages (assuming the page size currently stored in Pager.pageSize).
+ **
+-** This function returns SQLITE_OK if everything is successful, an IO
+-** error code if the attempt to write to the sub-journal fails, or 
+-** SQLITE_NOMEM if a malloc fails while setting a bit in a savepoint
+-** bitvec.
++** If no error occurs, SQLITE_OK is returned and the size of the database
++** in pages is stored in *pnPage. Otherwise, an error code (perhaps
++** SQLITE_IOERR_FSTAT) is returned and *pnPage is left unmodified.
+ */
+-static int subjournalPage(PgHdr *pPg){
+-  int rc = SQLITE_OK;
+-  Pager *pPager = pPg->pPager;
+-  if( pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
++static int pagerPagecount(Pager *pPager, Pgno *pnPage){
++  Pgno nPage;                     /* Value to return via *pnPage */
+ 
+-    /* Open the sub-journal, if it has not already been opened */
+-    assert( pPager->useJournal );
+-    assert( isOpen(pPager->jfd) || pagerUseWal(pPager) );
+-    assert( isOpen(pPager->sjfd) || pPager->nSubRec==0 );
+-    assert( pagerUseWal(pPager) 
+-         || pageInJournal(pPager, pPg) 
+-         || pPg->pgno>pPager->dbOrigSize 
+-    );
+-    rc = openSubJournal(pPager);
++  /* Query the WAL sub-system for the database size. The WalDbsize()
++  ** function returns zero if the WAL is not open (i.e. Pager.pWal==0), or
++  ** if the database size is not available. The database size is not
++  ** available from the WAL sub-system if the log file is empty or
++  ** contains no valid committed transactions.
++  */
++  assert( pPager->eState==PAGER_OPEN );
++  assert( pPager->eLock>=SHARED_LOCK );
++  nPage = sqlite3WalDbsize(pPager->pWal);
+ 
+-    /* If the sub-journal was opened successfully (or was already open),
+-    ** write the journal record into the file.  */
+-    if( rc==SQLITE_OK ){
+-      void *pData = pPg->pData;
+-      i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize);
+-      char *pData2;
+-  
+-      CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
+-      PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
+-      rc = write32bits(pPager->sjfd, offset, pPg->pgno);
+-      if( rc==SQLITE_OK ){
+-        rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4);
++  /* If the database size was not available from the WAL sub-system,
++  ** determine it based on the size of the database file. If the size
++  ** of the database file is not an integer multiple of the page-size,
++  ** round down to the nearest page. Except, any file larger than 0
++  ** bytes in size is considered to contain at least one page.
++  */
++  if( nPage==0 ){
++    i64 n = 0;                    /* Size of db file in bytes */
++    assert( isOpen(pPager->fd) || pPager->tempFile );
++    if( isOpen(pPager->fd) ){
++      int rc = sqlite3OsFileSize(pPager->fd, &n);
++      if( rc!=SQLITE_OK ){
++        return rc;
+       }
+     }
++    nPage = (Pgno)((n+pPager->pageSize-1) / pPager->pageSize);
+   }
+-  if( rc==SQLITE_OK ){
+-    pPager->nSubRec++;
+-    assert( pPager->nSavepoint>0 );
+-    rc = addToSavepointBitvecs(pPager, pPg->pgno);
++
++  /* If the current number of pages in the file is greater than the
++  ** configured maximum pager number, increase the allowed limit so
++  ** that the file can be read.
++  */
++  if( nPage>pPager->mxPgno ){
++    pPager->mxPgno = (Pgno)nPage;
+   }
+-  return rc;
++
++  *pnPage = nPage;
++  return SQLITE_OK;
+ }
+ 
++#ifndef SQLITE_OMIT_WAL
+ /*
+-** This function is called by the pcache layer when it has reached some
+-** soft memory limit. The first argument is a pointer to a Pager object
+-** (cast as a void*). The pager is always 'purgeable' (not an in-memory
+-** database). The second argument is a reference to a page that is 
+-** currently dirty but has no outstanding references. The page
+-** is always associated with the Pager object passed as the first 
+-** argument.
++** Check if the *-wal file that corresponds to the database opened by pPager
++** exists if the database is not empy, or verify that the *-wal file does
++** not exist (by deleting it) if the database file is empty.
+ **
+-** The job of this function is to make pPg clean by writing its contents
+-** out to the database file, if possible. This may involve syncing the
+-** journal file. 
++** If the database is not empty and the *-wal file exists, open the pager
++** in WAL mode.  If the database is empty or if no *-wal file exists and
++** if no error occurs, make sure Pager.journalMode is not set to
++** PAGER_JOURNALMODE_WAL.
+ **
+-** If successful, sqlite3PcacheMakeClean() is called on the page and
+-** SQLITE_OK returned. If an IO error occurs while trying to make the
+-** page clean, the IO error code is returned. If the page cannot be
+-** made clean for some other reason, but no error occurs, then SQLITE_OK
+-** is returned by sqlite3PcacheMakeClean() is not called.
++** Return SQLITE_OK or an error code.
++**
++** The caller must hold a SHARED lock on the database file to call this
++** function. Because an EXCLUSIVE lock on the db file is required to delete 
++** a WAL on a none-empty database, this ensures there is no race condition 
++** between the xAccess() below and an xDelete() being executed by some 
++** other connection.
+ */
+-static int pagerStress(void *p, PgHdr *pPg){
+-  Pager *pPager = (Pager *)p;
++static int pagerOpenWalIfPresent(Pager *pPager){
+   int rc = SQLITE_OK;
++  assert( pPager->eState==PAGER_OPEN );
++  assert( pPager->eLock>=SHARED_LOCK );
+ 
+-  assert( pPg->pPager==pPager );
+-  assert( pPg->flags&PGHDR_DIRTY );
+-
+-  /* The doNotSpill NOSYNC bit is set during times when doing a sync of
+-  ** journal (and adding a new header) is not allowed.  This occurs
+-  ** during calls to sqlite3PagerWrite() while trying to journal multiple
+-  ** pages belonging to the same sector.
+-  **
+-  ** The doNotSpill ROLLBACK and OFF bits inhibits all cache spilling
+-  ** regardless of whether or not a sync is required.  This is set during
+-  ** a rollback or by user request, respectively.
+-  **
+-  ** Spilling is also prohibited when in an error state since that could
+-  ** lead to database corruption.   In the current implementation it 
+-  ** is impossible for sqlite3PcacheFetch() to be called with createFlag==3
+-  ** while in the error state, hence it is impossible for this routine to
+-  ** be called in the error state.  Nevertheless, we include a NEVER()
+-  ** test for the error state as a safeguard against future changes.
+-  */
+-  if( NEVER(pPager->errCode) ) return SQLITE_OK;
+-  testcase( pPager->doNotSpill & SPILLFLAG_ROLLBACK );
+-  testcase( pPager->doNotSpill & SPILLFLAG_OFF );
+-  testcase( pPager->doNotSpill & SPILLFLAG_NOSYNC );
+-  if( pPager->doNotSpill
+-   && ((pPager->doNotSpill & (SPILLFLAG_ROLLBACK|SPILLFLAG_OFF))!=0
+-      || (pPg->flags & PGHDR_NEED_SYNC)!=0)
+-  ){
+-    return SQLITE_OK;
+-  }
++  if( !pPager->tempFile ){
++    int isWal;                    /* True if WAL file exists */
++    Pgno nPage;                   /* Size of the database file */
+ 
+-  pPg->pDirty = 0;
+-  if( pagerUseWal(pPager) ){
+-    /* Write a single frame for this page to the log. */
+-    if( subjRequiresPage(pPg) ){ 
+-      rc = subjournalPage(pPg); 
+-    }
+-    if( rc==SQLITE_OK ){
+-      rc = pagerWalFrames(pPager, pPg, 0, 0);
+-    }
+-  }else{
+-  
+-    /* Sync the journal file if required. */
+-    if( pPg->flags&PGHDR_NEED_SYNC 
+-     || pPager->eState==PAGER_WRITER_CACHEMOD
+-    ){
+-      rc = syncJournal(pPager, 1);
+-    }
+-  
+-    /* If the page number of this page is larger than the current size of
+-    ** the database image, it may need to be written to the sub-journal.
+-    ** This is because the call to pager_write_pagelist() below will not
+-    ** actually write data to the file in this case.
+-    **
+-    ** Consider the following sequence of events:
+-    **
+-    **   BEGIN;
+-    **     <journal page X>
+-    **     <modify page X>
+-    **     SAVEPOINT sp;
+-    **       <shrink database file to Y pages>
+-    **       pagerStress(page X)
+-    **     ROLLBACK TO sp;
+-    **
+-    ** If (X>Y), then when pagerStress is called page X will not be written
+-    ** out to the database file, but will be dropped from the cache. Then,
+-    ** following the "ROLLBACK TO sp" statement, reading page X will read
+-    ** data from the database file. This will be the copy of page X as it
+-    ** was when the transaction started, not as it was when "SAVEPOINT sp"
+-    ** was executed.
+-    **
+-    ** The solution is to write the current data for page X into the 
+-    ** sub-journal file now (if it is not already there), so that it will
+-    ** be restored to its current value when the "ROLLBACK TO sp" is 
+-    ** executed.
+-    */
+-    if( NEVER(
+-        rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg)
+-    ) ){
+-      rc = subjournalPage(pPg);
++    rc = pagerPagecount(pPager, &nPage);
++    if( rc ) return rc;
++    if( nPage==0 ){
++      rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0);
++      if( rc==SQLITE_IOERR_DELETE_NOENT ) rc = SQLITE_OK;
++      isWal = 0;
++    }else{
++      rc = sqlite3OsAccess(
++          pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal
++      );
+     }
+-  
+-    /* Write the contents of the page out to the database file. */
+     if( rc==SQLITE_OK ){
+-      assert( (pPg->flags&PGHDR_NEED_SYNC)==0 );
+-      rc = pager_write_pagelist(pPager, pPg);
++      if( isWal ){
++        testcase( sqlite3PcachePagecount(pPager->pPCache)==0 );
++        rc = sqlite3PagerOpenWal(pPager, 0);
++      }else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){
++        pPager->journalMode = PAGER_JOURNALMODE_DELETE;
++      }
+     }
+   }
+-
+-  /* Mark the page as clean. */
+-  if( rc==SQLITE_OK ){
+-    PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno));
+-    sqlite3PcacheMakeClean(pPg);
+-  }
+-
+-  return pager_error(pPager, rc); 
++  return rc;
+ }
+-
++#endif
+ 
+ /*
+-** Allocate and initialize a new Pager object and put a pointer to it
+-** in *ppPager. The pager should eventually be freed by passing it
+-** to sqlite3PagerClose().
++** Playback savepoint pSavepoint. Or, if pSavepoint==NULL, then playback
++** the entire master journal file. The case pSavepoint==NULL occurs when 
++** a ROLLBACK TO command is invoked on a SAVEPOINT that is a transaction 
++** savepoint.
+ **
+-** The zFilename argument is the path to the database file to open.
+-** If zFilename is NULL then a randomly-named temporary file is created
+-** and used as the file to be cached. Temporary files are be deleted
+-** automatically when they are closed. If zFilename is ":memory:" then 
+-** all information is held in cache. It is never written to disk. 
+-** This can be used to implement an in-memory database.
++** When pSavepoint is not NULL (meaning a non-transaction savepoint is 
++** being rolled back), then the rollback consists of up to three stages,
++** performed in the order specified:
+ **
+-** The nExtra parameter specifies the number of bytes of space allocated
+-** along with each page reference. This space is available to the user
+-** via the sqlite3PagerGetExtra() API.
++**   * Pages are played back from the main journal starting at byte
++**     offset PagerSavepoint.iOffset and continuing to 
++**     PagerSavepoint.iHdrOffset, or to the end of the main journal
++**     file if PagerSavepoint.iHdrOffset is zero.
+ **
+-** The flags argument is used to specify properties that affect the
+-** operation of the pager. It should be passed some bitwise combination
+-** of the PAGER_* flags.
++**   * If PagerSavepoint.iHdrOffset is not zero, then pages are played
++**     back starting from the journal header immediately following 
++**     PagerSavepoint.iHdrOffset to the end of the main journal file.
+ **
+-** The vfsFlags parameter is a bitmask to pass to the flags parameter
+-** of the xOpen() method of the supplied VFS when opening files. 
++**   * Pages are then played back from the sub-journal file, starting
++**     with the PagerSavepoint.iSubRec and continuing to the end of
++**     the journal file.
+ **
+-** If the pager object is allocated and the specified file opened 
+-** successfully, SQLITE_OK is returned and *ppPager set to point to
+-** the new pager object. If an error occurs, *ppPager is set to NULL
+-** and error code returned. This function may return SQLITE_NOMEM
+-** (sqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or 
+-** various SQLITE_IO_XXX errors.
++** Throughout the rollback process, each time a page is rolled back, the
++** corresponding bit is set in a bitvec structure (variable pDone in the
++** implementation below). This is used to ensure that a page is only
++** rolled back the first time it is encountered in either journal.
++**
++** If pSavepoint is NULL, then pages are only played back from the main
++** journal file. There is no need for a bitvec in this case.
++**
++** In either case, before playback commences the Pager.dbSize variable
++** is reset to the value that it held at the start of the savepoint 
++** (or transaction). No page with a page-number greater than this value
++** is played back. If one is encountered it is simply skipped.
+ */
+-SQLITE_PRIVATE int sqlite3PagerOpen(
+-  sqlite3_vfs *pVfs,       /* The virtual file system to use */
+-  Pager **ppPager,         /* OUT: Return the Pager structure here */
+-  const char *zFilename,   /* Name of the database file to open */
+-  int nExtra,              /* Extra bytes append to each in-memory page */
+-  int flags,               /* flags controlling this file */
+-  int vfsFlags,            /* flags passed through to sqlite3_vfs.xOpen() */
+-  void (*xReinit)(DbPage*) /* Function to reinitialize pages */
+-){
+-  u8 *pPtr;
+-  Pager *pPager = 0;       /* Pager object to allocate and return */
++static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){
++  i64 szJ;                 /* Effective size of the main journal */
++  i64 iHdrOff;             /* End of first segment of main-journal records */
+   int rc = SQLITE_OK;      /* Return code */
+-  int tempFile = 0;        /* True for temp files (incl. in-memory files) */
+-  int memDb = 0;           /* True if this is an in-memory file */
+-  int readOnly = 0;        /* True if this is a read-only file */
+-  int journalFileSize;     /* Bytes to allocate for each journal fd */
+-  char *zPathname = 0;     /* Full path to database file */
+-  int nPathname = 0;       /* Number of bytes in zPathname */
+-  int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */
+-  int pcacheSize = sqlite3PcacheSize();       /* Bytes to allocate for PCache */
+-  u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE;  /* Default page size */
+-  const char *zUri = 0;    /* URI args to copy */
+-  int nUri = 0;            /* Number of bytes of URI args at *zUri */
+-
+-  /* Figure out how much space is required for each journal file-handle
+-  ** (there are two of them, the main journal and the sub-journal). This
+-  ** is the maximum space required for an in-memory journal file handle 
+-  ** and a regular journal file-handle. Note that a "regular journal-handle"
+-  ** may be a wrapper capable of caching the first portion of the journal
+-  ** file in memory to implement the atomic-write optimization (see 
+-  ** source file journal.c).
+-  */
+-  if( sqlite3JournalSize(pVfs)>sqlite3MemJournalSize() ){
+-    journalFileSize = ROUND8(sqlite3JournalSize(pVfs));
+-  }else{
+-    journalFileSize = ROUND8(sqlite3MemJournalSize());
+-  }
+-
+-  /* Set the output variable to NULL in case an error occurs. */
+-  *ppPager = 0;
++  Bitvec *pDone = 0;       /* Bitvec to ensure pages played back only once */
+ 
+-#ifndef SQLITE_OMIT_MEMORYDB
+-  if( flags & PAGER_MEMORY ){
+-    memDb = 1;
+-    if( zFilename && zFilename[0] ){
+-      zPathname = sqlite3DbStrDup(0, zFilename);
+-      if( zPathname==0  ) return SQLITE_NOMEM;
+-      nPathname = sqlite3Strlen30(zPathname);
+-      zFilename = 0;
+-    }
+-  }
+-#endif
++  assert( pPager->eState!=PAGER_ERROR );
++  assert( pPager->eState>=PAGER_WRITER_LOCKED );
+ 
+-  /* Compute and store the full pathname in an allocated buffer pointed
+-  ** to by zPathname, length nPathname. Or, if this is a temporary file,
+-  ** leave both nPathname and zPathname set to 0.
+-  */
+-  if( zFilename && zFilename[0] ){
+-    const char *z;
+-    nPathname = pVfs->mxPathname+1;
+-    zPathname = sqlite3DbMallocRaw(0, nPathname*2);
+-    if( zPathname==0 ){
++  /* Allocate a bitvec to use to store the set of pages rolled back */
++  if( pSavepoint ){
++    pDone = sqlite3BitvecCreate(pSavepoint->nOrig);
++    if( !pDone ){
+       return SQLITE_NOMEM;
+     }
+-    zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */
+-    rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
+-    nPathname = sqlite3Strlen30(zPathname);
+-    z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1];
+-    while( *z ){
+-      z += sqlite3Strlen30(z)+1;
+-      z += sqlite3Strlen30(z)+1;
+-    }
+-    nUri = (int)(&z[1] - zUri);
+-    assert( nUri>=0 );
+-    if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){
+-      /* This branch is taken when the journal path required by
+-      ** the database being opened will be more than pVfs->mxPathname
+-      ** bytes in length. This means the database cannot be opened,
+-      ** as it will not be possible to open the journal file or even
+-      ** check for a hot-journal before reading.
+-      */
+-      rc = SQLITE_CANTOPEN_BKPT;
+-    }
+-    if( rc!=SQLITE_OK ){
+-      sqlite3DbFree(0, zPathname);
+-      return rc;
+-    }
+   }
+ 
+-  /* Allocate memory for the Pager structure, PCache object, the
+-  ** three file descriptors, the database file name and the journal 
+-  ** file name. The layout in memory is as follows:
+-  **
+-  **     Pager object                    (sizeof(Pager) bytes)
+-  **     PCache object                   (sqlite3PcacheSize() bytes)
+-  **     Database file handle            (pVfs->szOsFile bytes)
+-  **     Sub-journal file handle         (journalFileSize bytes)
+-  **     Main journal file handle        (journalFileSize bytes)
+-  **     Database file name              (nPathname+1 bytes)
+-  **     Journal file name               (nPathname+8+1 bytes)
++  /* Set the database size back to the value it was before the savepoint 
++  ** being reverted was opened.
+   */
+-  pPtr = (u8 *)sqlite3MallocZero(
+-    ROUND8(sizeof(*pPager)) +      /* Pager structure */
+-    ROUND8(pcacheSize) +           /* PCache object */
+-    ROUND8(pVfs->szOsFile) +       /* The main db file */
+-    journalFileSize * 2 +          /* The two journal files */ 
+-    nPathname + 1 + nUri +         /* zFilename */
+-    nPathname + 8 + 2              /* zJournal */
+-#ifndef SQLITE_OMIT_WAL
+-    + nPathname + 4 + 2            /* zWal */
+-#endif
+-  );
+-  assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
+-  if( !pPtr ){
+-    sqlite3DbFree(0, zPathname);
+-    return SQLITE_NOMEM;
+-  }
+-  pPager =              (Pager*)(pPtr);
+-  pPager->pPCache =    (PCache*)(pPtr += ROUND8(sizeof(*pPager)));
+-  pPager->fd =   (sqlite3_file*)(pPtr += ROUND8(pcacheSize));
+-  pPager->sjfd = (sqlite3_file*)(pPtr += ROUND8(pVfs->szOsFile));
+-  pPager->jfd =  (sqlite3_file*)(pPtr += journalFileSize);
+-  pPager->zFilename =    (char*)(pPtr += journalFileSize);
+-  assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );
++  pPager->dbSize = pSavepoint ? pSavepoint->nOrig : pPager->dbOrigSize;
++  pPager->changeCountDone = pPager->tempFile;
++
++  if( !pSavepoint && pagerUseWal(pPager) ){
++    return pagerRollbackWal(pPager);
++  }
+ 
+-  /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */
+-  if( zPathname ){
+-    assert( nPathname>0 );
+-    pPager->zJournal =   (char*)(pPtr += nPathname + 1 + nUri);
+-    memcpy(pPager->zFilename, zPathname, nPathname);
+-    if( nUri ) memcpy(&pPager->zFilename[nPathname+1], zUri, nUri);
+-    memcpy(pPager->zJournal, zPathname, nPathname);
+-    memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+2);
+-    sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal);
+-#ifndef SQLITE_OMIT_WAL
+-    pPager->zWal = &pPager->zJournal[nPathname+8+1];
+-    memcpy(pPager->zWal, zPathname, nPathname);
+-    memcpy(&pPager->zWal[nPathname], "-wal\000", 4+1);
+-    sqlite3FileSuffix3(pPager->zFilename, pPager->zWal);
+-#endif
+-    sqlite3DbFree(0, zPathname);
++  /* Use pPager->journalOff as the effective size of the main rollback
++  ** journal.  The actual file might be larger than this in
++  ** PAGER_JOURNALMODE_TRUNCATE or PAGER_JOURNALMODE_PERSIST.  But anything
++  ** past pPager->journalOff is off-limits to us.
++  */
++  szJ = pPager->journalOff;
++  assert( pagerUseWal(pPager)==0 || szJ==0 );
++
++  /* Begin by rolling back records from the main journal starting at
++  ** PagerSavepoint.iOffset and continuing to the next journal header.
++  ** There might be records in the main journal that have a page number
++  ** greater than the current database size (pPager->dbSize) but those
++  ** will be skipped automatically.  Pages are added to pDone as they
++  ** are played back.
++  */
++  if( pSavepoint && !pagerUseWal(pPager) ){
++    iHdrOff = pSavepoint->iHdrOffset ? pSavepoint->iHdrOffset : szJ;
++    pPager->journalOff = pSavepoint->iOffset;
++    while( rc==SQLITE_OK && pPager->journalOff<iHdrOff ){
++      rc = pager_playback_one_page(pPager, &pPager->journalOff, pDone, 1, 1);
++    }
++    assert( rc!=SQLITE_DONE );
++  }else{
++    pPager->journalOff = 0;
+   }
+-  pPager->pVfs = pVfs;
+-  pPager->vfsFlags = vfsFlags;
+ 
+-  /* Open the pager file.
++  /* Continue rolling back records out of the main journal starting at
++  ** the first journal header seen and continuing until the effective end
++  ** of the main journal file.  Continue to skip out-of-range pages and
++  ** continue adding pages rolled back to pDone.
+   */
+-  if( zFilename && zFilename[0] ){
+-    int fout = 0;                    /* VFS flags returned by xOpen() */
+-    rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
+-    assert( !memDb );
+-    readOnly = (fout&SQLITE_OPEN_READONLY);
++  while( rc==SQLITE_OK && pPager->journalOff<szJ ){
++    u32 ii;            /* Loop counter */
++    u32 nJRec = 0;     /* Number of Journal Records */
++    u32 dummy;
++    rc = readJournalHdr(pPager, 0, szJ, &nJRec, &dummy);
++    assert( rc!=SQLITE_DONE );
+ 
+-    /* If the file was successfully opened for read/write access,
+-    ** choose a default page size in case we have to create the
+-    ** database file. The default page size is the maximum of:
+-    **
+-    **    + SQLITE_DEFAULT_PAGE_SIZE,
+-    **    + The value returned by sqlite3OsSectorSize()
+-    **    + The largest page size that can be written atomically.
++    /*
++    ** The "pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff"
++    ** test is related to ticket #2565.  See the discussion in the
++    ** pager_playback() function for additional information.
+     */
+-    if( rc==SQLITE_OK ){
+-      int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
+-      if( !readOnly ){
+-        setSectorSize(pPager);
+-        assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE);
+-        if( szPageDflt<pPager->sectorSize ){
+-          if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){
+-            szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE;
+-          }else{
+-            szPageDflt = (u32)pPager->sectorSize;
+-          }
+-        }
+-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+-        {
+-          int ii;
+-          assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
+-          assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
+-          assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536);
+-          for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){
+-            if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ){
+-              szPageDflt = ii;
+-            }
+-          }
+-        }
+-#endif
+-      }
+-      pPager->noLock = sqlite3_uri_boolean(zFilename, "nolock", 0);
+-      if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0
+-       || sqlite3_uri_boolean(zFilename, "immutable", 0) ){
+-          vfsFlags |= SQLITE_OPEN_READONLY;
+-          goto act_like_temp_file;
+-      }
++    if( nJRec==0 
++     && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff
++    ){
++      nJRec = (u32)((szJ - pPager->journalOff)/JOURNAL_PG_SZ(pPager));
+     }
+-  }else{
+-    /* If a temporary file is requested, it is not opened immediately.
+-    ** In this case we accept the default page size and delay actually
+-    ** opening the file until the first call to OsWrite().
+-    **
+-    ** This branch is also run for an in-memory database. An in-memory
+-    ** database is the same as a temp-file that is never written out to
+-    ** disk and uses an in-memory rollback journal.
+-    **
+-    ** This branch also runs for files marked as immutable.
+-    */ 
+-act_like_temp_file:
+-    tempFile = 1;
+-    pPager->eState = PAGER_READER;     /* Pretend we already have a lock */
+-    pPager->eLock = EXCLUSIVE_LOCK;    /* Pretend we are in EXCLUSIVE locking mode */
+-    pPager->noLock = 1;                /* Do no locking */
+-    readOnly = (vfsFlags&SQLITE_OPEN_READONLY);
++    for(ii=0; rc==SQLITE_OK && ii<nJRec && pPager->journalOff<szJ; ii++){
++      rc = pager_playback_one_page(pPager, &pPager->journalOff, pDone, 1, 1);
++    }
++    assert( rc!=SQLITE_DONE );
+   }
++  assert( rc!=SQLITE_OK || pPager->journalOff>=szJ );
+ 
+-  /* The following call to PagerSetPagesize() serves to set the value of 
+-  ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer.
++  /* Finally,  rollback pages from the sub-journal.  Page that were
++  ** previously rolled back out of the main journal (and are hence in pDone)
++  ** will be skipped.  Out-of-range pages are also skipped.
+   */
+-  if( rc==SQLITE_OK ){
+-    assert( pPager->memDb==0 );
+-    rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1);
+-    testcase( rc!=SQLITE_OK );
++  if( pSavepoint ){
++    u32 ii;            /* Loop counter */
++    i64 offset = (i64)pSavepoint->iSubRec*(4+pPager->pageSize);
++
++    if( pagerUseWal(pPager) ){
++      rc = sqlite3WalSavepointUndo(pPager->pWal, pSavepoint->aWalData);
++    }
++    for(ii=pSavepoint->iSubRec; rc==SQLITE_OK && ii<pPager->nSubRec; ii++){
++      assert( offset==(i64)ii*(4+pPager->pageSize) );
++      rc = pager_playback_one_page(pPager, &offset, pDone, 0, 1);
++    }
++    assert( rc!=SQLITE_DONE );
+   }
+ 
+-  /* Initialize the PCache object. */
++  sqlite3BitvecDestroy(pDone);
+   if( rc==SQLITE_OK ){
+-    assert( nExtra<1000 );
+-    nExtra = ROUND8(nExtra);
+-    rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb,
+-                           !memDb?pagerStress:0, (void *)pPager, pPager->pPCache);
++    pPager->journalOff = szJ;
+   }
+ 
+-  /* If an error occurred above, free the  Pager structure and close the file.
+-  */
+-  if( rc!=SQLITE_OK ){
+-    sqlite3OsClose(pPager->fd);
+-    sqlite3PageFree(pPager->pTmpSpace);
+-    sqlite3_free(pPager);
+-    return rc;
++  return rc;
 +}
 +
-+SQLITE_PRIVATE void sqlite3pager_sqlite3PagerSetError( Pager *pPager, int error) {
-+  pPager->errCode = error;
++/*
++** Change the maximum number of in-memory pages that are allowed.
++*/
++SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){
++  sqlite3PcacheSetCachesize(pPager->pPCache, mxPage);
 +}
 +
++/*
++** Invoke SQLITE_FCNTL_MMAP_SIZE based on the current value of szMmap.
++*/
++static void pagerFixMaplimit(Pager *pPager){
++#if SQLITE_MAX_MMAP_SIZE>0
++  sqlite3_file *fd = pPager->fd;
++  if( isOpen(fd) && fd->pMethods->iVersion>=3 ){
++    sqlite3_int64 sz;
++    sz = pPager->szMmap;
++    pPager->bUseFetch = (sz>0);
++    sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz);
+   }
 +#endif
-+/* END SQLCIPHER */
++}
+ 
+-  PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename));
+-  IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename))
++/*
++** Change the maximum size of any memory mapping made of the database file.
++*/
++SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *pPager, sqlite3_int64 szMmap){
++  pPager->szMmap = szMmap;
++  pagerFixMaplimit(pPager);
++}
+ 
+-  pPager->useJournal = (u8)useJournal;
+-  /* pPager->stmtOpen = 0; */
+-  /* pPager->stmtInUse = 0; */
+-  /* pPager->nRef = 0; */
+-  /* pPager->stmtSize = 0; */
+-  /* pPager->stmtJSize = 0; */
+-  /* pPager->nPage = 0; */
+-  pPager->mxPgno = SQLITE_MAX_PAGE_COUNT;
+-  /* pPager->state = PAGER_UNLOCK; */
+-  /* pPager->errMask = 0; */
+-  pPager->tempFile = (u8)tempFile;
+-  assert( tempFile==PAGER_LOCKINGMODE_NORMAL 
+-          || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE );
+-  assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 );
+-  pPager->exclusiveMode = (u8)tempFile; 
+-  pPager->changeCountDone = pPager->tempFile;
+-  pPager->memDb = (u8)memDb;
+-  pPager->readOnly = (u8)readOnly;
+-  assert( useJournal || pPager->tempFile );
+-  pPager->noSync = pPager->tempFile;
++/*
++** Free as much memory as possible from the pager.
++*/
++SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){
++  sqlite3PcacheShrink(pPager->pPCache);
++}
++
++/*
++** Adjust settings of the pager to those specified in the pgFlags parameter.
++**
++** The "level" in pgFlags & PAGER_SYNCHRONOUS_MASK sets the robustness
++** of the database to damage due to OS crashes or power failures by
++** changing the number of syncs()s when writing the journals.
++** There are three levels:
++**
++**    OFF       sqlite3OsSync() is never called.  This is the default
++**              for temporary and transient files.
++**
++**    NORMAL    The journal is synced once before writes begin on the
++**              database.  This is normally adequate protection, but
++**              it is theoretically possible, though very unlikely,
++**              that an inopertune power failure could leave the journal
++**              in a state which would cause damage to the database
++**              when it is rolled back.
++**
++**    FULL      The journal is synced twice before writes begin on the
++**              database (with some additional information - the nRec field
++**              of the journal header - being written in between the two
++**              syncs).  If we assume that writing a
++**              single disk sector is atomic, then this mode provides
++**              assurance that the journal will not be corrupted to the
++**              point of causing damage to the database during rollback.
++**
++** The above is for a rollback-journal mode.  For WAL mode, OFF continues
++** to mean that no syncs ever occur.  NORMAL means that the WAL is synced
++** prior to the start of checkpoint and that the database file is synced
++** at the conclusion of the checkpoint if the entire content of the WAL
++** was written back into the database.  But no sync operations occur for
++** an ordinary commit in NORMAL mode with WAL.  FULL means that the WAL
++** file is synced following each commit operation, in addition to the
++** syncs associated with NORMAL.
++**
++** Do not confuse synchronous=FULL with SQLITE_SYNC_FULL.  The
++** SQLITE_SYNC_FULL macro means to use the MacOSX-style full-fsync
++** using fcntl(F_FULLFSYNC).  SQLITE_SYNC_NORMAL means to do an
++** ordinary fsync() call.  There is no difference between SQLITE_SYNC_FULL
++** and SQLITE_SYNC_NORMAL on platforms other than MacOSX.  But the
++** synchronous=FULL versus synchronous=NORMAL setting determines when
++** the xSync primitive is called and is relevant to all platforms.
++**
++** Numeric values associated with these states are OFF==1, NORMAL=2,
++** and FULL=3.
++*/
++#ifndef SQLITE_OMIT_PAGER_PRAGMAS
++SQLITE_PRIVATE void sqlite3PagerSetFlags(
++  Pager *pPager,        /* The pager to set safety level for */
++  unsigned pgFlags      /* Various flags */
++){
++  unsigned level = pgFlags & PAGER_SYNCHRONOUS_MASK;
++  assert( level>=1 && level<=3 );
++  pPager->noSync =  (level==1 || pPager->tempFile) ?1:0;
++  pPager->fullSync = (level==3 && !pPager->tempFile) ?1:0;
+   if( pPager->noSync ){
+-    assert( pPager->fullSync==0 );
+-    assert( pPager->syncFlags==0 );
+-    assert( pPager->walSyncFlags==0 );
+-    assert( pPager->ckptSyncFlags==0 );
++    pPager->syncFlags = 0;
++    pPager->ckptSyncFlags = 0;
++  }else if( pgFlags & PAGER_FULLFSYNC ){
++    pPager->syncFlags = SQLITE_SYNC_FULL;
++    pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
++  }else if( pgFlags & PAGER_CKPT_FULLFSYNC ){
++    pPager->syncFlags = SQLITE_SYNC_NORMAL;
++    pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
+   }else{
+-    pPager->fullSync = 1;
+     pPager->syncFlags = SQLITE_SYNC_NORMAL;
+-    pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS;
+     pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL;
+   }
+-  /* pPager->pFirst = 0; */
+-  /* pPager->pFirstSynced = 0; */
+-  /* pPager->pLast = 0; */
+-  pPager->nExtra = (u16)nExtra;
+-  pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT;
+-  assert( isOpen(pPager->fd) || tempFile );
+-  setSectorSize(pPager);
+-  if( !useJournal ){
+-    pPager->journalMode = PAGER_JOURNALMODE_OFF;
+-  }else if( memDb ){
+-    pPager->journalMode = PAGER_JOURNALMODE_MEMORY;
++  pPager->walSyncFlags = pPager->syncFlags;
++  if( pPager->fullSync ){
++    pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS;
++  }
++  if( pgFlags & PAGER_CACHESPILL ){
++    pPager->doNotSpill &= ~SPILLFLAG_OFF;
++  }else{
++    pPager->doNotSpill |= SPILLFLAG_OFF;
+   }
+-  /* pPager->xBusyHandler = 0; */
+-  /* pPager->pBusyHandlerArg = 0; */
+-  pPager->xReiniter = xReinit;
+-  /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
+-  /* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */
+-
+-  *ppPager = pPager;
+-  return SQLITE_OK;
+ }
++#endif
+ 
++/*
++** The following global variable is incremented whenever the library
++** attempts to open a temporary file.  This information is used for
++** testing and analysis only.  
++*/
++#ifdef SQLITE_TEST
++SQLITE_API int sqlite3_opentemp_count = 0;
++#endif
+ 
+-/* Verify that the database file has not be deleted or renamed out from
+-** under the pager.  Return SQLITE_OK if the database is still were it ought
+-** to be on disk.  Return non-zero (SQLITE_READONLY_DBMOVED or some other error
+-** code from sqlite3OsAccess()) if the database has gone missing.
++/*
++** Open a temporary file.
++**
++** Write the file descriptor into *pFile. Return SQLITE_OK on success 
++** or some other error code if we fail. The OS will automatically 
++** delete the temporary file when it is closed.
++**
++** The flags passed to the VFS layer xOpen() call are those specified
++** by parameter vfsFlags ORed with the following:
++**
++**     SQLITE_OPEN_READWRITE
++**     SQLITE_OPEN_CREATE
++**     SQLITE_OPEN_EXCLUSIVE
++**     SQLITE_OPEN_DELETEONCLOSE
+ */
+-static int databaseIsUnmoved(Pager *pPager){
+-  int bHasMoved = 0;
+-  int rc;
++static int pagerOpentemp(
++  Pager *pPager,        /* The pager object */
++  sqlite3_file *pFile,  /* Write the file descriptor here */
++  int vfsFlags          /* Flags passed through to the VFS */
++){
++  int rc;               /* Return code */
+ 
+-  if( pPager->tempFile ) return SQLITE_OK;
+-  if( pPager->dbSize==0 ) return SQLITE_OK;
+-  assert( pPager->zFilename && pPager->zFilename[0] );
+-  rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved);
+-  if( rc==SQLITE_NOTFOUND ){
+-    /* If the HAS_MOVED file-control is unimplemented, assume that the file
+-    ** has not been moved.  That is the historical behavior of SQLite: prior to
+-    ** version 3.8.3, it never checked */
+-    rc = SQLITE_OK;
+-  }else if( rc==SQLITE_OK && bHasMoved ){
+-    rc = SQLITE_READONLY_DBMOVED;
+-  }
++#ifdef SQLITE_TEST
++  sqlite3_opentemp_count++;  /* Used for testing and analysis only */
++#endif
++
++  vfsFlags |=  SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
++            SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE;
++  rc = sqlite3OsOpen(pPager->pVfs, 0, pFile, vfsFlags, 0);
++  assert( rc!=SQLITE_OK || isOpen(pFile) );
+   return rc;
+ }
+ 
+-
+ /*
+-** This function is called after transitioning from PAGER_UNLOCK to
+-** PAGER_SHARED state. It tests if there is a hot journal present in
+-** the file-system for the given pager. A hot journal is one that 
+-** needs to be played back. According to this function, a hot-journal
+-** file exists if the following criteria are met:
+-**
+-**   * The journal file exists in the file system, and
+-**   * No process holds a RESERVED or greater lock on the database file, and
+-**   * The database file itself is greater than 0 bytes in size, and
+-**   * The first byte of the journal file exists and is not 0x00.
++** Set the busy handler function.
+ **
+-** If the current size of the database file is 0 but a journal file
+-** exists, that is probably an old journal left over from a prior
+-** database with the same name. In this case the journal file is
+-** just deleted using OsDelete, *pExists is set to 0 and SQLITE_OK
+-** is returned.
++** The pager invokes the busy-handler if sqlite3OsLock() returns 
++** SQLITE_BUSY when trying to upgrade from no-lock to a SHARED lock,
++** or when trying to upgrade from a RESERVED lock to an EXCLUSIVE 
++** lock. It does *not* invoke the busy handler when upgrading from
++** SHARED to RESERVED, or when upgrading from SHARED to EXCLUSIVE
++** (which occurs during hot-journal rollback). Summary:
+ **
+-** This routine does not check if there is a master journal filename
+-** at the end of the file. If there is, and that master journal file
+-** does not exist, then the journal file is not really hot. In this
+-** case this routine will return a false-positive. The pager_playback()
+-** routine will discover that the journal file is not really hot and 
+-** will not roll it back. 
++**   Transition                        | Invokes xBusyHandler
++**   --------------------------------------------------------
++**   NO_LOCK       -> SHARED_LOCK      | Yes
++**   SHARED_LOCK   -> RESERVED_LOCK    | No
++**   SHARED_LOCK   -> EXCLUSIVE_LOCK   | No
++**   RESERVED_LOCK -> EXCLUSIVE_LOCK   | Yes
+ **
+-** If a hot-journal file is found to exist, *pExists is set to 1 and 
+-** SQLITE_OK returned. If no hot-journal file is present, *pExists is
+-** set to 0 and SQLITE_OK returned. If an IO error occurs while trying
+-** to determine whether or not a hot-journal file exists, the IO error
+-** code is returned and the value of *pExists is undefined.
++** If the busy-handler callback returns non-zero, the lock is 
++** retried. If it returns zero, then the SQLITE_BUSY error is
++** returned to the caller of the pager API function.
+ */
+-static int hasHotJournal(Pager *pPager, int *pExists){
+-  sqlite3_vfs * const pVfs = pPager->pVfs;
+-  int rc = SQLITE_OK;           /* Return code */
+-  int exists = 1;               /* True if a journal file is present */
+-  int jrnlOpen = !!isOpen(pPager->jfd);
+-
+-  assert( pPager->useJournal );
+-  assert( isOpen(pPager->fd) );
+-  assert( pPager->eState==PAGER_OPEN );
+-
+-  assert( jrnlOpen==0 || ( sqlite3OsDeviceCharacteristics(pPager->jfd) &
+-    SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
+-  ));
+-
+-  *pExists = 0;
+-  if( !jrnlOpen ){
+-    rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists);
+-  }
+-  if( rc==SQLITE_OK && exists ){
+-    int locked = 0;             /* True if some process holds a RESERVED lock */
+-
+-    /* Race condition here:  Another process might have been holding the
+-    ** the RESERVED lock and have a journal open at the sqlite3OsAccess() 
+-    ** call above, but then delete the journal and drop the lock before
+-    ** we get to the following sqlite3OsCheckReservedLock() call.  If that
+-    ** is the case, this routine might think there is a hot journal when
+-    ** in fact there is none.  This results in a false-positive which will
+-    ** be dealt with by the playback routine.  Ticket #3883.
+-    */
+-    rc = sqlite3OsCheckReservedLock(pPager->fd, &locked);
+-    if( rc==SQLITE_OK && !locked ){
+-      Pgno nPage;                 /* Number of pages in database file */
++SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(
++  Pager *pPager,                       /* Pager object */
++  int (*xBusyHandler)(void *),         /* Pointer to busy-handler function */
++  void *pBusyHandlerArg                /* Argument to pass to xBusyHandler */
++){
++  pPager->xBusyHandler = xBusyHandler;
++  pPager->pBusyHandlerArg = pBusyHandlerArg;
+ 
+-      rc = pagerPagecount(pPager, &nPage);
+-      if( rc==SQLITE_OK ){
+-        /* If the database is zero pages in size, that means that either (1) the
+-        ** journal is a remnant from a prior database with the same name where
+-        ** the database file but not the journal was deleted, or (2) the initial
+-        ** transaction that populates a new database is being rolled back.
+-        ** In either case, the journal file can be deleted.  However, take care
+-        ** not to delete the journal file if it is already open due to
+-        ** journal_mode=PERSIST.
+-        */
+-        if( nPage==0 && !jrnlOpen ){
+-          sqlite3BeginBenignMalloc();
+-          if( pagerLockDb(pPager, RESERVED_LOCK)==SQLITE_OK ){
+-            sqlite3OsDelete(pVfs, pPager->zJournal, 0);
+-            if( !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK);
+-          }
+-          sqlite3EndBenignMalloc();
+-        }else{
+-          /* The journal file exists and no other connection has a reserved
+-          ** or greater lock on the database file. Now check that there is
+-          ** at least one non-zero bytes at the start of the journal file.
+-          ** If there is, then we consider this journal to be hot. If not, 
+-          ** it can be ignored.
+-          */
+-          if( !jrnlOpen ){
+-            int f = SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL;
+-            rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &f);
+-          }
+-          if( rc==SQLITE_OK ){
+-            u8 first = 0;
+-            rc = sqlite3OsRead(pPager->jfd, (void *)&first, 1, 0);
+-            if( rc==SQLITE_IOERR_SHORT_READ ){
+-              rc = SQLITE_OK;
+-            }
+-            if( !jrnlOpen ){
+-              sqlite3OsClose(pPager->jfd);
+-            }
+-            *pExists = (first!=0);
+-          }else if( rc==SQLITE_CANTOPEN ){
+-            /* If we cannot open the rollback journal file in order to see if
+-            ** it has a zero header, that might be due to an I/O error, or
+-            ** it might be due to the race condition described above and in
+-            ** ticket #3883.  Either way, assume that the journal is hot.
+-            ** This might be a false positive.  But if it is, then the
+-            ** automatic journal playback and recovery mechanism will deal
+-            ** with it under an EXCLUSIVE lock where we do not need to
+-            ** worry so much with race conditions.
+-            */
+-            *pExists = 1;
+-            rc = SQLITE_OK;
+-          }
+-        }
+-      }
+-    }
++  if( isOpen(pPager->fd) ){
++    void **ap = (void **)&pPager->xBusyHandler;
++    assert( ((int(*)(void *))(ap[0]))==xBusyHandler );
++    assert( ap[1]==pBusyHandlerArg );
++    sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap);
+   }
+-
+-  return rc;
+ }
+ 
+ /*
+-** This function is called to obtain a shared lock on the database file.
+-** It is illegal to call sqlite3PagerAcquire() until after this function
+-** has been successfully called. If a shared-lock is already held when
+-** this function is called, it is a no-op.
++** Change the page size used by the Pager object. The new page size 
++** is passed in *pPageSize.
+ **
+-** The following operations are also performed by this function.
++** If the pager is in the error state when this function is called, it
++** is a no-op. The value returned is the error state error code (i.e. 
++** one of SQLITE_IOERR, an SQLITE_IOERR_xxx sub-code or SQLITE_FULL).
+ **
+-**   1) If the pager is currently in PAGER_OPEN state (no lock held
+-**      on the database file), then an attempt is made to obtain a
+-**      SHARED lock on the database file. Immediately after obtaining
+-**      the SHARED lock, the file-system is checked for a hot-journal,
+-**      which is played back if present. Following any hot-journal 
+-**      rollback, the contents of the cache are validated by checking
+-**      the 'change-counter' field of the database file header and
+-**      discarded if they are found to be invalid.
++** Otherwise, if all of the following are true:
+ **
+-**   2) If the pager is running in exclusive-mode, and there are currently
+-**      no outstanding references to any pages, and is in the error state,
+-**      then an attempt is made to clear the error state by discarding
+-**      the contents of the page cache and rolling back any open journal
+-**      file.
++**   * the new page size (value of *pPageSize) is valid (a power 
++**     of two between 512 and SQLITE_MAX_PAGE_SIZE, inclusive), and
+ **
+-** If everything is successful, SQLITE_OK is returned. If an IO error 
+-** occurs while locking the database, checking for a hot-journal file or 
+-** rolling back a journal file, the IO error code is returned.
++**   * there are no outstanding page references, and
++**
++**   * the database is either not an in-memory database or it is
++**     an in-memory database that currently consists of zero pages.
++**
++** then the pager object page size is set to *pPageSize.
++**
++** If the page size is changed, then this function uses sqlite3PagerMalloc() 
++** to obtain a new Pager.pTmpSpace buffer. If this allocation attempt 
++** fails, SQLITE_NOMEM is returned and the page size remains unchanged. 
++** In all other cases, SQLITE_OK is returned.
++**
++** If the page size is not changed, either because one of the enumerated
++** conditions above is not true, the pager was in error state when this
++** function was called, or because the memory allocation attempt failed, 
++** then *pPageSize is set to the old, retained page size before returning.
+ */
+-SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
+-  int rc = SQLITE_OK;                /* Return code */
++SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){
++  int rc = SQLITE_OK;
+ 
+-  /* This routine is only called from b-tree and only when there are no
+-  ** outstanding pages. This implies that the pager state should either
+-  ** be OPEN or READER. READER is only possible if the pager is or was in 
+-  ** exclusive access mode.
++  /* It is not possible to do a full assert_pager_state() here, as this
++  ** function may be called from within PagerOpen(), before the state
++  ** of the Pager object is internally consistent.
++  **
++  ** At one point this function returned an error if the pager was in 
++  ** PAGER_ERROR state. But since PAGER_ERROR state guarantees that
++  ** there is at least one outstanding page reference, this function
++  ** is a no-op for that case anyhow.
+   */
+-  assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
+-  assert( assert_pager_state(pPager) );
+-  assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER );
+-  if( NEVER(MEMDB && pPager->errCode) ){ return pPager->errCode; }
+-
+-  if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){
+-    int bHotJournal = 1;          /* True if there exists a hot journal-file */
+ 
+-    assert( !MEMDB );
++  u32 pageSize = *pPageSize;
++  assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) );
++  if( (pPager->memDb==0 || pPager->dbSize==0)
++   && sqlite3PcacheRefCount(pPager->pPCache)==0 
++   && pageSize && pageSize!=(u32)pPager->pageSize 
++  ){
++    char *pNew = NULL;             /* New temp space */
++    i64 nByte = 0;
+ 
+-    rc = pager_wait_on_lock(pPager, SHARED_LOCK);
+-    if( rc!=SQLITE_OK ){
+-      assert( pPager->eLock==NO_LOCK || pPager->eLock==UNKNOWN_LOCK );
+-      goto failed;
++    if( pPager->eState>PAGER_OPEN && isOpen(pPager->fd) ){
++      rc = sqlite3OsFileSize(pPager->fd, &nByte);
++    }
++    if( rc==SQLITE_OK ){
++      pNew = (char *)sqlite3PageMalloc(pageSize);
++      if( !pNew ) rc = SQLITE_NOMEM;
+     }
+ 
+-    /* If a journal file exists, and there is no RESERVED lock on the
+-    ** database file, then it either needs to be played back or deleted.
+-    */
+-    if( pPager->eLock<=SHARED_LOCK ){
+-      rc = hasHotJournal(pPager, &bHotJournal);
++    if( rc==SQLITE_OK ){
++      pager_reset(pPager);
++      rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize);
+     }
+-    if( rc!=SQLITE_OK ){
+-      goto failed;
++    if( rc==SQLITE_OK ){
++      sqlite3PageFree(pPager->pTmpSpace);
++      pPager->pTmpSpace = pNew;
++      pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize);
++      pPager->pageSize = pageSize;
++    }else{
++      sqlite3PageFree(pNew);
+     }
+-    if( bHotJournal ){
+-      if( pPager->readOnly ){
+-        rc = SQLITE_READONLY_ROLLBACK;
+-        goto failed;
+-      }
++  }
+ 
+-      /* Get an EXCLUSIVE lock on the database file. At this point it is
+-      ** important that a RESERVED lock is not obtained on the way to the
+-      ** EXCLUSIVE lock. If it were, another process might open the
+-      ** database file, detect the RESERVED lock, and conclude that the
+-      ** database is safe to read while this process is still rolling the 
+-      ** hot-journal back.
+-      ** 
+-      ** Because the intermediate RESERVED lock is not requested, any
+-      ** other process attempting to access the database file will get to 
+-      ** this point in the code and fail to obtain its own EXCLUSIVE lock 
+-      ** on the database file.
+-      **
+-      ** Unless the pager is in locking_mode=exclusive mode, the lock is
+-      ** downgraded to SHARED_LOCK before this function returns.
+-      */
+-      rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
+-      if( rc!=SQLITE_OK ){
+-        goto failed;
+-      }
+- 
+-      /* If it is not already open and the file exists on disk, open the 
+-      ** journal for read/write access. Write access is required because 
+-      ** in exclusive-access mode the file descriptor will be kept open 
+-      ** and possibly used for a transaction later on. Also, write-access 
+-      ** is usually required to finalize the journal in journal_mode=persist 
+-      ** mode (and also for journal_mode=truncate on some systems).
+-      **
+-      ** If the journal does not exist, it usually means that some 
+-      ** other connection managed to get in and roll it back before 
+-      ** this connection obtained the exclusive lock above. Or, it 
+-      ** may mean that the pager was in the error-state when this
+-      ** function was called and the journal file does not exist.
+-      */
+-      if( !isOpen(pPager->jfd) ){
+-        sqlite3_vfs * const pVfs = pPager->pVfs;
+-        int bExists;              /* True if journal file exists */
+-        rc = sqlite3OsAccess(
+-            pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &bExists);
+-        if( rc==SQLITE_OK && bExists ){
+-          int fout = 0;
+-          int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL;
+-          assert( !pPager->tempFile );
+-          rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout);
+-          assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
+-          if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){
+-            rc = SQLITE_CANTOPEN_BKPT;
+-            sqlite3OsClose(pPager->jfd);
+-          }
+-        }
+-      }
+- 
+-      /* Playback and delete the journal.  Drop the database write
+-      ** lock and reacquire the read lock. Purge the cache before
+-      ** playing back the hot-journal so that we don't end up with
+-      ** an inconsistent cache.  Sync the hot journal before playing
+-      ** it back since the process that crashed and left the hot journal
+-      ** probably did not sync it and we are required to always sync
+-      ** the journal before playing it back.
+-      */
+-      if( isOpen(pPager->jfd) ){
+-        assert( rc==SQLITE_OK );
+-        rc = pagerSyncHotJournal(pPager);
+-        if( rc==SQLITE_OK ){
+-          rc = pager_playback(pPager, 1);
+-          pPager->eState = PAGER_OPEN;
+-        }
+-      }else if( !pPager->exclusiveMode ){
+-        pagerUnlockDb(pPager, SHARED_LOCK);
+-      }
++  *pPageSize = pPager->pageSize;
++  if( rc==SQLITE_OK ){
++    if( nReserve<0 ) nReserve = pPager->nReserve;
++    assert( nReserve>=0 && nReserve<1000 );
++    pPager->nReserve = (i16)nReserve;
++    pagerReportSize(pPager);
++    pagerFixMaplimit(pPager);
++  }
++  return rc;
++}
+ 
+-      if( rc!=SQLITE_OK ){
+-        /* This branch is taken if an error occurs while trying to open
+-        ** or roll back a hot-journal while holding an EXCLUSIVE lock. The
+-        ** pager_unlock() routine will be called before returning to unlock
+-        ** the file. If the unlock attempt fails, then Pager.eLock must be
+-        ** set to UNKNOWN_LOCK (see the comment above the #define for 
+-        ** UNKNOWN_LOCK above for an explanation). 
+-        **
+-        ** In order to get pager_unlock() to do this, set Pager.eState to
+-        ** PAGER_ERROR now. This is not actually counted as a transition
+-        ** to ERROR state in the state diagram at the top of this file,
+-        ** since we know that the same call to pager_unlock() will very
+-        ** shortly transition the pager object to the OPEN state. Calling
+-        ** assert_pager_state() would fail now, as it should not be possible
+-        ** to be in ERROR state when there are zero outstanding page 
+-        ** references.
+-        */
+-        pager_error(pPager, rc);
+-        goto failed;
+-      }
++/*
++** Return a pointer to the "temporary page" buffer held internally
++** by the pager.  This is a buffer that is big enough to hold the
++** entire content of a database page.  This buffer is used internally
++** during rollback and will be overwritten whenever a rollback
++** occurs.  But other modules are free to use it too, as long as
++** no rollbacks are happening.
++*/
++SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager *pPager){
++  return pPager->pTmpSpace;
++}
+ 
+-      assert( pPager->eState==PAGER_OPEN );
+-      assert( (pPager->eLock==SHARED_LOCK)
+-           || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK)
+-      );
++/*
++** Attempt to set the maximum database page count if mxPage is positive. 
++** Make no changes if mxPage is zero or negative.  And never reduce the
++** maximum page count below the current size of the database.
++**
++** Regardless of mxPage, return the current maximum page count.
++*/
++SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager *pPager, int mxPage){
++  if( mxPage>0 ){
++    pPager->mxPgno = mxPage;
++  }
++  assert( pPager->eState!=PAGER_OPEN );      /* Called only by OP_MaxPgcnt */
++  assert( pPager->mxPgno>=pPager->dbSize );  /* OP_MaxPgcnt enforces this */
++  return pPager->mxPgno;
++}
++
++/*
++** The following set of routines are used to disable the simulated
++** I/O error mechanism.  These routines are used to avoid simulated
++** errors in places where we do not care about errors.
++**
++** Unless -DSQLITE_TEST=1 is used, these routines are all no-ops
++** and generate no code.
++*/
++#ifdef SQLITE_TEST
++SQLITE_API extern int sqlite3_io_error_pending;
++SQLITE_API extern int sqlite3_io_error_hit;
++static int saved_cnt;
++void disable_simulated_io_errors(void){
++  saved_cnt = sqlite3_io_error_pending;
++  sqlite3_io_error_pending = -1;
++}
++void enable_simulated_io_errors(void){
++  sqlite3_io_error_pending = saved_cnt;
++}
++#else
++# define disable_simulated_io_errors()
++# define enable_simulated_io_errors()
++#endif
++
++/*
++** Read the first N bytes from the beginning of the file into memory
++** that pDest points to. 
++**
++** If the pager was opened on a transient file (zFilename==""), or
++** opened on a file less than N bytes in size, the output buffer is
++** zeroed and SQLITE_OK returned. The rationale for this is that this 
++** function is used to read database headers, and a new transient or
++** zero sized database has a header than consists entirely of zeroes.
++**
++** If any IO error apart from SQLITE_IOERR_SHORT_READ is encountered,
++** the error code is returned to the caller and the contents of the
++** output buffer undefined.
++*/
++SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){
++  int rc = SQLITE_OK;
++  memset(pDest, 0, N);
++  assert( isOpen(pPager->fd) || pPager->tempFile );
++
++  /* This routine is only called by btree immediately after creating
++  ** the Pager object.  There has not been an opportunity to transition
++  ** to WAL mode yet.
++  */
++  assert( !pagerUseWal(pPager) );
++
++  if( isOpen(pPager->fd) ){
++    IOTRACE(("DBHDR %p 0 %d\n", pPager, N))
++    rc = sqlite3OsRead(pPager->fd, pDest, N, 0);
++    if( rc==SQLITE_IOERR_SHORT_READ ){
++      rc = SQLITE_OK;
+     }
++  }
++  return rc;
++}
+ 
+-    if( !pPager->tempFile && pPager->hasBeenUsed ){
+-      /* The shared-lock has just been acquired then check to
+-      ** see if the database has been modified.  If the database has changed,
+-      ** flush the cache.  The pPager->hasBeenUsed flag prevents this from
+-      ** occurring on the very first access to a file, in order to save a
+-      ** single unnecessary sqlite3OsRead() call at the start-up.
+-      **
+-      ** Database changes is detected by looking at 15 bytes beginning
+-      ** at offset 24 into the file.  The first 4 of these 16 bytes are
+-      ** a 32-bit counter that is incremented with each change.  The
+-      ** other bytes change randomly with each file change when
+-      ** a codec is in use.
+-      ** 
+-      ** There is a vanishingly small chance that a change will not be 
+-      ** detected.  The chance of an undetected change is so small that
+-      ** it can be neglected.
+-      */
+-      Pgno nPage = 0;
+-      char dbFileVers[sizeof(pPager->dbFileVers)];
++/*
++** This function may only be called when a read-transaction is open on
++** the pager. It returns the total number of pages in the database.
++**
++** However, if the file is between 1 and <page-size> bytes in size, then 
++** this is considered a 1 page file.
++*/
++SQLITE_PRIVATE void sqlite3PagerPagecount(Pager *pPager, int *pnPage){
++  assert( pPager->eState>=PAGER_READER );
++  assert( pPager->eState!=PAGER_WRITER_FINISHED );
++  *pnPage = (int)pPager->dbSize;
++}
+ 
+-      rc = pagerPagecount(pPager, &nPage);
+-      if( rc ) goto failed;
+ 
+-      if( nPage>0 ){
+-        IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
+-        rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
+-        if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
+-          goto failed;
+-        }
+-      }else{
+-        memset(dbFileVers, 0, sizeof(dbFileVers));
+-      }
++/*
++** Try to obtain a lock of type locktype on the database file. If
++** a similar or greater lock is already held, this function is a no-op
++** (returning SQLITE_OK immediately).
++**
++** Otherwise, attempt to obtain the lock using sqlite3OsLock(). Invoke 
++** the busy callback if the lock is currently not available. Repeat 
++** until the busy callback returns false or until the attempt to 
++** obtain the lock succeeds.
++**
++** Return SQLITE_OK on success and an error code if we cannot obtain
++** the lock. If the lock is obtained successfully, set the Pager.state 
++** variable to locktype before returning.
++*/
++static int pager_wait_on_lock(Pager *pPager, int locktype){
++  int rc;                              /* Return code */
+ 
+-      if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){
+-        pager_reset(pPager);
++  /* Check that this is either a no-op (because the requested lock is 
++  ** already held), or one of the transitions that the busy-handler
++  ** may be invoked during, according to the comment above
++  ** sqlite3PagerSetBusyhandler().
++  */
++  assert( (pPager->eLock>=locktype)
++       || (pPager->eLock==NO_LOCK && locktype==SHARED_LOCK)
++       || (pPager->eLock==RESERVED_LOCK && locktype==EXCLUSIVE_LOCK)
++  );
+ 
+-        /* Unmap the database file. It is possible that external processes
+-        ** may have truncated the database file and then extended it back
+-        ** to its original size while this process was not holding a lock.
+-        ** In this case there may exist a Pager.pMap mapping that appears
+-        ** to be the right size but is not actually valid. Avoid this
+-        ** possibility by unmapping the db here. */
+-        if( USEFETCH(pPager) ){
+-          sqlite3OsUnfetch(pPager->fd, 0, 0);
+-        }
+-      }
+-    }
++  do {
++    rc = pagerLockDb(pPager, locktype);
++  }while( rc==SQLITE_BUSY && pPager->xBusyHandler(pPager->pBusyHandlerArg) );
++  return rc;
++}
+ 
+-    /* If there is a WAL file in the file-system, open this database in WAL
+-    ** mode. Otherwise, the following function call is a no-op.
+-    */
+-    rc = pagerOpenWalIfPresent(pPager);
+-#ifndef SQLITE_OMIT_WAL
+-    assert( pPager->pWal==0 || rc==SQLITE_OK );
++/*
++** Function assertTruncateConstraint(pPager) checks that one of the 
++** following is true for all dirty pages currently in the page-cache:
++**
++**   a) The page number is less than or equal to the size of the 
++**      current database image, in pages, OR
++**
++**   b) if the page content were written at this time, it would not
++**      be necessary to write the current content out to the sub-journal
++**      (as determined by function subjRequiresPage()).
++**
++** If the condition asserted by this function were not true, and the
++** dirty page were to be discarded from the cache via the pagerStress()
++** routine, pagerStress() would not write the current page content to
++** the database file. If a savepoint transaction were rolled back after
++** this happened, the correct behavior would be to restore the current
++** content of the page. However, since this content is not present in either
++** the database file or the portion of the rollback journal and 
++** sub-journal rolled back the content could not be restored and the
++** database image would become corrupt. It is therefore fortunate that 
++** this circumstance cannot arise.
++*/
++#if defined(SQLITE_DEBUG)
++static void assertTruncateConstraintCb(PgHdr *pPg){
++  assert( pPg->flags&PGHDR_DIRTY );
++  assert( !subjRequiresPage(pPg) || pPg->pgno<=pPg->pPager->dbSize );
++}
++static void assertTruncateConstraint(Pager *pPager){
++  sqlite3PcacheIterateDirty(pPager->pPCache, assertTruncateConstraintCb);
++}
++#else
++# define assertTruncateConstraint(pPager)
+ #endif
++
++/*
++** Truncate the in-memory database file image to nPage pages. This 
++** function does not actually modify the database file on disk. It 
++** just sets the internal state of the pager object so that the 
++** truncation will be done when the current transaction is committed.
++**
++** This function is only called right before committing a transaction.
++** Once this function has been called, the transaction must either be
++** rolled back or committed. It is not safe to call this function and
++** then continue writing to the database.
++*/
++SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){
++  assert( pPager->dbSize>=nPage );
++  assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
++  pPager->dbSize = nPage;
++
++  /* At one point the code here called assertTruncateConstraint() to
++  ** ensure that all pages being truncated away by this operation are,
++  ** if one or more savepoints are open, present in the savepoint 
++  ** journal so that they can be restored if the savepoint is rolled
++  ** back. This is no longer necessary as this function is now only
++  ** called right before committing a transaction. So although the 
++  ** Pager object may still have open savepoints (Pager.nSavepoint!=0), 
++  ** they cannot be rolled back. So the assertTruncateConstraint() call
++  ** is no longer correct. */
++}
++
++
++/*
++** This function is called before attempting a hot-journal rollback. It
++** syncs the journal file to disk, then sets pPager->journalHdr to the
++** size of the journal file so that the pager_playback() routine knows
++** that the entire journal file has been synced.
++**
++** Syncing a hot-journal to disk before attempting to roll it back ensures 
++** that if a power-failure occurs during the rollback, the process that
++** attempts rollback following system recovery sees the same journal
++** content as this process.
++**
++** If everything goes as planned, SQLITE_OK is returned. Otherwise, 
++** an SQLite error code.
++*/
++static int pagerSyncHotJournal(Pager *pPager){
++  int rc = SQLITE_OK;
++  if( !pPager->noSync ){
++    rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_NORMAL);
++  }
++  if( rc==SQLITE_OK ){
++    rc = sqlite3OsFileSize(pPager->jfd, &pPager->journalHdr);
++  }
++  return rc;
++}
++
++/*
++** Obtain a reference to a memory mapped page object for page number pgno. 
++** The new object will use the pointer pData, obtained from xFetch().
++** If successful, set *ppPage to point to the new page reference
++** and return SQLITE_OK. Otherwise, return an SQLite error code and set
++** *ppPage to zero.
++**
++** Page references obtained by calling this function should be released
++** by calling pagerReleaseMapPage().
++*/
++static int pagerAcquireMapPage(
++  Pager *pPager,                  /* Pager object */
++  Pgno pgno,                      /* Page number */
++  void *pData,                    /* xFetch()'d data for this page */
++  PgHdr **ppPage                  /* OUT: Acquired page object */
++){
++  PgHdr *p;                       /* Memory mapped page to return */
++  
++  if( pPager->pMmapFreelist ){
++    *ppPage = p = pPager->pMmapFreelist;
++    pPager->pMmapFreelist = p->pDirty;
++    p->pDirty = 0;
++    memset(p->pExtra, 0, pPager->nExtra);
++  }else{
++    *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra);
++    if( p==0 ){
++      sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData);
++      return SQLITE_NOMEM;
++    }
++    p->pExtra = (void *)&p[1];
++    p->flags = PGHDR_MMAP;
++    p->nRef = 1;
++    p->pPager = pPager;
+   }
+ 
+-  if( pagerUseWal(pPager) ){
+-    assert( rc==SQLITE_OK );
+-    rc = pagerBeginReadTransaction(pPager);
+-  }
++  assert( p->pExtra==(void *)&p[1] );
++  assert( p->pPage==0 );
++  assert( p->flags==PGHDR_MMAP );
++  assert( p->pPager==pPager );
++  assert( p->nRef==1 );
+ 
+-  if( pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){
+-    rc = pagerPagecount(pPager, &pPager->dbSize);
+-  }
++  p->pgno = pgno;
++  p->pData = pData;
++  pPager->nMmapOut++;
+ 
+- failed:
+-  if( rc!=SQLITE_OK ){
+-    assert( !MEMDB );
+-    pager_unlock(pPager);
+-    assert( pPager->eState==PAGER_OPEN );
+-  }else{
+-    pPager->eState = PAGER_READER;
+-  }
+-  return rc;
++  return SQLITE_OK;
+ }
+ 
+ /*
+-** If the reference count has reached zero, rollback any active
+-** transaction and unlock the pager.
+-**
+-** Except, in locking_mode=EXCLUSIVE when there is nothing to in
+-** the rollback journal, the unlock is not performed and there is
+-** nothing to rollback, so this routine is a no-op.
+-*/ 
+-static void pagerUnlockIfUnused(Pager *pPager){
+-  if( pPager->nMmapOut==0 && (sqlite3PcacheRefCount(pPager->pPCache)==0) ){
+-    pagerUnlockAndRollback(pPager);
++** Release a reference to page pPg. pPg must have been returned by an 
++** earlier call to pagerAcquireMapPage().
++*/
++static void pagerReleaseMapPage(PgHdr *pPg){
++  Pager *pPager = pPg->pPager;
++  pPager->nMmapOut--;
++  pPg->pDirty = pPager->pMmapFreelist;
++  pPager->pMmapFreelist = pPg;
++
++  assert( pPager->fd->pMethods->iVersion>=3 );
++  sqlite3OsUnfetch(pPager->fd, (i64)(pPg->pgno-1)*pPager->pageSize, pPg->pData);
++}
++
++/*
++** Free all PgHdr objects stored in the Pager.pMmapFreelist list.
++*/
++static void pagerFreeMapHdrs(Pager *pPager){
++  PgHdr *p;
++  PgHdr *pNext;
++  for(p=pPager->pMmapFreelist; p; p=pNext){
++    pNext = p->pDirty;
++    sqlite3_free(p);
+   }
+ }
+ 
++
+ /*
+-** Acquire a reference to page number pgno in pager pPager (a page
+-** reference has type DbPage*). If the requested reference is 
+-** successfully obtained, it is copied to *ppPage and SQLITE_OK returned.
+-**
+-** If the requested page is already in the cache, it is returned. 
+-** Otherwise, a new page object is allocated and populated with data
+-** read from the database file. In some cases, the pcache module may
+-** choose not to allocate a new page object and may reuse an existing
+-** object with no outstanding references.
+-**
+-** The extra data appended to a page is always initialized to zeros the 
+-** first time a page is loaded into memory. If the page requested is 
+-** already in the cache when this function is called, then the extra
+-** data is left as it was when the page object was last used.
+-**
+-** If the database image is smaller than the requested page or if a 
+-** non-zero value is passed as the noContent parameter and the 
+-** requested page is not already stored in the cache, then no 
+-** actual disk read occurs. In this case the memory image of the 
+-** page is initialized to all zeros. 
+-**
+-** If noContent is true, it means that we do not care about the contents
+-** of the page. This occurs in two scenarios:
+-**
+-**   a) When reading a free-list leaf page from the database, and
+-**
+-**   b) When a savepoint is being rolled back and we need to load
+-**      a new page into the cache to be filled with the data read
+-**      from the savepoint journal.
+-**
+-** If noContent is true, then the data returned is zeroed instead of
+-** being read from the database. Additionally, the bits corresponding
+-** to pgno in Pager.pInJournal (bitvec of pages already written to the
+-** journal file) and the PagerSavepoint.pInSavepoint bitvecs of any open
+-** savepoints are set. This means if the page is made writable at any
+-** point in the future, using a call to sqlite3PagerWrite(), its contents
+-** will not be journaled. This saves IO.
++** Shutdown the page cache.  Free all memory and close all files.
+ **
+-** The acquisition might fail for several reasons.  In all cases,
+-** an appropriate error code is returned and *ppPage is set to NULL.
++** If a transaction was in progress when this routine is called, that
++** transaction is rolled back.  All outstanding pages are invalidated
++** and their memory is freed.  Any attempt to use a page associated
++** with this page cache after this function returns will likely
++** result in a coredump.
+ **
+-** See also sqlite3PagerLookup().  Both this routine and Lookup() attempt
+-** to find a page in the in-memory cache first.  If the page is not already
+-** in memory, this routine goes to disk to read it in whereas Lookup()
+-** just returns 0.  This routine acquires a read-lock the first time it
+-** has to go to disk, and could also playback an old journal if necessary.
+-** Since Lookup() never goes to disk, it never has to deal with locks
+-** or journal files.
++** This function always succeeds. If a transaction is active an attempt
++** is made to roll it back. If an error occurs during the rollback 
++** a hot journal may be left in the filesystem but no error is returned
++** to the caller.
+ */
+-SQLITE_PRIVATE int sqlite3PagerAcquire(
+-  Pager *pPager,      /* The pager open on the database file */
+-  Pgno pgno,          /* Page number to fetch */
+-  DbPage **ppPage,    /* Write a pointer to the page here */
+-  int flags           /* PAGER_GET_XXX flags */
+-){
+-  int rc = SQLITE_OK;
+-  PgHdr *pPg = 0;
+-  u32 iFrame = 0;                 /* Frame to read from WAL file */
+-  const int noContent = (flags & PAGER_GET_NOCONTENT);
+-
+-  /* It is acceptable to use a read-only (mmap) page for any page except
+-  ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY
+-  ** flag was specified by the caller. And so long as the db is not a 
+-  ** temporary or in-memory database.  */
+-  const int bMmapOk = (pgno!=1 && USEFETCH(pPager)
+-   && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY))
+-#ifdef SQLITE_HAS_CODEC
+-   && pPager->xCodec==0
+-#endif
+-  );
++SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager){
++  u8 *pTmp = (u8 *)pPager->pTmpSpace;
+ 
+-  assert( pPager->eState>=PAGER_READER );
+   assert( assert_pager_state(pPager) );
+-  assert( noContent==0 || bMmapOk==0 );
+-
+-  if( pgno==0 ){
+-    return SQLITE_CORRUPT_BKPT;
+-  }
+-  pPager->hasBeenUsed = 1;
+-
+-  /* If the pager is in the error state, return an error immediately. 
+-  ** Otherwise, request the page from the PCache layer. */
+-  if( pPager->errCode!=SQLITE_OK ){
+-    rc = pPager->errCode;
++  disable_simulated_io_errors();
++  sqlite3BeginBenignMalloc();
++  pagerFreeMapHdrs(pPager);
++  /* pPager->errCode = 0; */
++  pPager->exclusiveMode = 0;
++#ifndef SQLITE_OMIT_WAL
++  sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags, pPager->pageSize, pTmp);
++  pPager->pWal = 0;
++#endif
++  pager_reset(pPager);
++  if( MEMDB ){
++    pager_unlock(pPager);
+   }else{
+-    if( bMmapOk && pagerUseWal(pPager) ){
+-      rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
+-      if( rc!=SQLITE_OK ) goto pager_acquire_err;
+-    }
+-
+-    if( bMmapOk && iFrame==0 ){
+-      void *pData = 0;
+-
+-      rc = sqlite3OsFetch(pPager->fd, 
+-          (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData
+-      );
+-
+-      if( rc==SQLITE_OK && pData ){
+-        if( pPager->eState>PAGER_READER ){
+-          pPg = sqlite3PagerLookup(pPager, pgno);
+-        }
+-        if( pPg==0 ){
+-          rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
+-        }else{
+-          sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
+-        }
+-        if( pPg ){
+-          assert( rc==SQLITE_OK );
+-          *ppPage = pPg;
+-          return SQLITE_OK;
+-        }
+-      }
+-      if( rc!=SQLITE_OK ){
+-        goto pager_acquire_err;
+-      }
+-    }
+-
+-    {
+-      sqlite3_pcache_page *pBase;
+-      pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3);
+-      if( pBase==0 ){
+-        rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase);
+-        if( rc!=SQLITE_OK ) goto pager_acquire_err;
+-      }
+-      pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase);
+-      if( pPg==0 ) rc = SQLITE_NOMEM;
++    /* If it is open, sync the journal file before calling UnlockAndRollback.
++    ** If this is not done, then an unsynced portion of the open journal 
++    ** file may be played back into the database. If a power failure occurs 
++    ** while this is happening, the database could become corrupt.
++    **
++    ** If an error occurs while trying to sync the journal, shift the pager
++    ** into the ERROR state. This causes UnlockAndRollback to unlock the
++    ** database and close the journal file without attempting to roll it
++    ** back or finalize it. The next database user will have to do hot-journal
++    ** rollback before accessing the database file.
++    */
++    if( isOpen(pPager->jfd) ){
++      pager_error(pPager, pagerSyncHotJournal(pPager));
+     }
++    pagerUnlockAndRollback(pPager);
+   }
++  sqlite3EndBenignMalloc();
++  enable_simulated_io_errors();
++  PAGERTRACE(("CLOSE %d\n", PAGERID(pPager)));
++  IOTRACE(("CLOSE %p\n", pPager))
++  sqlite3OsClose(pPager->jfd);
++  sqlite3OsClose(pPager->fd);
++  sqlite3PageFree(pTmp);
++  sqlite3PcacheClose(pPager->pPCache);
+ 
+-  if( rc!=SQLITE_OK ){
+-    /* Either the call to sqlite3PcacheFetch() returned an error or the
+-    ** pager was already in the error-state when this function was called.
+-    ** Set pPg to 0 and jump to the exception handler.  */
+-    pPg = 0;
+-    goto pager_acquire_err;
+-  }
+-  assert( (*ppPage)->pgno==pgno );
+-  assert( (*ppPage)->pPager==pPager || (*ppPage)->pPager==0 );
+-
+-  if( (*ppPage)->pPager && !noContent ){
+-    /* In this case the pcache already contains an initialized copy of
+-    ** the page. Return without further ado.  */
+-    assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) );
+-    pPager->aStat[PAGER_STAT_HIT]++;
+-    return SQLITE_OK;
+-
+-  }else{
+-    /* The pager cache has created a new page. Its content needs to 
+-    ** be initialized.  */
+-
+-    pPg = *ppPage;
+-    pPg->pPager = pPager;
+-
+-    /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
+-    ** number greater than this, or the unused locking-page, is requested. */
+-    if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){
+-      rc = SQLITE_CORRUPT_BKPT;
+-      goto pager_acquire_err;
+-    }
++#ifdef SQLITE_HAS_CODEC
++  if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
++#endif
+ 
+-    if( MEMDB || pPager->dbSize<pgno || noContent || !isOpen(pPager->fd) ){
+-      if( pgno>pPager->mxPgno ){
+-        rc = SQLITE_FULL;
+-        goto pager_acquire_err;
+-      }
+-      if( noContent ){
+-        /* Failure to set the bits in the InJournal bit-vectors is benign.
+-        ** It merely means that we might do some extra work to journal a 
+-        ** page that does not need to be journaled.  Nevertheless, be sure 
+-        ** to test the case where a malloc error occurs while trying to set 
+-        ** a bit in a bit vector.
+-        */
+-        sqlite3BeginBenignMalloc();
+-        if( pgno<=pPager->dbOrigSize ){
+-          TESTONLY( rc = ) sqlite3BitvecSet(pPager->pInJournal, pgno);
+-          testcase( rc==SQLITE_NOMEM );
+-        }
+-        TESTONLY( rc = ) addToSavepointBitvecs(pPager, pgno);
+-        testcase( rc==SQLITE_NOMEM );
+-        sqlite3EndBenignMalloc();
+-      }
+-      memset(pPg->pData, 0, pPager->pageSize);
+-      IOTRACE(("ZERO %p %d\n", pPager, pgno));
+-    }else{
+-      if( pagerUseWal(pPager) && bMmapOk==0 ){
+-        rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
+-        if( rc!=SQLITE_OK ) goto pager_acquire_err;
+-      }
+-      assert( pPg->pPager==pPager );
+-      pPager->aStat[PAGER_STAT_MISS]++;
+-      rc = readDbPage(pPg, iFrame);
+-      if( rc!=SQLITE_OK ){
+-        goto pager_acquire_err;
+-      }
+-    }
+-    pager_set_pagehash(pPg);
+-  }
++  assert( !pPager->aSavepoint && !pPager->pInJournal );
++  assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) );
+ 
++  sqlite3_free(pPager);
+   return SQLITE_OK;
+-
+-pager_acquire_err:
+-  assert( rc!=SQLITE_OK );
+-  if( pPg ){
+-    sqlite3PcacheDrop(pPg);
+-  }
+-  pagerUnlockIfUnused(pPager);
+-
+-  *ppPage = 0;
+-  return rc;
+ }
+ 
++#if !defined(NDEBUG) || defined(SQLITE_TEST)
+ /*
+-** Acquire a page if it is already in the in-memory cache.  Do
+-** not read the page from disk.  Return a pointer to the page,
+-** or 0 if the page is not in cache. 
+-**
+-** See also sqlite3PagerGet().  The difference between this routine
+-** and sqlite3PagerGet() is that _get() will go to the disk and read
+-** in the page if the page is not already in cache.  This routine
+-** returns NULL if the page is not in cache or if a disk I/O error 
+-** has ever happened.
++** Return the page number for page pPg.
+ */
+-SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
+-  sqlite3_pcache_page *pPage;
+-  assert( pPager!=0 );
+-  assert( pgno!=0 );
+-  assert( pPager->pPCache!=0 );
+-  pPage = sqlite3PcacheFetch(pPager->pPCache, pgno, 0);
+-  assert( pPage==0 || pPager->hasBeenUsed );
+-  return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage);
++SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage *pPg){
++  return pPg->pgno;
+ }
++#endif
+ 
+ /*
+-** Release a page reference.
+-**
+-** If the number of references to the page drop to zero, then the
+-** page is added to the LRU list.  When all references to all pages
+-** are released, a rollback occurs and the lock on the database is
+-** removed.
++** Increment the reference count for page pPg.
+ */
+-SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage *pPg){
+-  Pager *pPager;
+-  assert( pPg!=0 );
+-  pPager = pPg->pPager;
+-  if( pPg->flags & PGHDR_MMAP ){
+-    pagerReleaseMapPage(pPg);
+-  }else{
+-    sqlite3PcacheRelease(pPg);
+-  }
+-  pagerUnlockIfUnused(pPager);
+-}
+-SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){
+-  if( pPg ) sqlite3PagerUnrefNotNull(pPg);
++SQLITE_PRIVATE void sqlite3PagerRef(DbPage *pPg){
++  sqlite3PcacheRef(pPg);
+ }
+ 
+ /*
+-** This function is called at the start of every write transaction.
+-** There must already be a RESERVED or EXCLUSIVE lock on the database 
+-** file when this routine is called.
++** Sync the journal. In other words, make sure all the pages that have
++** been written to the journal have actually reached the surface of the
++** disk and can be restored in the event of a hot-journal rollback.
+ **
+-** Open the journal file for pager pPager and write a journal header
+-** to the start of it. If there are active savepoints, open the sub-journal
+-** as well. This function is only used when the journal file is being 
+-** opened to write a rollback log for a transaction. It is not used 
+-** when opening a hot journal file to roll it back.
++** If the Pager.noSync flag is set, then this function is a no-op.
++** Otherwise, the actions required depend on the journal-mode and the 
++** device characteristics of the file-system, as follows:
+ **
+-** If the journal file is already open (as it may be in exclusive mode),
+-** then this function just writes a journal header to the start of the
+-** already open file. 
++**   * If the journal file is an in-memory journal file, no action need
++**     be taken.
+ **
+-** Whether or not the journal file is opened by this function, the
+-** Pager.pInJournal bitvec structure is allocated.
++**   * Otherwise, if the device does not support the SAFE_APPEND property,
++**     then the nRec field of the most recently written journal header
++**     is updated to contain the number of journal records that have
++**     been written following it. If the pager is operating in full-sync
++**     mode, then the journal file is synced before this field is updated.
+ **
+-** Return SQLITE_OK if everything is successful. Otherwise, return 
+-** SQLITE_NOMEM if the attempt to allocate Pager.pInJournal fails, or 
+-** an IO error code if opening or writing the journal file fails.
++**   * If the device does not support the SEQUENTIAL property, then 
++**     journal file is synced.
++**
++** Or, in pseudo-code:
++**
++**   if( NOT <in-memory journal> ){
++**     if( NOT SAFE_APPEND ){
++**       if( <full-sync mode> ) xSync(<journal file>);
++**       <update nRec field>
++**     } 
++**     if( NOT SEQUENTIAL ) xSync(<journal file>);
++**   }
++**
++** If successful, this routine clears the PGHDR_NEED_SYNC flag of every 
++** page currently held in memory before returning SQLITE_OK. If an IO
++** error is encountered, then the IO error code is returned to the caller.
+ */
+-static int pager_open_journal(Pager *pPager){
+-  int rc = SQLITE_OK;                        /* Return code */
+-  sqlite3_vfs * const pVfs = pPager->pVfs;   /* Local cache of vfs pointer */
++static int syncJournal(Pager *pPager, int newHdr){
++  int rc;                         /* Return code */
+ 
+-  assert( pPager->eState==PAGER_WRITER_LOCKED );
++  assert( pPager->eState==PAGER_WRITER_CACHEMOD
++       || pPager->eState==PAGER_WRITER_DBMOD
++  );
+   assert( assert_pager_state(pPager) );
+-  assert( pPager->pInJournal==0 );
+-  
+-  /* If already in the error state, this function is a no-op.  But on
+-  ** the other hand, this routine is never called if we are already in
+-  ** an error state. */
+-  if( NEVER(pPager->errCode) ) return pPager->errCode;
++  assert( !pagerUseWal(pPager) );
+ 
+-  if( !pagerUseWal(pPager) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
+-    pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize);
+-    if( pPager->pInJournal==0 ){
+-      return SQLITE_NOMEM;
+-    }
+-  
+-    /* Open the journal file if it is not already open. */
+-    if( !isOpen(pPager->jfd) ){
+-      if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){
+-        sqlite3MemJournalOpen(pPager->jfd);
+-      }else{
+-        const int flags =                   /* VFS flags to open journal file */
+-          SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
+-          (pPager->tempFile ? 
+-            (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL):
+-            (SQLITE_OPEN_MAIN_JOURNAL)
+-          );
++  rc = sqlite3PagerExclusiveLock(pPager);
++  if( rc!=SQLITE_OK ) return rc;
+ 
+-        /* Verify that the database still has the same name as it did when
+-        ** it was originally opened. */
+-        rc = databaseIsUnmoved(pPager);
+-        if( rc==SQLITE_OK ){
+-#ifdef SQLITE_ENABLE_ATOMIC_WRITE
+-          rc = sqlite3JournalOpen(
+-              pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager)
+-          );
+-#else
+-          rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
+-#endif
++  if( !pPager->noSync ){
++    assert( !pPager->tempFile );
++    if( isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){
++      const int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
++      assert( isOpen(pPager->jfd) );
++
++      if( 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){
++        /* This block deals with an obscure problem. If the last connection
++        ** that wrote to this database was operating in persistent-journal
++        ** mode, then the journal file may at this point actually be larger
++        ** than Pager.journalOff bytes. If the next thing in the journal
++        ** file happens to be a journal-header (written as part of the
++        ** previous connection's transaction), and a crash or power-failure 
++        ** occurs after nRec is updated but before this connection writes 
++        ** anything else to the journal file (or commits/rolls back its 
++        ** transaction), then SQLite may become confused when doing the 
++        ** hot-journal rollback following recovery. It may roll back all
++        ** of this connections data, then proceed to rolling back the old,
++        ** out-of-date data that follows it. Database corruption.
++        **
++        ** To work around this, if the journal file does appear to contain
++        ** a valid header following Pager.journalOff, then write a 0x00
++        ** byte to the start of it to prevent it from being recognized.
++        **
++        ** Variable iNextHdrOffset is set to the offset at which this
++        ** problematic header will occur, if it exists. aMagic is used 
++        ** as a temporary buffer to inspect the first couple of bytes of
++        ** the potential journal header.
++        */
++        i64 iNextHdrOffset;
++        u8 aMagic[8];
++        u8 zHeader[sizeof(aJournalMagic)+4];
++
++        memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic));
++        put32bits(&zHeader[sizeof(aJournalMagic)], pPager->nRec);
++
++        iNextHdrOffset = journalHdrOffset(pPager);
++        rc = sqlite3OsRead(pPager->jfd, aMagic, 8, iNextHdrOffset);
++        if( rc==SQLITE_OK && 0==memcmp(aMagic, aJournalMagic, 8) ){
++          static const u8 zerobyte = 0;
++          rc = sqlite3OsWrite(pPager->jfd, &zerobyte, 1, iNextHdrOffset);
++        }
++        if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
++          return rc;
++        }
++
++        /* Write the nRec value into the journal file header. If in
++        ** full-synchronous mode, sync the journal first. This ensures that
++        ** all data has really hit the disk before nRec is updated to mark
++        ** it as a candidate for rollback.
++        **
++        ** This is not required if the persistent media supports the
++        ** SAFE_APPEND property. Because in this case it is not possible 
++        ** for garbage data to be appended to the file, the nRec field
++        ** is populated with 0xFFFFFFFF when the journal header is written
++        ** and never needs to be updated.
++        */
++        if( pPager->fullSync && 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){
++          PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager)));
++          IOTRACE(("JSYNC %p\n", pPager))
++          rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags);
++          if( rc!=SQLITE_OK ) return rc;
+         }
++        IOTRACE(("JHDR %p %lld\n", pPager, pPager->journalHdr));
++        rc = sqlite3OsWrite(
++            pPager->jfd, zHeader, sizeof(zHeader), pPager->journalHdr
++        );
++        if( rc!=SQLITE_OK ) return rc;
++      }
++      if( 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){
++        PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager)));
++        IOTRACE(("JSYNC %p\n", pPager))
++        rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags| 
++          (pPager->syncFlags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0)
++        );
++        if( rc!=SQLITE_OK ) return rc;
+       }
+-      assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
+-    }
+-  
+-  
+-    /* Write the first journal header to the journal file and open 
+-    ** the sub-journal if necessary.
+-    */
+-    if( rc==SQLITE_OK ){
+-      /* TODO: Check if all of these are really required. */
+-      pPager->nRec = 0;
+-      pPager->journalOff = 0;
+-      pPager->setMaster = 0;
+-      pPager->journalHdr = 0;
+-      rc = writeJournalHdr(pPager);
+-    }
+-  }
+ 
+-  if( rc!=SQLITE_OK ){
+-    sqlite3BitvecDestroy(pPager->pInJournal);
+-    pPager->pInJournal = 0;
+-  }else{
+-    assert( pPager->eState==PAGER_WRITER_LOCKED );
+-    pPager->eState = PAGER_WRITER_CACHEMOD;
++      pPager->journalHdr = pPager->journalOff;
++      if( newHdr && 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){
++        pPager->nRec = 0;
++        rc = writeJournalHdr(pPager);
++        if( rc!=SQLITE_OK ) return rc;
++      }
++    }else{
++      pPager->journalHdr = pPager->journalOff;
++    }
+   }
+ 
+-  return rc;
++  /* Unless the pager is in noSync mode, the journal file was just 
++  ** successfully synced. Either way, clear the PGHDR_NEED_SYNC flag on 
++  ** all pages.
++  */
++  sqlite3PcacheClearSyncFlags(pPager->pPCache);
++  pPager->eState = PAGER_WRITER_DBMOD;
++  assert( assert_pager_state(pPager) );
++  return SQLITE_OK;
+ }
+ 
+ /*
+-** Begin a write-transaction on the specified pager object. If a 
+-** write-transaction has already been opened, this function is a no-op.
++** The argument is the first in a linked list of dirty pages connected
++** by the PgHdr.pDirty pointer. This function writes each one of the
++** in-memory pages in the list to the database file. The argument may
++** be NULL, representing an empty list. In this case this function is
++** a no-op.
+ **
+-** If the exFlag argument is false, then acquire at least a RESERVED
+-** lock on the database file. If exFlag is true, then acquire at least
+-** an EXCLUSIVE lock. If such a lock is already held, no locking 
+-** functions need be called.
++** The pager must hold at least a RESERVED lock when this function
++** is called. Before writing anything to the database file, this lock
++** is upgraded to an EXCLUSIVE lock. If the lock cannot be obtained,
++** SQLITE_BUSY is returned and no data is written to the database file.
++** 
++** If the pager is a temp-file pager and the actual file-system file
++** is not yet open, it is created and opened before any data is 
++** written out.
+ **
+-** If the subjInMemory argument is non-zero, then any sub-journal opened
+-** within this transaction will be opened as an in-memory file. This
+-** has no effect if the sub-journal is already opened (as it may be when
+-** running in exclusive mode) or if the transaction does not require a
+-** sub-journal. If the subjInMemory argument is zero, then any required
+-** sub-journal is implemented in-memory if pPager is an in-memory database, 
+-** or using a temporary file otherwise.
++** Once the lock has been upgraded and, if necessary, the file opened,
++** the pages are written out to the database file in list order. Writing
++** a page is skipped if it meets either of the following criteria:
++**
++**   * The page number is greater than Pager.dbSize, or
++**   * The PGHDR_DONT_WRITE flag is set on the page.
++**
++** If writing out a page causes the database file to grow, Pager.dbFileSize
++** is updated accordingly. If page 1 is written out, then the value cached
++** in Pager.dbFileVers[] is updated to match the new value stored in
++** the database file.
++**
++** If everything is successful, SQLITE_OK is returned. If an IO error 
++** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot
++** be obtained, SQLITE_BUSY is returned.
+ */
+-SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){
+-  int rc = SQLITE_OK;
++static int pager_write_pagelist(Pager *pPager, PgHdr *pList){
++  int rc = SQLITE_OK;                  /* Return code */
+ 
+-  if( pPager->errCode ) return pPager->errCode;
+-  assert( pPager->eState>=PAGER_READER && pPager->eState<PAGER_ERROR );
+-  pPager->subjInMemory = (u8)subjInMemory;
++  /* This function is only called for rollback pagers in WRITER_DBMOD state. */
++  assert( !pagerUseWal(pPager) );
++  assert( pPager->eState==PAGER_WRITER_DBMOD );
++  assert( pPager->eLock==EXCLUSIVE_LOCK );
+ 
+-  if( ALWAYS(pPager->eState==PAGER_READER) ){
+-    assert( pPager->pInJournal==0 );
++  /* If the file is a temp-file has not yet been opened, open it now. It
++  ** is not possible for rc to be other than SQLITE_OK if this branch
++  ** is taken, as pager_wait_on_lock() is a no-op for temp-files.
++  */
++  if( !isOpen(pPager->fd) ){
++    assert( pPager->tempFile && rc==SQLITE_OK );
++    rc = pagerOpentemp(pPager, pPager->fd, pPager->vfsFlags);
++  }
+ 
+-    if( pagerUseWal(pPager) ){
+-      /* If the pager is configured to use locking_mode=exclusive, and an
+-      ** exclusive lock on the database is not already held, obtain it now.
+-      */
+-      if( pPager->exclusiveMode && sqlite3WalExclusiveMode(pPager->pWal, -1) ){
+-        rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
+-        if( rc!=SQLITE_OK ){
+-          return rc;
+-        }
+-        sqlite3WalExclusiveMode(pPager->pWal, 1);
+-      }
++  /* Before the first write, give the VFS a hint of what the final
++  ** file size will be.
++  */
++  assert( rc!=SQLITE_OK || isOpen(pPager->fd) );
++  if( rc==SQLITE_OK 
++   && pPager->dbHintSize<pPager->dbSize
++   && (pList->pDirty || pList->pgno>pPager->dbHintSize)
++  ){
++    sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize;
++    sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile);
++    pPager->dbHintSize = pPager->dbSize;
++  }
+ 
+-      /* Grab the write lock on the log file. If successful, upgrade to
+-      ** PAGER_RESERVED state. Otherwise, return an error code to the caller.
+-      ** The busy-handler is not invoked if another connection already
+-      ** holds the write-lock. If possible, the upper layer will call it.
+-      */
+-      rc = sqlite3WalBeginWriteTransaction(pPager->pWal);
+-    }else{
+-      /* Obtain a RESERVED lock on the database file. If the exFlag parameter
+-      ** is true, then immediately upgrade this to an EXCLUSIVE lock. The
+-      ** busy-handler callback can be used when upgrading to the EXCLUSIVE
+-      ** lock, but not when obtaining the RESERVED lock.
++  while( rc==SQLITE_OK && pList ){
++    Pgno pgno = pList->pgno;
++
++    /* If there are dirty pages in the page cache with page numbers greater
++    ** than Pager.dbSize, this means sqlite3PagerTruncateImage() was called to
++    ** make the file smaller (presumably by auto-vacuum code). Do not write
++    ** any such pages to the file.
++    **
++    ** Also, do not write out any page that has the PGHDR_DONT_WRITE flag
++    ** set (set by sqlite3PagerDontWrite()).
++    */
++    if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){
++      i64 offset = (pgno-1)*(i64)pPager->pageSize;   /* Offset to write */
++      char *pData;                                   /* Data to write */    
++
++      assert( (pList->flags&PGHDR_NEED_SYNC)==0 );
++      if( pList->pgno==1 ) pager_write_changecounter(pList);
++
++      /* Encode the database */
++      CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData);
++
++      /* Write out the page data. */
++      rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
++
++      /* If page 1 was just written, update Pager.dbFileVers to match
++      ** the value now stored in the database file. If writing this 
++      ** page caused the database file to grow, update dbFileSize. 
+       */
+-      rc = pagerLockDb(pPager, RESERVED_LOCK);
+-      if( rc==SQLITE_OK && exFlag ){
+-        rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
++      if( pgno==1 ){
++        memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers));
+       }
+-    }
++      if( pgno>pPager->dbFileSize ){
++        pPager->dbFileSize = pgno;
++      }
++      pPager->aStat[PAGER_STAT_WRITE]++;
+ 
+-    if( rc==SQLITE_OK ){
+-      /* Change to WRITER_LOCKED state.
+-      **
+-      ** WAL mode sets Pager.eState to PAGER_WRITER_LOCKED or CACHEMOD
+-      ** when it has an open transaction, but never to DBMOD or FINISHED.
+-      ** This is because in those states the code to roll back savepoint 
+-      ** transactions may copy data from the sub-journal into the database 
+-      ** file as well as into the page cache. Which would be incorrect in 
+-      ** WAL mode.
+-      */
+-      pPager->eState = PAGER_WRITER_LOCKED;
+-      pPager->dbHintSize = pPager->dbSize;
+-      pPager->dbFileSize = pPager->dbSize;
+-      pPager->dbOrigSize = pPager->dbSize;
+-      pPager->journalOff = 0;
+-    }
++      /* Update any backup objects copying the contents of this pager. */
++      sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)pList->pData);
+ 
+-    assert( rc==SQLITE_OK || pPager->eState==PAGER_READER );
+-    assert( rc!=SQLITE_OK || pPager->eState==PAGER_WRITER_LOCKED );
+-    assert( assert_pager_state(pPager) );
++      PAGERTRACE(("STORE %d page %d hash(%08x)\n",
++                   PAGERID(pPager), pgno, pager_pagehash(pList)));
++      IOTRACE(("PGOUT %p %d\n", pPager, pgno));
++      PAGER_INCR(sqlite3_pager_writedb_count);
++    }else{
++      PAGERTRACE(("NOSTORE %d page %d\n", PAGERID(pPager), pgno));
++    }
++    pager_set_pagehash(pList);
++    pList = pList->pDirty;
+   }
+ 
+-  PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager)));
+   return rc;
+ }
+ 
+ /*
+-** Mark a single data page as writeable. The page is written into the 
+-** main journal or sub-journal as required. If the page is written into
+-** one of the journals, the corresponding bit is set in the 
+-** Pager.pInJournal bitvec and the PagerSavepoint.pInSavepoint bitvecs
+-** of any open savepoints as appropriate.
++** Ensure that the sub-journal file is open. If it is already open, this 
++** function is a no-op.
++**
++** SQLITE_OK is returned if everything goes according to plan. An 
++** SQLITE_IOERR_XXX error code is returned if a call to sqlite3OsOpen() 
++** fails.
+ */
+-static int pager_write(PgHdr *pPg){
+-  Pager *pPager = pPg->pPager;
++static int openSubJournal(Pager *pPager){
+   int rc = SQLITE_OK;
+-  int inJournal;
+-
+-  /* This routine is not called unless a write-transaction has already 
+-  ** been started. The journal file may or may not be open at this point.
+-  ** It is never called in the ERROR state.
+-  */
+-  assert( pPager->eState==PAGER_WRITER_LOCKED
+-       || pPager->eState==PAGER_WRITER_CACHEMOD
+-       || pPager->eState==PAGER_WRITER_DBMOD
+-  );
+-  assert( assert_pager_state(pPager) );
+-  assert( pPager->errCode==0 );
+-  assert( pPager->readOnly==0 );
+-
+-  CHECK_PAGE(pPg);
+-
+-  /* The journal file needs to be opened. Higher level routines have already
+-  ** obtained the necessary locks to begin the write-transaction, but the
+-  ** rollback journal might not yet be open. Open it now if this is the case.
+-  **
+-  ** This is done before calling sqlite3PcacheMakeDirty() on the page. 
+-  ** Otherwise, if it were done after calling sqlite3PcacheMakeDirty(), then
+-  ** an error might occur and the pager would end up in WRITER_LOCKED state
+-  ** with pages marked as dirty in the cache.
+-  */
+-  if( pPager->eState==PAGER_WRITER_LOCKED ){
+-    rc = pager_open_journal(pPager);
+-    if( rc!=SQLITE_OK ) return rc;
++  if( !isOpen(pPager->sjfd) ){
++    if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){
++      sqlite3MemJournalOpen(pPager->sjfd);
++    }else{
++      rc = pagerOpentemp(pPager, pPager->sjfd, SQLITE_OPEN_SUBJOURNAL);
++    }
+   }
+-  assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
+-  assert( assert_pager_state(pPager) );
+-
+-  /* Mark the page as dirty.  If the page has already been written
+-  ** to the journal then we can return right away.
+-  */
+-  sqlite3PcacheMakeDirty(pPg);
+-  inJournal = pageInJournal(pPager, pPg);
+-  if( inJournal && (pPager->nSavepoint==0 || !subjRequiresPage(pPg)) ){
+-    assert( !pagerUseWal(pPager) );
+-  }else{
+-  
+-    /* The transaction journal now exists and we have a RESERVED or an
+-    ** EXCLUSIVE lock on the main database file.  Write the current page to
+-    ** the transaction journal if it is not there already.
+-    */
+-    if( !inJournal && !pagerUseWal(pPager) ){
+-      assert( pagerUseWal(pPager)==0 );
+-      if( pPg->pgno<=pPager->dbOrigSize && isOpen(pPager->jfd) ){
+-        u32 cksum;
+-        char *pData2;
+-        i64 iOff = pPager->journalOff;
+-
+-        /* We should never write to the journal file the page that
+-        ** contains the database locks.  The following assert verifies
+-        ** that we do not. */
+-        assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
+-
+-        assert( pPager->journalHdr<=pPager->journalOff );
+-        CODEC2(pPager, pPg->pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
+-        cksum = pager_cksum(pPager, (u8*)pData2);
+-
+-        /* Even if an IO or diskfull error occurs while journalling the
+-        ** page in the block above, set the need-sync flag for the page.
+-        ** Otherwise, when the transaction is rolled back, the logic in
+-        ** playback_one_page() will think that the page needs to be restored
+-        ** in the database file. And if an IO error occurs while doing so,
+-        ** then corruption may follow.
+-        */
+-        pPg->flags |= PGHDR_NEED_SYNC;
++  return rc;
++}
+ 
+-        rc = write32bits(pPager->jfd, iOff, pPg->pgno);
+-        if( rc!=SQLITE_OK ) return rc;
+-        rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize, iOff+4);
+-        if( rc!=SQLITE_OK ) return rc;
+-        rc = write32bits(pPager->jfd, iOff+pPager->pageSize+4, cksum);
+-        if( rc!=SQLITE_OK ) return rc;
++/*
++** Append a record of the current state of page pPg to the sub-journal. 
++** It is the callers responsibility to use subjRequiresPage() to check 
++** that it is really required before calling this function.
++**
++** If successful, set the bit corresponding to pPg->pgno in the bitvecs
++** for all open savepoints before returning.
++**
++** This function returns SQLITE_OK if everything is successful, an IO
++** error code if the attempt to write to the sub-journal fails, or 
++** SQLITE_NOMEM if a malloc fails while setting a bit in a savepoint
++** bitvec.
++*/
++static int subjournalPage(PgHdr *pPg){
++  int rc = SQLITE_OK;
++  Pager *pPager = pPg->pPager;
++  if( pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
+ 
+-        IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, 
+-                 pPager->journalOff, pPager->pageSize));
+-        PAGER_INCR(sqlite3_pager_writej_count);
+-        PAGERTRACE(("JOURNAL %d page %d needSync=%d hash(%08x)\n",
+-             PAGERID(pPager), pPg->pgno, 
+-             ((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg)));
++    /* Open the sub-journal, if it has not already been opened */
++    assert( pPager->useJournal );
++    assert( isOpen(pPager->jfd) || pagerUseWal(pPager) );
++    assert( isOpen(pPager->sjfd) || pPager->nSubRec==0 );
++    assert( pagerUseWal(pPager) 
++         || pageInJournal(pPager, pPg) 
++         || pPg->pgno>pPager->dbOrigSize 
++    );
++    rc = openSubJournal(pPager);
+ 
+-        pPager->journalOff += 8 + pPager->pageSize;
+-        pPager->nRec++;
+-        assert( pPager->pInJournal!=0 );
+-        rc = sqlite3BitvecSet(pPager->pInJournal, pPg->pgno);
+-        testcase( rc==SQLITE_NOMEM );
+-        assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
+-        rc |= addToSavepointBitvecs(pPager, pPg->pgno);
+-        if( rc!=SQLITE_OK ){
+-          assert( rc==SQLITE_NOMEM );
+-          return rc;
+-        }
+-      }else{
+-        if( pPager->eState!=PAGER_WRITER_DBMOD ){
+-          pPg->flags |= PGHDR_NEED_SYNC;
+-        }
+-        PAGERTRACE(("APPEND %d page %d needSync=%d\n",
+-                PAGERID(pPager), pPg->pgno,
+-               ((pPg->flags&PGHDR_NEED_SYNC)?1:0)));
+-      }
+-    }
++    /* If the sub-journal was opened successfully (or was already open),
++    ** write the journal record into the file.  */
++    if( rc==SQLITE_OK ){
++      void *pData = pPg->pData;
++      i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize);
++      char *pData2;
+   
+-    /* If the statement journal is open and the page is not in it,
+-    ** then write the current page to the statement journal.  Note that
+-    ** the statement journal format differs from the standard journal format
+-    ** in that it omits the checksums and the header.
+-    */
+-    if( pPager->nSavepoint>0 && subjRequiresPage(pPg) ){
+-      rc = subjournalPage(pPg);
++      CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
++      PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
++      rc = write32bits(pPager->sjfd, offset, pPg->pgno);
++      if( rc==SQLITE_OK ){
++        rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4);
++      }
+     }
+   }
+-
+-  /* Update the database size and return.
+-  */
+-  if( pPager->dbSize<pPg->pgno ){
+-    pPager->dbSize = pPg->pgno;
++  if( rc==SQLITE_OK ){
++    pPager->nSubRec++;
++    assert( pPager->nSavepoint>0 );
++    rc = addToSavepointBitvecs(pPager, pPg->pgno);
+   }
+   return rc;
+ }
+ 
+ /*
+-** This is a variant of sqlite3PagerWrite() that runs when the sector size
+-** is larger than the page size.  SQLite makes the (reasonable) assumption that
+-** all bytes of a sector are written together by hardware.  Hence, all bytes of
+-** a sector need to be journalled in case of a power loss in the middle of
+-** a write.
++** This function is called by the pcache layer when it has reached some
++** soft memory limit. The first argument is a pointer to a Pager object
++** (cast as a void*). The pager is always 'purgeable' (not an in-memory
++** database). The second argument is a reference to a page that is 
++** currently dirty but has no outstanding references. The page
++** is always associated with the Pager object passed as the first 
++** argument.
+ **
+-** Usually, the sector size is less than or equal to the page size, in which
+-** case pages can be individually written.  This routine only runs in the exceptional
+-** case where the page size is smaller than the sector size.
++** The job of this function is to make pPg clean by writing its contents
++** out to the database file, if possible. This may involve syncing the
++** journal file. 
++**
++** If successful, sqlite3PcacheMakeClean() is called on the page and
++** SQLITE_OK returned. If an IO error occurs while trying to make the
++** page clean, the IO error code is returned. If the page cannot be
++** made clean for some other reason, but no error occurs, then SQLITE_OK
++** is returned by sqlite3PcacheMakeClean() is not called.
+ */
+-static SQLITE_NOINLINE int pagerWriteLargeSector(PgHdr *pPg){
+-  int rc = SQLITE_OK;            /* Return code */
+-  Pgno nPageCount;               /* Total number of pages in database file */
+-  Pgno pg1;                      /* First page of the sector pPg is located on. */
+-  int nPage = 0;                 /* Number of pages starting at pg1 to journal */
+-  int ii;                        /* Loop counter */
+-  int needSync = 0;              /* True if any page has PGHDR_NEED_SYNC */
+-  Pager *pPager = pPg->pPager;   /* The pager that owns pPg */
+-  Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
++static int pagerStress(void *p, PgHdr *pPg){
++  Pager *pPager = (Pager *)p;
++  int rc = SQLITE_OK;
+ 
+-  /* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow
+-  ** a journal header to be written between the pages journaled by
+-  ** this function.
+-  */
+-  assert( !MEMDB );
+-  assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)==0 );
+-  pPager->doNotSpill |= SPILLFLAG_NOSYNC;
++  assert( pPg->pPager==pPager );
++  assert( pPg->flags&PGHDR_DIRTY );
+ 
+-  /* This trick assumes that both the page-size and sector-size are
+-  ** an integer power of 2. It sets variable pg1 to the identifier
+-  ** of the first page of the sector pPg is located on.
++  /* The doNotSpill NOSYNC bit is set during times when doing a sync of
++  ** journal (and adding a new header) is not allowed.  This occurs
++  ** during calls to sqlite3PagerWrite() while trying to journal multiple
++  ** pages belonging to the same sector.
++  **
++  ** The doNotSpill ROLLBACK and OFF bits inhibits all cache spilling
++  ** regardless of whether or not a sync is required.  This is set during
++  ** a rollback or by user request, respectively.
++  **
++  ** Spilling is also prohibited when in an error state since that could
++  ** lead to database corruption.   In the current implementation it 
++  ** is impossible for sqlite3PcacheFetch() to be called with createFlag==3
++  ** while in the error state, hence it is impossible for this routine to
++  ** be called in the error state.  Nevertheless, we include a NEVER()
++  ** test for the error state as a safeguard against future changes.
+   */
+-  pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1;
+-
+-  nPageCount = pPager->dbSize;
+-  if( pPg->pgno>nPageCount ){
+-    nPage = (pPg->pgno - pg1)+1;
+-  }else if( (pg1+nPagePerSector-1)>nPageCount ){
+-    nPage = nPageCount+1-pg1;
+-  }else{
+-    nPage = nPagePerSector;
++  if( NEVER(pPager->errCode) ) return SQLITE_OK;
++  testcase( pPager->doNotSpill & SPILLFLAG_ROLLBACK );
++  testcase( pPager->doNotSpill & SPILLFLAG_OFF );
++  testcase( pPager->doNotSpill & SPILLFLAG_NOSYNC );
++  if( pPager->doNotSpill
++   && ((pPager->doNotSpill & (SPILLFLAG_ROLLBACK|SPILLFLAG_OFF))!=0
++      || (pPg->flags & PGHDR_NEED_SYNC)!=0)
++  ){
++    return SQLITE_OK;
+   }
+-  assert(nPage>0);
+-  assert(pg1<=pPg->pgno);
+-  assert((pg1+nPage)>pPg->pgno);
+ 
+-  for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){
+-    Pgno pg = pg1+ii;
+-    PgHdr *pPage;
+-    if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){
+-      if( pg!=PAGER_MJ_PGNO(pPager) ){
+-        rc = sqlite3PagerGet(pPager, pg, &pPage);
+-        if( rc==SQLITE_OK ){
+-          rc = pager_write(pPage);
+-          if( pPage->flags&PGHDR_NEED_SYNC ){
+-            needSync = 1;
+-          }
+-          sqlite3PagerUnrefNotNull(pPage);
+-        }
+-      }
+-    }else if( (pPage = sqlite3PagerLookup(pPager, pg))!=0 ){
+-      if( pPage->flags&PGHDR_NEED_SYNC ){
+-        needSync = 1;
+-      }
+-      sqlite3PagerUnrefNotNull(pPage);
++  pPg->pDirty = 0;
++  if( pagerUseWal(pPager) ){
++    /* Write a single frame for this page to the log. */
++    if( subjRequiresPage(pPg) ){ 
++      rc = subjournalPage(pPg); 
++    }
++    if( rc==SQLITE_OK ){
++      rc = pagerWalFrames(pPager, pPg, 0, 0);
++    }
++  }else{
++  
++    /* Sync the journal file if required. */
++    if( pPg->flags&PGHDR_NEED_SYNC 
++     || pPager->eState==PAGER_WRITER_CACHEMOD
++    ){
++      rc = syncJournal(pPager, 1);
++    }
++  
++    /* If the page number of this page is larger than the current size of
++    ** the database image, it may need to be written to the sub-journal.
++    ** This is because the call to pager_write_pagelist() below will not
++    ** actually write data to the file in this case.
++    **
++    ** Consider the following sequence of events:
++    **
++    **   BEGIN;
++    **     <journal page X>
++    **     <modify page X>
++    **     SAVEPOINT sp;
++    **       <shrink database file to Y pages>
++    **       pagerStress(page X)
++    **     ROLLBACK TO sp;
++    **
++    ** If (X>Y), then when pagerStress is called page X will not be written
++    ** out to the database file, but will be dropped from the cache. Then,
++    ** following the "ROLLBACK TO sp" statement, reading page X will read
++    ** data from the database file. This will be the copy of page X as it
++    ** was when the transaction started, not as it was when "SAVEPOINT sp"
++    ** was executed.
++    **
++    ** The solution is to write the current data for page X into the 
++    ** sub-journal file now (if it is not already there), so that it will
++    ** be restored to its current value when the "ROLLBACK TO sp" is 
++    ** executed.
++    */
++    if( NEVER(
++        rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg)
++    ) ){
++      rc = subjournalPage(pPg);
++    }
++  
++    /* Write the contents of the page out to the database file. */
++    if( rc==SQLITE_OK ){
++      assert( (pPg->flags&PGHDR_NEED_SYNC)==0 );
++      rc = pager_write_pagelist(pPager, pPg);
+     }
+   }
+ 
+-  /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages 
+-  ** starting at pg1, then it needs to be set for all of them. Because
+-  ** writing to any of these nPage pages may damage the others, the
+-  ** journal file must contain sync()ed copies of all of them
+-  ** before any of them can be written out to the database file.
+-  */
+-  if( rc==SQLITE_OK && needSync ){
+-    assert( !MEMDB );
+-    for(ii=0; ii<nPage; ii++){
+-      PgHdr *pPage = sqlite3PagerLookup(pPager, pg1+ii);
+-      if( pPage ){
+-        pPage->flags |= PGHDR_NEED_SYNC;
+-        sqlite3PagerUnrefNotNull(pPage);
+-      }
+-    }
++  /* Mark the page as clean. */
++  if( rc==SQLITE_OK ){
++    PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno));
++    sqlite3PcacheMakeClean(pPg);
+   }
+ 
+-  assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)!=0 );
+-  pPager->doNotSpill &= ~SPILLFLAG_NOSYNC;
+-  return rc;
++  return pager_error(pPager, rc); 
+ }
+ 
++
+ /*
+-** Mark a data page as writeable. This routine must be called before 
+-** making changes to a page. The caller must check the return value 
+-** of this function and be careful not to change any page data unless 
+-** this routine returns SQLITE_OK.
++** Allocate and initialize a new Pager object and put a pointer to it
++** in *ppPager. The pager should eventually be freed by passing it
++** to sqlite3PagerClose().
+ **
+-** The difference between this function and pager_write() is that this
+-** function also deals with the special case where 2 or more pages
+-** fit on a single disk sector. In this case all co-resident pages
+-** must have been written to the journal file before returning.
++** The zFilename argument is the path to the database file to open.
++** If zFilename is NULL then a randomly-named temporary file is created
++** and used as the file to be cached. Temporary files are be deleted
++** automatically when they are closed. If zFilename is ":memory:" then 
++** all information is held in cache. It is never written to disk. 
++** This can be used to implement an in-memory database.
+ **
+-** If an error occurs, SQLITE_NOMEM or an IO error code is returned
+-** as appropriate. Otherwise, SQLITE_OK.
++** The nExtra parameter specifies the number of bytes of space allocated
++** along with each page reference. This space is available to the user
++** via the sqlite3PagerGetExtra() API.
++**
++** The flags argument is used to specify properties that affect the
++** operation of the pager. It should be passed some bitwise combination
++** of the PAGER_* flags.
++**
++** The vfsFlags parameter is a bitmask to pass to the flags parameter
++** of the xOpen() method of the supplied VFS when opening files. 
++**
++** If the pager object is allocated and the specified file opened 
++** successfully, SQLITE_OK is returned and *ppPager set to point to
++** the new pager object. If an error occurs, *ppPager is set to NULL
++** and error code returned. This function may return SQLITE_NOMEM
++** (sqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or 
++** various SQLITE_IO_XXX errors.
+ */
+-SQLITE_PRIVATE int sqlite3PagerWrite(PgHdr *pPg){
+-  assert( (pPg->flags & PGHDR_MMAP)==0 );
+-  assert( pPg->pPager->eState>=PAGER_WRITER_LOCKED );
+-  assert( pPg->pPager->eState!=PAGER_ERROR );
+-  assert( assert_pager_state(pPg->pPager) );
+-  if( pPg->pPager->sectorSize > (u32)pPg->pPager->pageSize ){
+-    return pagerWriteLargeSector(pPg);
++SQLITE_PRIVATE int sqlite3PagerOpen(
++  sqlite3_vfs *pVfs,       /* The virtual file system to use */
++  Pager **ppPager,         /* OUT: Return the Pager structure here */
++  const char *zFilename,   /* Name of the database file to open */
++  int nExtra,              /* Extra bytes append to each in-memory page */
++  int flags,               /* flags controlling this file */
++  int vfsFlags,            /* flags passed through to sqlite3_vfs.xOpen() */
++  void (*xReinit)(DbPage*) /* Function to reinitialize pages */
++){
++  u8 *pPtr;
++  Pager *pPager = 0;       /* Pager object to allocate and return */
++  int rc = SQLITE_OK;      /* Return code */
++  int tempFile = 0;        /* True for temp files (incl. in-memory files) */
++  int memDb = 0;           /* True if this is an in-memory file */
++  int readOnly = 0;        /* True if this is a read-only file */
++  int journalFileSize;     /* Bytes to allocate for each journal fd */
++  char *zPathname = 0;     /* Full path to database file */
++  int nPathname = 0;       /* Number of bytes in zPathname */
++  int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */
++  int pcacheSize = sqlite3PcacheSize();       /* Bytes to allocate for PCache */
++  u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE;  /* Default page size */
++  const char *zUri = 0;    /* URI args to copy */
++  int nUri = 0;            /* Number of bytes of URI args at *zUri */
++
++  /* Figure out how much space is required for each journal file-handle
++  ** (there are two of them, the main journal and the sub-journal). This
++  ** is the maximum space required for an in-memory journal file handle 
++  ** and a regular journal file-handle. Note that a "regular journal-handle"
++  ** may be a wrapper capable of caching the first portion of the journal
++  ** file in memory to implement the atomic-write optimization (see 
++  ** source file journal.c).
++  */
++  if( sqlite3JournalSize(pVfs)>sqlite3MemJournalSize() ){
++    journalFileSize = ROUND8(sqlite3JournalSize(pVfs));
+   }else{
+-    return pager_write(pPg);
++    journalFileSize = ROUND8(sqlite3MemJournalSize());
+   }
+-}
+ 
+-/*
+-** Return TRUE if the page given in the argument was previously passed
+-** to sqlite3PagerWrite().  In other words, return TRUE if it is ok
+-** to change the content of the page.
+-*/
+-#ifndef NDEBUG
+-SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage *pPg){
+-  return pPg->flags&PGHDR_DIRTY;
+-}
+-#endif
++  /* Set the output variable to NULL in case an error occurs. */
++  *ppPager = 0;
+ 
+-/*
+-** A call to this routine tells the pager that it is not necessary to
+-** write the information on page pPg back to the disk, even though
+-** that page might be marked as dirty.  This happens, for example, when
+-** the page has been added as a leaf of the freelist and so its
+-** content no longer matters.
+-**
+-** The overlying software layer calls this routine when all of the data
+-** on the given page is unused. The pager marks the page as clean so
+-** that it does not get written to disk.
+-**
+-** Tests show that this optimization can quadruple the speed of large 
+-** DELETE operations.
+-*/
+-SQLITE_PRIVATE void sqlite3PagerDontWrite(PgHdr *pPg){
+-  Pager *pPager = pPg->pPager;
+-  if( (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){
+-    PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager)));
+-    IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno))
+-    pPg->flags |= PGHDR_DONT_WRITE;
+-    pager_set_pagehash(pPg);
++#ifndef SQLITE_OMIT_MEMORYDB
++  if( flags & PAGER_MEMORY ){
++    memDb = 1;
++    if( zFilename && zFilename[0] ){
++      zPathname = sqlite3DbStrDup(0, zFilename);
++      if( zPathname==0  ) return SQLITE_NOMEM;
++      nPathname = sqlite3Strlen30(zPathname);
++      zFilename = 0;
++    }
+   }
+-}
+-
+-/*
+-** This routine is called to increment the value of the database file 
+-** change-counter, stored as a 4-byte big-endian integer starting at 
+-** byte offset 24 of the pager file.  The secondary change counter at
+-** 92 is also updated, as is the SQLite version number at offset 96.
+-**
+-** But this only happens if the pPager->changeCountDone flag is false.
+-** To avoid excess churning of page 1, the update only happens once.
+-** See also the pager_write_changecounter() routine that does an 
+-** unconditional update of the change counters.
+-**
+-** If the isDirectMode flag is zero, then this is done by calling 
+-** sqlite3PagerWrite() on page 1, then modifying the contents of the
+-** page data. In this case the file will be updated when the current
+-** transaction is committed.
+-**
+-** The isDirectMode flag may only be non-zero if the library was compiled
+-** with the SQLITE_ENABLE_ATOMIC_WRITE macro defined. In this case,
+-** if isDirect is non-zero, then the database file is updated directly
+-** by writing an updated version of page 1 using a call to the 
+-** sqlite3OsWrite() function.
+-*/
+-static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
+-  int rc = SQLITE_OK;
++#endif
+ 
+-  assert( pPager->eState==PAGER_WRITER_CACHEMOD
+-       || pPager->eState==PAGER_WRITER_DBMOD
+-  );
+-  assert( assert_pager_state(pPager) );
++  /* Compute and store the full pathname in an allocated buffer pointed
++  ** to by zPathname, length nPathname. Or, if this is a temporary file,
++  ** leave both nPathname and zPathname set to 0.
++  */
++  if( zFilename && zFilename[0] ){
++    const char *z;
++    nPathname = pVfs->mxPathname+1;
++    zPathname = sqlite3DbMallocRaw(0, nPathname*2);
++    if( zPathname==0 ){
++      return SQLITE_NOMEM;
++    }
++    zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */
++    rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
++    nPathname = sqlite3Strlen30(zPathname);
++    z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1];
++    while( *z ){
++      z += sqlite3Strlen30(z)+1;
++      z += sqlite3Strlen30(z)+1;
++    }
++    nUri = (int)(&z[1] - zUri);
++    assert( nUri>=0 );
++    if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){
++      /* This branch is taken when the journal path required by
++      ** the database being opened will be more than pVfs->mxPathname
++      ** bytes in length. This means the database cannot be opened,
++      ** as it will not be possible to open the journal file or even
++      ** check for a hot-journal before reading.
++      */
++      rc = SQLITE_CANTOPEN_BKPT;
++    }
++    if( rc!=SQLITE_OK ){
++      sqlite3DbFree(0, zPathname);
++      return rc;
++    }
++  }
+ 
+-  /* Declare and initialize constant integer 'isDirect'. If the
+-  ** atomic-write optimization is enabled in this build, then isDirect
+-  ** is initialized to the value passed as the isDirectMode parameter
+-  ** to this function. Otherwise, it is always set to zero.
++  /* Allocate memory for the Pager structure, PCache object, the
++  ** three file descriptors, the database file name and the journal 
++  ** file name. The layout in memory is as follows:
+   **
+-  ** The idea is that if the atomic-write optimization is not
+-  ** enabled at compile time, the compiler can omit the tests of
+-  ** 'isDirect' below, as well as the block enclosed in the
+-  ** "if( isDirect )" condition.
++  **     Pager object                    (sizeof(Pager) bytes)
++  **     PCache object                   (sqlite3PcacheSize() bytes)
++  **     Database file handle            (pVfs->szOsFile bytes)
++  **     Sub-journal file handle         (journalFileSize bytes)
++  **     Main journal file handle        (journalFileSize bytes)
++  **     Database file name              (nPathname+1 bytes)
++  **     Journal file name               (nPathname+8+1 bytes)
+   */
+-#ifndef SQLITE_ENABLE_ATOMIC_WRITE
+-# define DIRECT_MODE 0
+-  assert( isDirectMode==0 );
+-  UNUSED_PARAMETER(isDirectMode);
+-#else
+-# define DIRECT_MODE isDirectMode
++  pPtr = (u8 *)sqlite3MallocZero(
++    ROUND8(sizeof(*pPager)) +      /* Pager structure */
++    ROUND8(pcacheSize) +           /* PCache object */
++    ROUND8(pVfs->szOsFile) +       /* The main db file */
++    journalFileSize * 2 +          /* The two journal files */ 
++    nPathname + 1 + nUri +         /* zFilename */
++    nPathname + 8 + 2              /* zJournal */
++#ifndef SQLITE_OMIT_WAL
++    + nPathname + 4 + 2            /* zWal */
+ #endif
++  );
++  assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
++  if( !pPtr ){
++    sqlite3DbFree(0, zPathname);
++    return SQLITE_NOMEM;
++  }
++  pPager =              (Pager*)(pPtr);
++  pPager->pPCache =    (PCache*)(pPtr += ROUND8(sizeof(*pPager)));
++  pPager->fd =   (sqlite3_file*)(pPtr += ROUND8(pcacheSize));
++  pPager->sjfd = (sqlite3_file*)(pPtr += ROUND8(pVfs->szOsFile));
++  pPager->jfd =  (sqlite3_file*)(pPtr += journalFileSize);
++  pPager->zFilename =    (char*)(pPtr += journalFileSize);
++  assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );
+ 
+-  if( !pPager->changeCountDone && ALWAYS(pPager->dbSize>0) ){
+-    PgHdr *pPgHdr;                /* Reference to page 1 */
+-
+-    assert( !pPager->tempFile && isOpen(pPager->fd) );
++  /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */
++  if( zPathname ){
++    assert( nPathname>0 );
++    pPager->zJournal =   (char*)(pPtr += nPathname + 1 + nUri);
++    memcpy(pPager->zFilename, zPathname, nPathname);
++    if( nUri ) memcpy(&pPager->zFilename[nPathname+1], zUri, nUri);
++    memcpy(pPager->zJournal, zPathname, nPathname);
++    memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+2);
++    sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal);
++#ifndef SQLITE_OMIT_WAL
++    pPager->zWal = &pPager->zJournal[nPathname+8+1];
++    memcpy(pPager->zWal, zPathname, nPathname);
++    memcpy(&pPager->zWal[nPathname], "-wal\000", 4+1);
++    sqlite3FileSuffix3(pPager->zFilename, pPager->zWal);
++#endif
++    sqlite3DbFree(0, zPathname);
++  }
++  pPager->pVfs = pVfs;
++  pPager->vfsFlags = vfsFlags;
+ 
+-    /* Open page 1 of the file for writing. */
+-    rc = sqlite3PagerGet(pPager, 1, &pPgHdr);
+-    assert( pPgHdr==0 || rc==SQLITE_OK );
++  /* Open the pager file.
++  */
++  if( zFilename && zFilename[0] ){
++    int fout = 0;                    /* VFS flags returned by xOpen() */
++    rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
++    assert( !memDb );
++    readOnly = (fout&SQLITE_OPEN_READONLY);
+ 
+-    /* If page one was fetched successfully, and this function is not
+-    ** operating in direct-mode, make page 1 writable.  When not in 
+-    ** direct mode, page 1 is always held in cache and hence the PagerGet()
+-    ** above is always successful - hence the ALWAYS on rc==SQLITE_OK.
++    /* If the file was successfully opened for read/write access,
++    ** choose a default page size in case we have to create the
++    ** database file. The default page size is the maximum of:
++    **
++    **    + SQLITE_DEFAULT_PAGE_SIZE,
++    **    + The value returned by sqlite3OsSectorSize()
++    **    + The largest page size that can be written atomically.
+     */
+-    if( !DIRECT_MODE && ALWAYS(rc==SQLITE_OK) ){
+-      rc = sqlite3PagerWrite(pPgHdr);
+-    }
+-
+     if( rc==SQLITE_OK ){
+-      /* Actually do the update of the change counter */
+-      pager_write_changecounter(pPgHdr);
+-
+-      /* If running in direct mode, write the contents of page 1 to the file. */
+-      if( DIRECT_MODE ){
+-        const void *zBuf;
+-        assert( pPager->dbFileSize>0 );
+-        CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM, zBuf);
+-        if( rc==SQLITE_OK ){
+-          rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0);
+-          pPager->aStat[PAGER_STAT_WRITE]++;
++      int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
++      if( !readOnly ){
++        setSectorSize(pPager);
++        assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE);
++        if( szPageDflt<pPager->sectorSize ){
++          if( pPager->sectorSize>SQLITE_MAX_DEFAULT_PAGE_SIZE ){
++            szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE;
++          }else{
++            szPageDflt = (u32)pPager->sectorSize;
++          }
+         }
+-        if( rc==SQLITE_OK ){
+-          /* Update the pager's copy of the change-counter. Otherwise, the
+-          ** next time a read transaction is opened the cache will be
+-          ** flushed (as the change-counter values will not match).  */
+-          const void *pCopy = (const void *)&((const char *)zBuf)[24];
+-          memcpy(&pPager->dbFileVers, pCopy, sizeof(pPager->dbFileVers));
+-          pPager->changeCountDone = 1;
++#ifdef SQLITE_ENABLE_ATOMIC_WRITE
++        {
++          int ii;
++          assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
++          assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
++          assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536);
++          for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){
++            if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ){
++              szPageDflt = ii;
++            }
++          }
+         }
+-      }else{
+-        pPager->changeCountDone = 1;
++#endif
++      }
++      pPager->noLock = sqlite3_uri_boolean(zFilename, "nolock", 0);
++      if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0
++       || sqlite3_uri_boolean(zFilename, "immutable", 0) ){
++          vfsFlags |= SQLITE_OPEN_READONLY;
++          goto act_like_temp_file;
+       }
+     }
++  }else{
++    /* If a temporary file is requested, it is not opened immediately.
++    ** In this case we accept the default page size and delay actually
++    ** opening the file until the first call to OsWrite().
++    **
++    ** This branch is also run for an in-memory database. An in-memory
++    ** database is the same as a temp-file that is never written out to
++    ** disk and uses an in-memory rollback journal.
++    **
++    ** This branch also runs for files marked as immutable.
++    */ 
++act_like_temp_file:
++    tempFile = 1;
++    pPager->eState = PAGER_READER;     /* Pretend we already have a lock */
++    pPager->eLock = EXCLUSIVE_LOCK;    /* Pretend we are in EXCLUSIVE locking mode */
++    pPager->noLock = 1;                /* Do no locking */
++    readOnly = (vfsFlags&SQLITE_OPEN_READONLY);
++  }
+ 
+-    /* Release the page reference. */
+-    sqlite3PagerUnref(pPgHdr);
++  /* The following call to PagerSetPagesize() serves to set the value of 
++  ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer.
++  */
++  if( rc==SQLITE_OK ){
++    assert( pPager->memDb==0 );
++    rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1);
++    testcase( rc!=SQLITE_OK );
+   }
+-  return rc;
++
++  /* Initialize the PCache object. */
++  if( rc==SQLITE_OK ){
++    assert( nExtra<1000 );
++    nExtra = ROUND8(nExtra);
++    rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb,
++                           !memDb?pagerStress:0, (void *)pPager, pPager->pPCache);
++  }
++
++  /* If an error occurred above, free the  Pager structure and close the file.
++  */
++  if( rc!=SQLITE_OK ){
++    sqlite3OsClose(pPager->fd);
++    sqlite3PageFree(pPager->pTmpSpace);
++    sqlite3_free(pPager);
++    return rc;
++  }
++
++  PAGERTRACE(("OPEN %d %s\n", FILEHANDLEID(pPager->fd), pPager->zFilename));
++  IOTRACE(("OPEN %p %s\n", pPager, pPager->zFilename))
++
++  pPager->useJournal = (u8)useJournal;
++  /* pPager->stmtOpen = 0; */
++  /* pPager->stmtInUse = 0; */
++  /* pPager->nRef = 0; */
++  /* pPager->stmtSize = 0; */
++  /* pPager->stmtJSize = 0; */
++  /* pPager->nPage = 0; */
++  pPager->mxPgno = SQLITE_MAX_PAGE_COUNT;
++  /* pPager->state = PAGER_UNLOCK; */
++  /* pPager->errMask = 0; */
++  pPager->tempFile = (u8)tempFile;
++  assert( tempFile==PAGER_LOCKINGMODE_NORMAL 
++          || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE );
++  assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 );
++  pPager->exclusiveMode = (u8)tempFile; 
++  pPager->changeCountDone = pPager->tempFile;
++  pPager->memDb = (u8)memDb;
++  pPager->readOnly = (u8)readOnly;
++  assert( useJournal || pPager->tempFile );
++  pPager->noSync = pPager->tempFile;
++  if( pPager->noSync ){
++    assert( pPager->fullSync==0 );
++    assert( pPager->syncFlags==0 );
++    assert( pPager->walSyncFlags==0 );
++    assert( pPager->ckptSyncFlags==0 );
++  }else{
++    pPager->fullSync = 1;
++    pPager->syncFlags = SQLITE_SYNC_NORMAL;
++    pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS;
++    pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL;
++  }
++  /* pPager->pFirst = 0; */
++  /* pPager->pFirstSynced = 0; */
++  /* pPager->pLast = 0; */
++  pPager->nExtra = (u16)nExtra;
++  pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT;
++  assert( isOpen(pPager->fd) || tempFile );
++  setSectorSize(pPager);
++  if( !useJournal ){
++    pPager->journalMode = PAGER_JOURNALMODE_OFF;
++  }else if( memDb ){
++    pPager->journalMode = PAGER_JOURNALMODE_MEMORY;
++  }
++  /* pPager->xBusyHandler = 0; */
++  /* pPager->pBusyHandlerArg = 0; */
++  pPager->xReiniter = xReinit;
++  /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */
++  /* pPager->szMmap = SQLITE_DEFAULT_MMAP_SIZE // will be set by btree.c */
++
++  *ppPager = pPager;
++  return SQLITE_OK;
+ }
+ 
+-/*
+-** Sync the database file to disk. This is a no-op for in-memory databases
+-** or pages with the Pager.noSync flag set.
+-**
+-** If successful, or if called on a pager for which it is a no-op, this
+-** function returns SQLITE_OK. Otherwise, an IO error code is returned.
++
++/* Verify that the database file has not be deleted or renamed out from
++** under the pager.  Return SQLITE_OK if the database is still were it ought
++** to be on disk.  Return non-zero (SQLITE_READONLY_DBMOVED or some other error
++** code from sqlite3OsAccess()) if the database has gone missing.
+ */
+-SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager, const char *zMaster){
+-  int rc = SQLITE_OK;
++static int databaseIsUnmoved(Pager *pPager){
++  int bHasMoved = 0;
++  int rc;
+ 
+-  if( isOpen(pPager->fd) ){
+-    void *pArg = (void*)zMaster;
+-    rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg);
+-    if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
+-  }
+-  if( rc==SQLITE_OK && !pPager->noSync ){
+-    assert( !MEMDB );
+-    rc = sqlite3OsSync(pPager->fd, pPager->syncFlags);
++  if( pPager->tempFile ) return SQLITE_OK;
++  if( pPager->dbSize==0 ) return SQLITE_OK;
++  assert( pPager->zFilename && pPager->zFilename[0] );
++  rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved);
++  if( rc==SQLITE_NOTFOUND ){
++    /* If the HAS_MOVED file-control is unimplemented, assume that the file
++    ** has not been moved.  That is the historical behavior of SQLite: prior to
++    ** version 3.8.3, it never checked */
++    rc = SQLITE_OK;
++  }else if( rc==SQLITE_OK && bHasMoved ){
++    rc = SQLITE_READONLY_DBMOVED;
+   }
+   return rc;
+ }
+ 
++
+ /*
+-** This function may only be called while a write-transaction is active in
+-** rollback. If the connection is in WAL mode, this call is a no-op. 
+-** Otherwise, if the connection does not already have an EXCLUSIVE lock on 
+-** the database file, an attempt is made to obtain one.
++** This function is called after transitioning from PAGER_UNLOCK to
++** PAGER_SHARED state. It tests if there is a hot journal present in
++** the file-system for the given pager. A hot journal is one that 
++** needs to be played back. According to this function, a hot-journal
++** file exists if the following criteria are met:
+ **
+-** If the EXCLUSIVE lock is already held or the attempt to obtain it is
+-** successful, or the connection is in WAL mode, SQLITE_OK is returned.
+-** Otherwise, either SQLITE_BUSY or an SQLITE_IOERR_XXX error code is 
+-** returned.
++**   * The journal file exists in the file system, and
++**   * No process holds a RESERVED or greater lock on the database file, and
++**   * The database file itself is greater than 0 bytes in size, and
++**   * The first byte of the journal file exists and is not 0x00.
++**
++** If the current size of the database file is 0 but a journal file
++** exists, that is probably an old journal left over from a prior
++** database with the same name. In this case the journal file is
++** just deleted using OsDelete, *pExists is set to 0 and SQLITE_OK
++** is returned.
++**
++** This routine does not check if there is a master journal filename
++** at the end of the file. If there is, and that master journal file
++** does not exist, then the journal file is not really hot. In this
++** case this routine will return a false-positive. The pager_playback()
++** routine will discover that the journal file is not really hot and 
++** will not roll it back. 
++**
++** If a hot-journal file is found to exist, *pExists is set to 1 and 
++** SQLITE_OK returned. If no hot-journal file is present, *pExists is
++** set to 0 and SQLITE_OK returned. If an IO error occurs while trying
++** to determine whether or not a hot-journal file exists, the IO error
++** code is returned and the value of *pExists is undefined.
+ */
+-SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager *pPager){
+-  int rc = SQLITE_OK;
+-  assert( pPager->eState==PAGER_WRITER_CACHEMOD 
+-       || pPager->eState==PAGER_WRITER_DBMOD 
+-       || pPager->eState==PAGER_WRITER_LOCKED 
+-  );
+-  assert( assert_pager_state(pPager) );
+-  if( 0==pagerUseWal(pPager) ){
+-    rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
++static int hasHotJournal(Pager *pPager, int *pExists){
++  sqlite3_vfs * const pVfs = pPager->pVfs;
++  int rc = SQLITE_OK;           /* Return code */
++  int exists = 1;               /* True if a journal file is present */
++  int jrnlOpen = !!isOpen(pPager->jfd);
++
++  assert( pPager->useJournal );
++  assert( isOpen(pPager->fd) );
++  assert( pPager->eState==PAGER_OPEN );
++
++  assert( jrnlOpen==0 || ( sqlite3OsDeviceCharacteristics(pPager->jfd) &
++    SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
++  ));
++
++  *pExists = 0;
++  if( !jrnlOpen ){
++    rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists);
++  }
++  if( rc==SQLITE_OK && exists ){
++    int locked = 0;             /* True if some process holds a RESERVED lock */
++
++    /* Race condition here:  Another process might have been holding the
++    ** the RESERVED lock and have a journal open at the sqlite3OsAccess() 
++    ** call above, but then delete the journal and drop the lock before
++    ** we get to the following sqlite3OsCheckReservedLock() call.  If that
++    ** is the case, this routine might think there is a hot journal when
++    ** in fact there is none.  This results in a false-positive which will
++    ** be dealt with by the playback routine.  Ticket #3883.
++    */
++    rc = sqlite3OsCheckReservedLock(pPager->fd, &locked);
++    if( rc==SQLITE_OK && !locked ){
++      Pgno nPage;                 /* Number of pages in database file */
++
++      rc = pagerPagecount(pPager, &nPage);
++      if( rc==SQLITE_OK ){
++        /* If the database is zero pages in size, that means that either (1) the
++        ** journal is a remnant from a prior database with the same name where
++        ** the database file but not the journal was deleted, or (2) the initial
++        ** transaction that populates a new database is being rolled back.
++        ** In either case, the journal file can be deleted.  However, take care
++        ** not to delete the journal file if it is already open due to
++        ** journal_mode=PERSIST.
++        */
++        if( nPage==0 && !jrnlOpen ){
++          sqlite3BeginBenignMalloc();
++          if( pagerLockDb(pPager, RESERVED_LOCK)==SQLITE_OK ){
++            sqlite3OsDelete(pVfs, pPager->zJournal, 0);
++            if( !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK);
++          }
++          sqlite3EndBenignMalloc();
++        }else{
++          /* The journal file exists and no other connection has a reserved
++          ** or greater lock on the database file. Now check that there is
++          ** at least one non-zero bytes at the start of the journal file.
++          ** If there is, then we consider this journal to be hot. If not, 
++          ** it can be ignored.
++          */
++          if( !jrnlOpen ){
++            int f = SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL;
++            rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &f);
++          }
++          if( rc==SQLITE_OK ){
++            u8 first = 0;
++            rc = sqlite3OsRead(pPager->jfd, (void *)&first, 1, 0);
++            if( rc==SQLITE_IOERR_SHORT_READ ){
++              rc = SQLITE_OK;
++            }
++            if( !jrnlOpen ){
++              sqlite3OsClose(pPager->jfd);
++            }
++            *pExists = (first!=0);
++          }else if( rc==SQLITE_CANTOPEN ){
++            /* If we cannot open the rollback journal file in order to see if
++            ** it has a zero header, that might be due to an I/O error, or
++            ** it might be due to the race condition described above and in
++            ** ticket #3883.  Either way, assume that the journal is hot.
++            ** This might be a false positive.  But if it is, then the
++            ** automatic journal playback and recovery mechanism will deal
++            ** with it under an EXCLUSIVE lock where we do not need to
++            ** worry so much with race conditions.
++            */
++            *pExists = 1;
++            rc = SQLITE_OK;
++          }
++        }
++      }
++    }
+   }
++
+   return rc;
+ }
+ 
+ /*
+-** Sync the database file for the pager pPager. zMaster points to the name
+-** of a master journal file that should be written into the individual
+-** journal file. zMaster may be NULL, which is interpreted as no master
+-** journal (a single database transaction).
+-**
+-** This routine ensures that:
++** This function is called to obtain a shared lock on the database file.
++** It is illegal to call sqlite3PagerAcquire() until after this function
++** has been successfully called. If a shared-lock is already held when
++** this function is called, it is a no-op.
+ **
+-**   * The database file change-counter is updated,
+-**   * the journal is synced (unless the atomic-write optimization is used),
+-**   * all dirty pages are written to the database file, 
+-**   * the database file is truncated (if required), and
+-**   * the database file synced. 
++** The following operations are also performed by this function.
+ **
+-** The only thing that remains to commit the transaction is to finalize 
+-** (delete, truncate or zero the first part of) the journal file (or 
+-** delete the master journal file if specified).
++**   1) If the pager is currently in PAGER_OPEN state (no lock held
++**      on the database file), then an attempt is made to obtain a
++**      SHARED lock on the database file. Immediately after obtaining
++**      the SHARED lock, the file-system is checked for a hot-journal,
++**      which is played back if present. Following any hot-journal 
++**      rollback, the contents of the cache are validated by checking
++**      the 'change-counter' field of the database file header and
++**      discarded if they are found to be invalid.
+ **
+-** Note that if zMaster==NULL, this does not overwrite a previous value
+-** passed to an sqlite3PagerCommitPhaseOne() call.
++**   2) If the pager is running in exclusive-mode, and there are currently
++**      no outstanding references to any pages, and is in the error state,
++**      then an attempt is made to clear the error state by discarding
++**      the contents of the page cache and rolling back any open journal
++**      file.
+ **
+-** If the final parameter - noSync - is true, then the database file itself
+-** is not synced. The caller must call sqlite3PagerSync() directly to
+-** sync the database file before calling CommitPhaseTwo() to delete the
+-** journal file in this case.
++** If everything is successful, SQLITE_OK is returned. If an IO error 
++** occurs while locking the database, checking for a hot-journal file or 
++** rolling back a journal file, the IO error code is returned.
+ */
+-SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
+-  Pager *pPager,                  /* Pager object */
+-  const char *zMaster,            /* If not NULL, the master journal name */
+-  int noSync                      /* True to omit the xSync on the db file */
+-){
+-  int rc = SQLITE_OK;             /* Return code */
++SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
++  int rc = SQLITE_OK;                /* Return code */
+ 
+-  assert( pPager->eState==PAGER_WRITER_LOCKED
+-       || pPager->eState==PAGER_WRITER_CACHEMOD
+-       || pPager->eState==PAGER_WRITER_DBMOD
+-       || pPager->eState==PAGER_ERROR
+-  );
++  /* This routine is only called from b-tree and only when there are no
++  ** outstanding pages. This implies that the pager state should either
++  ** be OPEN or READER. READER is only possible if the pager is or was in 
++  ** exclusive access mode.
++  */
++  assert( sqlite3PcacheRefCount(pPager->pPCache)==0 );
+   assert( assert_pager_state(pPager) );
++  assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER );
++  if( NEVER(MEMDB && pPager->errCode) ){ return pPager->errCode; }
+ 
+-  /* If a prior error occurred, report that error again. */
+-  if( NEVER(pPager->errCode) ) return pPager->errCode;
++  if( !pagerUseWal(pPager) && pPager->eState==PAGER_OPEN ){
++    int bHotJournal = 1;          /* True if there exists a hot journal-file */
+ 
+-  PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", 
+-      pPager->zFilename, zMaster, pPager->dbSize));
++    assert( !MEMDB );
+ 
+-  /* If no database changes have been made, return early. */
+-  if( pPager->eState<PAGER_WRITER_CACHEMOD ) return SQLITE_OK;
++    rc = pager_wait_on_lock(pPager, SHARED_LOCK);
++    if( rc!=SQLITE_OK ){
++      assert( pPager->eLock==NO_LOCK || pPager->eLock==UNKNOWN_LOCK );
++      goto failed;
++    }
+ 
+-  if( MEMDB ){
+-    /* If this is an in-memory db, or no pages have been written to, or this
+-    ** function has already been called, it is mostly a no-op.  However, any
+-    ** backup in progress needs to be restarted.
++    /* If a journal file exists, and there is no RESERVED lock on the
++    ** database file, then it either needs to be played back or deleted.
+     */
+-    sqlite3BackupRestart(pPager->pBackup);
+-  }else{
+-    if( pagerUseWal(pPager) ){
+-      PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache);
+-      PgHdr *pPageOne = 0;
+-      if( pList==0 ){
+-        /* Must have at least one page for the WAL commit flag.
+-        ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */
+-        rc = sqlite3PagerGet(pPager, 1, &pPageOne);
+-        pList = pPageOne;
+-        pList->pDirty = 0;
+-      }
+-      assert( rc==SQLITE_OK );
+-      if( ALWAYS(pList) ){
+-        rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1);
+-      }
+-      sqlite3PagerUnref(pPageOne);
+-      if( rc==SQLITE_OK ){
+-        sqlite3PcacheCleanAll(pPager->pPCache);
++    if( pPager->eLock<=SHARED_LOCK ){
++      rc = hasHotJournal(pPager, &bHotJournal);
++    }
++    if( rc!=SQLITE_OK ){
++      goto failed;
++    }
++    if( bHotJournal ){
++      if( pPager->readOnly ){
++        rc = SQLITE_READONLY_ROLLBACK;
++        goto failed;
+       }
+-    }else{
+-      /* The following block updates the change-counter. Exactly how it
+-      ** does this depends on whether or not the atomic-update optimization
+-      ** was enabled at compile time, and if this transaction meets the 
+-      ** runtime criteria to use the operation: 
+-      **
+-      **    * The file-system supports the atomic-write property for
+-      **      blocks of size page-size, and 
+-      **    * This commit is not part of a multi-file transaction, and
+-      **    * Exactly one page has been modified and store in the journal file.
++
++      /* Get an EXCLUSIVE lock on the database file. At this point it is
++      ** important that a RESERVED lock is not obtained on the way to the
++      ** EXCLUSIVE lock. If it were, another process might open the
++      ** database file, detect the RESERVED lock, and conclude that the
++      ** database is safe to read while this process is still rolling the 
++      ** hot-journal back.
++      ** 
++      ** Because the intermediate RESERVED lock is not requested, any
++      ** other process attempting to access the database file will get to 
++      ** this point in the code and fail to obtain its own EXCLUSIVE lock 
++      ** on the database file.
+       **
+-      ** If the optimization was not enabled at compile time, then the
+-      ** pager_incr_changecounter() function is called to update the change
+-      ** counter in 'indirect-mode'. If the optimization is compiled in but
+-      ** is not applicable to this transaction, call sqlite3JournalCreate()
+-      ** to make sure the journal file has actually been created, then call
+-      ** pager_incr_changecounter() to update the change-counter in indirect
+-      ** mode. 
++      ** Unless the pager is in locking_mode=exclusive mode, the lock is
++      ** downgraded to SHARED_LOCK before this function returns.
++      */
++      rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
++      if( rc!=SQLITE_OK ){
++        goto failed;
++      }
++ 
++      /* If it is not already open and the file exists on disk, open the 
++      ** journal for read/write access. Write access is required because 
++      ** in exclusive-access mode the file descriptor will be kept open 
++      ** and possibly used for a transaction later on. Also, write-access 
++      ** is usually required to finalize the journal in journal_mode=persist 
++      ** mode (and also for journal_mode=truncate on some systems).
+       **
+-      ** Otherwise, if the optimization is both enabled and applicable,
+-      ** then call pager_incr_changecounter() to update the change-counter
+-      ** in 'direct' mode. In this case the journal file will never be
+-      ** created for this transaction.
++      ** If the journal does not exist, it usually means that some 
++      ** other connection managed to get in and roll it back before 
++      ** this connection obtained the exclusive lock above. Or, it 
++      ** may mean that the pager was in the error-state when this
++      ** function was called and the journal file does not exist.
+       */
+-  #ifdef SQLITE_ENABLE_ATOMIC_WRITE
+-      PgHdr *pPg;
+-      assert( isOpen(pPager->jfd) 
+-           || pPager->journalMode==PAGER_JOURNALMODE_OFF 
+-           || pPager->journalMode==PAGER_JOURNALMODE_WAL 
+-      );
+-      if( !zMaster && isOpen(pPager->jfd) 
+-       && pPager->journalOff==jrnlBufferSize(pPager) 
+-       && pPager->dbSize>=pPager->dbOrigSize
+-       && (0==(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty)
+-      ){
+-        /* Update the db file change counter via the direct-write method. The 
+-        ** following call will modify the in-memory representation of page 1 
+-        ** to include the updated change counter and then write page 1 
+-        ** directly to the database file. Because of the atomic-write 
+-        ** property of the host file-system, this is safe.
+-        */
+-        rc = pager_incr_changecounter(pPager, 1);
+-      }else{
+-        rc = sqlite3JournalCreate(pPager->jfd);
+-        if( rc==SQLITE_OK ){
+-          rc = pager_incr_changecounter(pPager, 0);
++      if( !isOpen(pPager->jfd) ){
++        sqlite3_vfs * const pVfs = pPager->pVfs;
++        int bExists;              /* True if journal file exists */
++        rc = sqlite3OsAccess(
++            pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &bExists);
++        if( rc==SQLITE_OK && bExists ){
++          int fout = 0;
++          int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL;
++          assert( !pPager->tempFile );
++          rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout);
++          assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
++          if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){
++            rc = SQLITE_CANTOPEN_BKPT;
++            sqlite3OsClose(pPager->jfd);
++          }
+         }
+       }
+-  #else
+-      rc = pager_incr_changecounter(pPager, 0);
+-  #endif
+-      if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
+-  
+-      /* Write the master journal name into the journal file. If a master 
+-      ** journal file name has already been written to the journal file, 
+-      ** or if zMaster is NULL (no master journal), then this call is a no-op.
+-      */
+-      rc = writeMasterJournal(pPager, zMaster);
+-      if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
+-  
+-      /* Sync the journal file and write all dirty pages to the database.
+-      ** If the atomic-update optimization is being used, this sync will not 
+-      ** create the journal file or perform any real IO.
+-      **
+-      ** Because the change-counter page was just modified, unless the
+-      ** atomic-update optimization is used it is almost certain that the
+-      ** journal requires a sync here. However, in locking_mode=exclusive
+-      ** on a system under memory pressure it is just possible that this is 
+-      ** not the case. In this case it is likely enough that the redundant
+-      ** xSync() call will be changed to a no-op by the OS anyhow. 
++ 
++      /* Playback and delete the journal.  Drop the database write
++      ** lock and reacquire the read lock. Purge the cache before
++      ** playing back the hot-journal so that we don't end up with
++      ** an inconsistent cache.  Sync the hot journal before playing
++      ** it back since the process that crashed and left the hot journal
++      ** probably did not sync it and we are required to always sync
++      ** the journal before playing it back.
+       */
+-      rc = syncJournal(pPager, 0);
+-      if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
+-  
+-      rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache));
+-      if( rc!=SQLITE_OK ){
+-        assert( rc!=SQLITE_IOERR_BLOCKED );
+-        goto commit_phase_one_exit;
++      if( isOpen(pPager->jfd) ){
++        assert( rc==SQLITE_OK );
++        rc = pagerSyncHotJournal(pPager);
++        if( rc==SQLITE_OK ){
++          rc = pager_playback(pPager, 1);
++          pPager->eState = PAGER_OPEN;
++        }
++      }else if( !pPager->exclusiveMode ){
++        pagerUnlockDb(pPager, SHARED_LOCK);
+       }
+-      sqlite3PcacheCleanAll(pPager->pPCache);
+ 
+-      /* If the file on disk is smaller than the database image, use 
+-      ** pager_truncate to grow the file here. This can happen if the database
+-      ** image was extended as part of the current transaction and then the
+-      ** last page in the db image moved to the free-list. In this case the
+-      ** last page is never written out to disk, leaving the database file
+-      ** undersized. Fix this now if it is the case.  */
+-      if( pPager->dbSize>pPager->dbFileSize ){
+-        Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager));
+-        assert( pPager->eState==PAGER_WRITER_DBMOD );
+-        rc = pager_truncate(pPager, nNew);
+-        if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
+-      }
+-  
+-      /* Finally, sync the database file. */
+-      if( !noSync ){
+-        rc = sqlite3PagerSync(pPager, zMaster);
++      if( rc!=SQLITE_OK ){
++        /* This branch is taken if an error occurs while trying to open
++        ** or roll back a hot-journal while holding an EXCLUSIVE lock. The
++        ** pager_unlock() routine will be called before returning to unlock
++        ** the file. If the unlock attempt fails, then Pager.eLock must be
++        ** set to UNKNOWN_LOCK (see the comment above the #define for 
++        ** UNKNOWN_LOCK above for an explanation). 
++        **
++        ** In order to get pager_unlock() to do this, set Pager.eState to
++        ** PAGER_ERROR now. This is not actually counted as a transition
++        ** to ERROR state in the state diagram at the top of this file,
++        ** since we know that the same call to pager_unlock() will very
++        ** shortly transition the pager object to the OPEN state. Calling
++        ** assert_pager_state() would fail now, as it should not be possible
++        ** to be in ERROR state when there are zero outstanding page 
++        ** references.
++        */
++        pager_error(pPager, rc);
++        goto failed;
+       }
+-      IOTRACE(("DBSYNC %p\n", pPager))
++
++      assert( pPager->eState==PAGER_OPEN );
++      assert( (pPager->eLock==SHARED_LOCK)
++           || (pPager->exclusiveMode && pPager->eLock>SHARED_LOCK)
++      );
+     }
+-  }
+ 
+-commit_phase_one_exit:
+-  if( rc==SQLITE_OK && !pagerUseWal(pPager) ){
+-    pPager->eState = PAGER_WRITER_FINISHED;
+-  }
+-  return rc;
+-}
++    if( !pPager->tempFile && pPager->hasBeenUsed ){
++      /* The shared-lock has just been acquired then check to
++      ** see if the database has been modified.  If the database has changed,
++      ** flush the cache.  The pPager->hasBeenUsed flag prevents this from
++      ** occurring on the very first access to a file, in order to save a
++      ** single unnecessary sqlite3OsRead() call at the start-up.
++      **
++      ** Database changes is detected by looking at 15 bytes beginning
++      ** at offset 24 into the file.  The first 4 of these 16 bytes are
++      ** a 32-bit counter that is incremented with each change.  The
++      ** other bytes change randomly with each file change when
++      ** a codec is in use.
++      ** 
++      ** There is a vanishingly small chance that a change will not be 
++      ** detected.  The chance of an undetected change is so small that
++      ** it can be neglected.
++      */
++      Pgno nPage = 0;
++      char dbFileVers[sizeof(pPager->dbFileVers)];
+ 
++      rc = pagerPagecount(pPager, &nPage);
++      if( rc ) goto failed;
+ 
+-/*
+-** When this function is called, the database file has been completely
+-** updated to reflect the changes made by the current transaction and
+-** synced to disk. The journal file still exists in the file-system 
+-** though, and if a failure occurs at this point it will eventually
+-** be used as a hot-journal and the current transaction rolled back.
+-**
+-** This function finalizes the journal file, either by deleting, 
+-** truncating or partially zeroing it, so that it cannot be used 
+-** for hot-journal rollback. Once this is done the transaction is
+-** irrevocably committed.
+-**
+-** If an error occurs, an IO error code is returned and the pager
+-** moves into the error state. Otherwise, SQLITE_OK is returned.
+-*/
+-SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager *pPager){
+-  int rc = SQLITE_OK;                  /* Return code */
++      if( nPage>0 ){
++        IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers)));
++        rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24);
++        if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){
++          goto failed;
++        }
++      }else{
++        memset(dbFileVers, 0, sizeof(dbFileVers));
++      }
+ 
+-  /* This routine should not be called if a prior error has occurred.
+-  ** But if (due to a coding error elsewhere in the system) it does get
+-  ** called, just return the same error code without doing anything. */
+-  if( NEVER(pPager->errCode) ) return pPager->errCode;
++      if( memcmp(pPager->dbFileVers, dbFileVers, sizeof(dbFileVers))!=0 ){
++        pager_reset(pPager);
++
++        /* Unmap the database file. It is possible that external processes
++        ** may have truncated the database file and then extended it back
++        ** to its original size while this process was not holding a lock.
++        ** In this case there may exist a Pager.pMap mapping that appears
++        ** to be the right size but is not actually valid. Avoid this
++        ** possibility by unmapping the db here. */
++        if( USEFETCH(pPager) ){
++          sqlite3OsUnfetch(pPager->fd, 0, 0);
++        }
++      }
++    }
++
++    /* If there is a WAL file in the file-system, open this database in WAL
++    ** mode. Otherwise, the following function call is a no-op.
++    */
++    rc = pagerOpenWalIfPresent(pPager);
++#ifndef SQLITE_OMIT_WAL
++    assert( pPager->pWal==0 || rc==SQLITE_OK );
++#endif
++  }
+ 
+-  assert( pPager->eState==PAGER_WRITER_LOCKED
+-       || pPager->eState==PAGER_WRITER_FINISHED
+-       || (pagerUseWal(pPager) && pPager->eState==PAGER_WRITER_CACHEMOD)
+-  );
+-  assert( assert_pager_state(pPager) );
++  if( pagerUseWal(pPager) ){
++    assert( rc==SQLITE_OK );
++    rc = pagerBeginReadTransaction(pPager);
++  }
+ 
+-  /* An optimization. If the database was not actually modified during
+-  ** this transaction, the pager is running in exclusive-mode and is
+-  ** using persistent journals, then this function is a no-op.
+-  **
+-  ** The start of the journal file currently contains a single journal 
+-  ** header with the nRec field set to 0. If such a journal is used as
+-  ** a hot-journal during hot-journal rollback, 0 changes will be made
+-  ** to the database file. So there is no need to zero the journal 
+-  ** header. Since the pager is in exclusive mode, there is no need
+-  ** to drop any locks either.
+-  */
+-  if( pPager->eState==PAGER_WRITER_LOCKED 
+-   && pPager->exclusiveMode 
+-   && pPager->journalMode==PAGER_JOURNALMODE_PERSIST
+-  ){
+-    assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) || !pPager->journalOff );
++  if( pPager->eState==PAGER_OPEN && rc==SQLITE_OK ){
++    rc = pagerPagecount(pPager, &pPager->dbSize);
++  }
++
++ failed:
++  if( rc!=SQLITE_OK ){
++    assert( !MEMDB );
++    pager_unlock(pPager);
++    assert( pPager->eState==PAGER_OPEN );
++  }else{
+     pPager->eState = PAGER_READER;
+-    return SQLITE_OK;
+   }
++  return rc;
++}
+ 
+-  PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
+-  pPager->iDataVersion++;
+-  rc = pager_end_transaction(pPager, pPager->setMaster, 1);
+-  return pager_error(pPager, rc);
++/*
++** If the reference count has reached zero, rollback any active
++** transaction and unlock the pager.
++**
++** Except, in locking_mode=EXCLUSIVE when there is nothing to in
++** the rollback journal, the unlock is not performed and there is
++** nothing to rollback, so this routine is a no-op.
++*/ 
++static void pagerUnlockIfUnused(Pager *pPager){
++  if( pPager->nMmapOut==0 && (sqlite3PcacheRefCount(pPager->pPCache)==0) ){
++    pagerUnlockAndRollback(pPager);
++  }
+ }
+ 
+ /*
+-** If a write transaction is open, then all changes made within the 
+-** transaction are reverted and the current write-transaction is closed.
+-** The pager falls back to PAGER_READER state if successful, or PAGER_ERROR
+-** state if an error occurs.
++** Acquire a reference to page number pgno in pager pPager (a page
++** reference has type DbPage*). If the requested reference is 
++** successfully obtained, it is copied to *ppPage and SQLITE_OK returned.
+ **
+-** If the pager is already in PAGER_ERROR state when this function is called,
+-** it returns Pager.errCode immediately. No work is performed in this case.
++** If the requested page is already in the cache, it is returned. 
++** Otherwise, a new page object is allocated and populated with data
++** read from the database file. In some cases, the pcache module may
++** choose not to allocate a new page object and may reuse an existing
++** object with no outstanding references.
+ **
+-** Otherwise, in rollback mode, this function performs two functions:
++** The extra data appended to a page is always initialized to zeros the 
++** first time a page is loaded into memory. If the page requested is 
++** already in the cache when this function is called, then the extra
++** data is left as it was when the page object was last used.
+ **
+-**   1) It rolls back the journal file, restoring all database file and 
+-**      in-memory cache pages to the state they were in when the transaction
+-**      was opened, and
++** If the database image is smaller than the requested page or if a 
++** non-zero value is passed as the noContent parameter and the 
++** requested page is not already stored in the cache, then no 
++** actual disk read occurs. In this case the memory image of the 
++** page is initialized to all zeros. 
+ **
+-**   2) It finalizes the journal file, so that it is not used for hot
+-**      rollback at any point in the future.
++** If noContent is true, it means that we do not care about the contents
++** of the page. This occurs in two scenarios:
+ **
+-** Finalization of the journal file (task 2) is only performed if the 
+-** rollback is successful.
++**   a) When reading a free-list leaf page from the database, and
+ **
+-** In WAL mode, all cache-entries containing data modified within the
+-** current transaction are either expelled from the cache or reverted to
+-** their pre-transaction state by re-reading data from the database or
+-** WAL files. The WAL transaction is then closed.
++**   b) When a savepoint is being rolled back and we need to load
++**      a new page into the cache to be filled with the data read
++**      from the savepoint journal.
++**
++** If noContent is true, then the data returned is zeroed instead of
++** being read from the database. Additionally, the bits corresponding
++** to pgno in Pager.pInJournal (bitvec of pages already written to the
++** journal file) and the PagerSavepoint.pInSavepoint bitvecs of any open
++** savepoints are set. This means if the page is made writable at any
++** point in the future, using a call to sqlite3PagerWrite(), its contents
++** will not be journaled. This saves IO.
++**
++** The acquisition might fail for several reasons.  In all cases,
++** an appropriate error code is returned and *ppPage is set to NULL.
++**
++** See also sqlite3PagerLookup().  Both this routine and Lookup() attempt
++** to find a page in the in-memory cache first.  If the page is not already
++** in memory, this routine goes to disk to read it in whereas Lookup()
++** just returns 0.  This routine acquires a read-lock the first time it
++** has to go to disk, and could also playback an old journal if necessary.
++** Since Lookup() never goes to disk, it never has to deal with locks
++** or journal files.
+ */
+-SQLITE_PRIVATE int sqlite3PagerRollback(Pager *pPager){
+-  int rc = SQLITE_OK;                  /* Return code */
+-  PAGERTRACE(("ROLLBACK %d\n", PAGERID(pPager)));
++SQLITE_PRIVATE int sqlite3PagerAcquire(
++  Pager *pPager,      /* The pager open on the database file */
++  Pgno pgno,          /* Page number to fetch */
++  DbPage **ppPage,    /* Write a pointer to the page here */
++  int flags           /* PAGER_GET_XXX flags */
++){
++  int rc = SQLITE_OK;
++  PgHdr *pPg = 0;
++  u32 iFrame = 0;                 /* Frame to read from WAL file */
++  const int noContent = (flags & PAGER_GET_NOCONTENT);
+ 
+-  /* PagerRollback() is a no-op if called in READER or OPEN state. If
+-  ** the pager is already in the ERROR state, the rollback is not 
+-  ** attempted here. Instead, the error code is returned to the caller.
+-  */
++  /* It is acceptable to use a read-only (mmap) page for any page except
++  ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY
++  ** flag was specified by the caller. And so long as the db is not a 
++  ** temporary or in-memory database.  */
++  const int bMmapOk = (pgno!=1 && USEFETCH(pPager)
++   && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY))
++#ifdef SQLITE_HAS_CODEC
++   && pPager->xCodec==0
++#endif
++  );
++
++  assert( pPager->eState>=PAGER_READER );
+   assert( assert_pager_state(pPager) );
+-  if( pPager->eState==PAGER_ERROR ) return pPager->errCode;
+-  if( pPager->eState<=PAGER_READER ) return SQLITE_OK;
++  assert( noContent==0 || bMmapOk==0 );
+ 
+-  if( pagerUseWal(pPager) ){
+-    int rc2;
+-    rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1);
+-    rc2 = pager_end_transaction(pPager, pPager->setMaster, 0);
+-    if( rc==SQLITE_OK ) rc = rc2;
+-  }else if( !isOpen(pPager->jfd) || pPager->eState==PAGER_WRITER_LOCKED ){
+-    int eState = pPager->eState;
+-    rc = pager_end_transaction(pPager, 0, 0);
+-    if( !MEMDB && eState>PAGER_WRITER_LOCKED ){
+-      /* This can happen using journal_mode=off. Move the pager to the error 
+-      ** state to indicate that the contents of the cache may not be trusted.
+-      ** Any active readers will get SQLITE_ABORT.
+-      */
+-      pPager->errCode = SQLITE_ABORT;
+-      pPager->eState = PAGER_ERROR;
+-      return rc;
+-    }
+-  }else{
+-    rc = pager_playback(pPager, 0);
++  if( pgno==0 ){
++    return SQLITE_CORRUPT_BKPT;
+   }
++  pPager->hasBeenUsed = 1;
+ 
+-  assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK );
+-  assert( rc==SQLITE_OK || rc==SQLITE_FULL || rc==SQLITE_CORRUPT
+-          || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR 
+-          || rc==SQLITE_CANTOPEN
+-  );
++  /* If the pager is in the error state, return an error immediately. 
++  ** Otherwise, request the page from the PCache layer. */
++  if( pPager->errCode!=SQLITE_OK ){
++    rc = pPager->errCode;
++  }else{
++    if( bMmapOk && pagerUseWal(pPager) ){
++      rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
++      if( rc!=SQLITE_OK ) goto pager_acquire_err;
++    }
+ 
+-  /* If an error occurs during a ROLLBACK, we can no longer trust the pager
+-  ** cache. So call pager_error() on the way out to make any error persistent.
+-  */
+-  return pager_error(pPager, rc);
+-}
++    if( bMmapOk && iFrame==0 ){
++      void *pData = 0;
+ 
+-/*
+-** Return TRUE if the database file is opened read-only.  Return FALSE
+-** if the database is (in theory) writable.
+-*/
+-SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager *pPager){
+-  return pPager->readOnly;
+-}
++      rc = sqlite3OsFetch(pPager->fd, 
++          (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData
++      );
+ 
+-/*
+-** Return the number of references to the pager.
+-*/
+-SQLITE_PRIVATE int sqlite3PagerRefcount(Pager *pPager){
+-  return sqlite3PcacheRefCount(pPager->pPCache);
+-}
++      if( rc==SQLITE_OK && pData ){
++        if( pPager->eState>PAGER_READER ){
++          pPg = sqlite3PagerLookup(pPager, pgno);
++        }
++        if( pPg==0 ){
++          rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg);
++        }else{
++          sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData);
++        }
++        if( pPg ){
++          assert( rc==SQLITE_OK );
++          *ppPage = pPg;
++          return SQLITE_OK;
++        }
++      }
++      if( rc!=SQLITE_OK ){
++        goto pager_acquire_err;
++      }
++    }
+ 
+-/*
+-** Return the approximate number of bytes of memory currently
+-** used by the pager and its associated cache.
+-*/
+-SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager *pPager){
+-  int perPageSize = pPager->pageSize + pPager->nExtra + sizeof(PgHdr)
+-                                     + 5*sizeof(void*);
+-  return perPageSize*sqlite3PcachePagecount(pPager->pPCache)
+-           + sqlite3MallocSize(pPager)
+-           + pPager->pageSize;
+-}
++    {
++      sqlite3_pcache_page *pBase;
++      pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3);
++      if( pBase==0 ){
++        rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase);
++        if( rc!=SQLITE_OK ) goto pager_acquire_err;
++      }
++      pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase);
++      if( pPg==0 ) rc = SQLITE_NOMEM;
++    }
++  }
+ 
+-/*
+-** Return the number of references to the specified page.
+-*/
+-SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage *pPage){
+-  return sqlite3PcachePageRefcount(pPage);
+-}
++  if( rc!=SQLITE_OK ){
++    /* Either the call to sqlite3PcacheFetch() returned an error or the
++    ** pager was already in the error-state when this function was called.
++    ** Set pPg to 0 and jump to the exception handler.  */
++    pPg = 0;
++    goto pager_acquire_err;
++  }
++  assert( (*ppPage)->pgno==pgno );
++  assert( (*ppPage)->pPager==pPager || (*ppPage)->pPager==0 );
+ 
+-#ifdef SQLITE_TEST
+-/*
+-** This routine is used for testing and analysis only.
+-*/
+-SQLITE_PRIVATE int *sqlite3PagerStats(Pager *pPager){
+-  static int a[11];
+-  a[0] = sqlite3PcacheRefCount(pPager->pPCache);
+-  a[1] = sqlite3PcachePagecount(pPager->pPCache);
+-  a[2] = sqlite3PcacheGetCachesize(pPager->pPCache);
+-  a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize;
+-  a[4] = pPager->eState;
+-  a[5] = pPager->errCode;
+-  a[6] = pPager->aStat[PAGER_STAT_HIT];
+-  a[7] = pPager->aStat[PAGER_STAT_MISS];
+-  a[8] = 0;  /* Used to be pPager->nOvfl */
+-  a[9] = pPager->nRead;
+-  a[10] = pPager->aStat[PAGER_STAT_WRITE];
+-  return a;
+-}
+-#endif
++  if( (*ppPage)->pPager && !noContent ){
++    /* In this case the pcache already contains an initialized copy of
++    ** the page. Return without further ado.  */
++    assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) );
++    pPager->aStat[PAGER_STAT_HIT]++;
++    return SQLITE_OK;
+ 
+-/*
+-** Parameter eStat must be either SQLITE_DBSTATUS_CACHE_HIT or
+-** SQLITE_DBSTATUS_CACHE_MISS. Before returning, *pnVal is incremented by the
+-** current cache hit or miss count, according to the value of eStat. If the 
+-** reset parameter is non-zero, the cache hit or miss count is zeroed before 
+-** returning.
+-*/
+-SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){
++  }else{
++    /* The pager cache has created a new page. Its content needs to 
++    ** be initialized.  */
+ 
+-  assert( eStat==SQLITE_DBSTATUS_CACHE_HIT
+-       || eStat==SQLITE_DBSTATUS_CACHE_MISS
+-       || eStat==SQLITE_DBSTATUS_CACHE_WRITE
+-  );
++    pPg = *ppPage;
++    pPg->pPager = pPager;
+ 
+-  assert( SQLITE_DBSTATUS_CACHE_HIT+1==SQLITE_DBSTATUS_CACHE_MISS );
+-  assert( SQLITE_DBSTATUS_CACHE_HIT+2==SQLITE_DBSTATUS_CACHE_WRITE );
+-  assert( PAGER_STAT_HIT==0 && PAGER_STAT_MISS==1 && PAGER_STAT_WRITE==2 );
++    /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
++    ** number greater than this, or the unused locking-page, is requested. */
++    if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){
++      rc = SQLITE_CORRUPT_BKPT;
++      goto pager_acquire_err;
++    }
+ 
+-  *pnVal += pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT];
+-  if( reset ){
+-    pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT] = 0;
++    if( MEMDB || pPager->dbSize<pgno || noContent || !isOpen(pPager->fd) ){
++      if( pgno>pPager->mxPgno ){
++        rc = SQLITE_FULL;
++        goto pager_acquire_err;
++      }
++      if( noContent ){
++        /* Failure to set the bits in the InJournal bit-vectors is benign.
++        ** It merely means that we might do some extra work to journal a 
++        ** page that does not need to be journaled.  Nevertheless, be sure 
++        ** to test the case where a malloc error occurs while trying to set 
++        ** a bit in a bit vector.
++        */
++        sqlite3BeginBenignMalloc();
++        if( pgno<=pPager->dbOrigSize ){
++          TESTONLY( rc = ) sqlite3BitvecSet(pPager->pInJournal, pgno);
++          testcase( rc==SQLITE_NOMEM );
++        }
++        TESTONLY( rc = ) addToSavepointBitvecs(pPager, pgno);
++        testcase( rc==SQLITE_NOMEM );
++        sqlite3EndBenignMalloc();
++      }
++      memset(pPg->pData, 0, pPager->pageSize);
++      IOTRACE(("ZERO %p %d\n", pPager, pgno));
++    }else{
++      if( pagerUseWal(pPager) && bMmapOk==0 ){
++        rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame);
++        if( rc!=SQLITE_OK ) goto pager_acquire_err;
++      }
++      assert( pPg->pPager==pPager );
++      pPager->aStat[PAGER_STAT_MISS]++;
++      rc = readDbPage(pPg, iFrame);
++      if( rc!=SQLITE_OK ){
++        goto pager_acquire_err;
++      }
++    }
++    pager_set_pagehash(pPg);
+   }
++
++  return SQLITE_OK;
++
++pager_acquire_err:
++  assert( rc!=SQLITE_OK );
++  if( pPg ){
++    sqlite3PcacheDrop(pPg);
++  }
++  pagerUnlockIfUnused(pPager);
++
++  *ppPage = 0;
++  return rc;
+ }
+ 
+ /*
+-** Return true if this is an in-memory pager.
++** Acquire a page if it is already in the in-memory cache.  Do
++** not read the page from disk.  Return a pointer to the page,
++** or 0 if the page is not in cache. 
++**
++** See also sqlite3PagerGet().  The difference between this routine
++** and sqlite3PagerGet() is that _get() will go to the disk and read
++** in the page if the page is not already in cache.  This routine
++** returns NULL if the page is not in cache or if a disk I/O error 
++** has ever happened.
+ */
+-SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
+-  return MEMDB;
++SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){
++  sqlite3_pcache_page *pPage;
++  assert( pPager!=0 );
++  assert( pgno!=0 );
++  assert( pPager->pPCache!=0 );
++  pPage = sqlite3PcacheFetch(pPager->pPCache, pgno, 0);
++  assert( pPage==0 || pPager->hasBeenUsed );
++  return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage);
+ }
+ 
+ /*
+-** Check that there are at least nSavepoint savepoints open. If there are
+-** currently less than nSavepoints open, then open one or more savepoints
+-** to make up the difference. If the number of savepoints is already
+-** equal to nSavepoint, then this function is a no-op.
++** Release a page reference.
+ **
+-** If a memory allocation fails, SQLITE_NOMEM is returned. If an error 
+-** occurs while opening the sub-journal file, then an IO error code is
+-** returned. Otherwise, SQLITE_OK.
++** If the number of references to the page drop to zero, then the
++** page is added to the LRU list.  When all references to all pages
++** are released, a rollback occurs and the lock on the database is
++** removed.
+ */
+-SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){
+-  int rc = SQLITE_OK;                       /* Return code */
+-  int nCurrent = pPager->nSavepoint;        /* Current number of savepoints */
+-
+-  assert( pPager->eState>=PAGER_WRITER_LOCKED );
+-  assert( assert_pager_state(pPager) );
+-
+-  if( nSavepoint>nCurrent && pPager->useJournal ){
+-    int ii;                                 /* Iterator variable */
+-    PagerSavepoint *aNew;                   /* New Pager.aSavepoint array */
+-
+-    /* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM
+-    ** if the allocation fails. Otherwise, zero the new portion in case a 
+-    ** malloc failure occurs while populating it in the for(...) loop below.
+-    */
+-    aNew = (PagerSavepoint *)sqlite3Realloc(
+-        pPager->aSavepoint, sizeof(PagerSavepoint)*nSavepoint
+-    );
+-    if( !aNew ){
+-      return SQLITE_NOMEM;
+-    }
+-    memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint));
+-    pPager->aSavepoint = aNew;
+-
+-    /* Populate the PagerSavepoint structures just allocated. */
+-    for(ii=nCurrent; ii<nSavepoint; ii++){
+-      aNew[ii].nOrig = pPager->dbSize;
+-      if( isOpen(pPager->jfd) && pPager->journalOff>0 ){
+-        aNew[ii].iOffset = pPager->journalOff;
+-      }else{
+-        aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager);
+-      }
+-      aNew[ii].iSubRec = pPager->nSubRec;
+-      aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize);
+-      if( !aNew[ii].pInSavepoint ){
+-        return SQLITE_NOMEM;
+-      }
+-      if( pagerUseWal(pPager) ){
+-        sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData);
+-      }
+-      pPager->nSavepoint = ii+1;
+-    }
+-    assert( pPager->nSavepoint==nSavepoint );
+-    assertTruncateConstraint(pPager);
++SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage *pPg){
++  Pager *pPager;
++  assert( pPg!=0 );
++  pPager = pPg->pPager;
++  if( pPg->flags & PGHDR_MMAP ){
++    pagerReleaseMapPage(pPg);
++  }else{
++    sqlite3PcacheRelease(pPg);
+   }
+-
+-  return rc;
++  pagerUnlockIfUnused(pPager);
++}
++SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){
++  if( pPg ) sqlite3PagerUnrefNotNull(pPg);
+ }
+ 
+ /*
+-** This function is called to rollback or release (commit) a savepoint.
+-** The savepoint to release or rollback need not be the most recently 
+-** created savepoint.
+-**
+-** Parameter op is always either SAVEPOINT_ROLLBACK or SAVEPOINT_RELEASE.
+-** If it is SAVEPOINT_RELEASE, then release and destroy the savepoint with
+-** index iSavepoint. If it is SAVEPOINT_ROLLBACK, then rollback all changes
+-** that have occurred since the specified savepoint was created.
++** This function is called at the start of every write transaction.
++** There must already be a RESERVED or EXCLUSIVE lock on the database 
++** file when this routine is called.
+ **
+-** The savepoint to rollback or release is identified by parameter 
+-** iSavepoint. A value of 0 means to operate on the outermost savepoint
+-** (the first created). A value of (Pager.nSavepoint-1) means operate
+-** on the most recently created savepoint. If iSavepoint is greater than
+-** (Pager.nSavepoint-1), then this function is a no-op.
++** Open the journal file for pager pPager and write a journal header
++** to the start of it. If there are active savepoints, open the sub-journal
++** as well. This function is only used when the journal file is being 
++** opened to write a rollback log for a transaction. It is not used 
++** when opening a hot journal file to roll it back.
+ **
+-** If a negative value is passed to this function, then the current
+-** transaction is rolled back. This is different to calling 
+-** sqlite3PagerRollback() because this function does not terminate
+-** the transaction or unlock the database, it just restores the 
+-** contents of the database to its original state. 
++** If the journal file is already open (as it may be in exclusive mode),
++** then this function just writes a journal header to the start of the
++** already open file. 
+ **
+-** In any case, all savepoints with an index greater than iSavepoint 
+-** are destroyed. If this is a release operation (op==SAVEPOINT_RELEASE),
+-** then savepoint iSavepoint is also destroyed.
++** Whether or not the journal file is opened by this function, the
++** Pager.pInJournal bitvec structure is allocated.
+ **
+-** This function may return SQLITE_NOMEM if a memory allocation fails,
+-** or an IO error code if an IO error occurs while rolling back a 
+-** savepoint. If no errors occur, SQLITE_OK is returned.
+-*/ 
+-SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
+-  int rc = pPager->errCode;       /* Return code */
+-
+-  assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK );
+-  assert( iSavepoint>=0 || op==SAVEPOINT_ROLLBACK );
++** Return SQLITE_OK if everything is successful. Otherwise, return 
++** SQLITE_NOMEM if the attempt to allocate Pager.pInJournal fails, or 
++** an IO error code if opening or writing the journal file fails.
++*/
++static int pager_open_journal(Pager *pPager){
++  int rc = SQLITE_OK;                        /* Return code */
++  sqlite3_vfs * const pVfs = pPager->pVfs;   /* Local cache of vfs pointer */
+ 
+-  if( rc==SQLITE_OK && iSavepoint<pPager->nSavepoint ){
+-    int ii;            /* Iterator variable */
+-    int nNew;          /* Number of remaining savepoints after this op. */
++  assert( pPager->eState==PAGER_WRITER_LOCKED );
++  assert( assert_pager_state(pPager) );
++  assert( pPager->pInJournal==0 );
++  
++  /* If already in the error state, this function is a no-op.  But on
++  ** the other hand, this routine is never called if we are already in
++  ** an error state. */
++  if( NEVER(pPager->errCode) ) return pPager->errCode;
+ 
+-    /* Figure out how many savepoints will still be active after this
+-    ** operation. Store this value in nNew. Then free resources associated 
+-    ** with any savepoints that are destroyed by this operation.
+-    */
+-    nNew = iSavepoint + (( op==SAVEPOINT_RELEASE ) ? 0 : 1);
+-    for(ii=nNew; ii<pPager->nSavepoint; ii++){
+-      sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
++  if( !pagerUseWal(pPager) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
++    pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize);
++    if( pPager->pInJournal==0 ){
++      return SQLITE_NOMEM;
+     }
+-    pPager->nSavepoint = nNew;
++  
++    /* Open the journal file if it is not already open. */
++    if( !isOpen(pPager->jfd) ){
++      if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){
++        sqlite3MemJournalOpen(pPager->jfd);
++      }else{
++        const int flags =                   /* VFS flags to open journal file */
++          SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
++          (pPager->tempFile ? 
++            (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL):
++            (SQLITE_OPEN_MAIN_JOURNAL)
++          );
+ 
+-    /* If this is a release of the outermost savepoint, truncate 
+-    ** the sub-journal to zero bytes in size. */
+-    if( op==SAVEPOINT_RELEASE ){
+-      if( nNew==0 && isOpen(pPager->sjfd) ){
+-        /* Only truncate if it is an in-memory sub-journal. */
+-        if( sqlite3IsMemJournal(pPager->sjfd) ){
+-          rc = sqlite3OsTruncate(pPager->sjfd, 0);
+-          assert( rc==SQLITE_OK );
++        /* Verify that the database still has the same name as it did when
++        ** it was originally opened. */
++        rc = databaseIsUnmoved(pPager);
++        if( rc==SQLITE_OK ){
++#ifdef SQLITE_ENABLE_ATOMIC_WRITE
++          rc = sqlite3JournalOpen(
++              pVfs, pPager->zJournal, pPager->jfd, flags, jrnlBufferSize(pPager)
++          );
++#else
++          rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, flags, 0);
++#endif
+         }
+-        pPager->nSubRec = 0;
+       }
++      assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
+     }
+-    /* Else this is a rollback operation, playback the specified savepoint.
+-    ** If this is a temp-file, it is possible that the journal file has
+-    ** not yet been opened. In this case there have been no changes to
+-    ** the database file, so the playback operation can be skipped.
++  
++  
++    /* Write the first journal header to the journal file and open 
++    ** the sub-journal if necessary.
+     */
+-    else if( pagerUseWal(pPager) || isOpen(pPager->jfd) ){
+-      PagerSavepoint *pSavepoint = (nNew==0)?0:&pPager->aSavepoint[nNew-1];
+-      rc = pagerPlaybackSavepoint(pPager, pSavepoint);
+-      assert(rc!=SQLITE_DONE);
++    if( rc==SQLITE_OK ){
++      /* TODO: Check if all of these are really required. */
++      pPager->nRec = 0;
++      pPager->journalOff = 0;
++      pPager->setMaster = 0;
++      pPager->journalHdr = 0;
++      rc = writeJournalHdr(pPager);
+     }
+   }
+ 
++  if( rc!=SQLITE_OK ){
++    sqlite3BitvecDestroy(pPager->pInJournal);
++    pPager->pInJournal = 0;
++  }else{
++    assert( pPager->eState==PAGER_WRITER_LOCKED );
++    pPager->eState = PAGER_WRITER_CACHEMOD;
++  }
++
+   return rc;
+ }
+ 
+ /*
+-** Return the full pathname of the database file.
++** Begin a write-transaction on the specified pager object. If a 
++** write-transaction has already been opened, this function is a no-op.
+ **
+-** Except, if the pager is in-memory only, then return an empty string if
+-** nullIfMemDb is true.  This routine is called with nullIfMemDb==1 when
+-** used to report the filename to the user, for compatibility with legacy
+-** behavior.  But when the Btree needs to know the filename for matching to
+-** shared cache, it uses nullIfMemDb==0 so that in-memory databases can
+-** participate in shared-cache.
++** If the exFlag argument is false, then acquire at least a RESERVED
++** lock on the database file. If exFlag is true, then acquire at least
++** an EXCLUSIVE lock. If such a lock is already held, no locking 
++** functions need be called.
++**
++** If the subjInMemory argument is non-zero, then any sub-journal opened
++** within this transaction will be opened as an in-memory file. This
++** has no effect if the sub-journal is already opened (as it may be when
++** running in exclusive mode) or if the transaction does not require a
++** sub-journal. If the subjInMemory argument is zero, then any required
++** sub-journal is implemented in-memory if pPager is an in-memory database, 
++** or using a temporary file otherwise.
+ */
+-SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){
+-  return (nullIfMemDb && pPager->memDb) ? "" : pPager->zFilename;
+-}
++SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){
++  int rc = SQLITE_OK;
+ 
+-/*
+-** Return the VFS structure for the pager.
+-*/
+-SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){
+-  return pPager->pVfs;
+-}
++  if( pPager->errCode ) return pPager->errCode;
++  assert( pPager->eState>=PAGER_READER && pPager->eState<PAGER_ERROR );
++  pPager->subjInMemory = (u8)subjInMemory;
+ 
+-/*
+-** Return the file handle for the database file associated
+-** with the pager.  This might return NULL if the file has
+-** not yet been opened.
+-*/
+-SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){
+-  return pPager->fd;
+-}
++  if( ALWAYS(pPager->eState==PAGER_READER) ){
++    assert( pPager->pInJournal==0 );
+ 
+-/*
+-** Return the full pathname of the journal file.
+-*/
+-SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager *pPager){
+-  return pPager->zJournal;
+-}
++    if( pagerUseWal(pPager) ){
++      /* If the pager is configured to use locking_mode=exclusive, and an
++      ** exclusive lock on the database is not already held, obtain it now.
++      */
++      if( pPager->exclusiveMode && sqlite3WalExclusiveMode(pPager->pWal, -1) ){
++        rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
++        if( rc!=SQLITE_OK ){
++          return rc;
++        }
++        sqlite3WalExclusiveMode(pPager->pWal, 1);
++      }
+ 
+-/*
+-** Return true if fsync() calls are disabled for this pager.  Return FALSE
+-** if fsync()s are executed normally.
+-*/
+-SQLITE_PRIVATE int sqlite3PagerNosync(Pager *pPager){
+-  return pPager->noSync;
+-}
++      /* Grab the write lock on the log file. If successful, upgrade to
++      ** PAGER_RESERVED state. Otherwise, return an error code to the caller.
++      ** The busy-handler is not invoked if another connection already
++      ** holds the write-lock. If possible, the upper layer will call it.
++      */
++      rc = sqlite3WalBeginWriteTransaction(pPager->pWal);
++    }else{
++      /* Obtain a RESERVED lock on the database file. If the exFlag parameter
++      ** is true, then immediately upgrade this to an EXCLUSIVE lock. The
++      ** busy-handler callback can be used when upgrading to the EXCLUSIVE
++      ** lock, but not when obtaining the RESERVED lock.
++      */
++      rc = pagerLockDb(pPager, RESERVED_LOCK);
++      if( rc==SQLITE_OK && exFlag ){
++        rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
++      }
++    }
+ 
+-#ifdef SQLITE_HAS_CODEC
+-/*
+-** Set or retrieve the codec for this pager
+-*/
+-SQLITE_PRIVATE void sqlite3PagerSetCodec(
+-  Pager *pPager,
+-  void *(*xCodec)(void*,void*,Pgno,int),
+-  void (*xCodecSizeChng)(void*,int,int),
+-  void (*xCodecFree)(void*),
+-  void *pCodec
+-){
+-  if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
+-  pPager->xCodec = pPager->memDb ? 0 : xCodec;
+-  pPager->xCodecSizeChng = xCodecSizeChng;
+-  pPager->xCodecFree = xCodecFree;
+-  pPager->pCodec = pCodec;
+-  pagerReportSize(pPager);
+-}
+-SQLITE_PRIVATE void *sqlite3PagerGetCodec(Pager *pPager){
+-  return pPager->pCodec;
+-}
++    if( rc==SQLITE_OK ){
++      /* Change to WRITER_LOCKED state.
++      **
++      ** WAL mode sets Pager.eState to PAGER_WRITER_LOCKED or CACHEMOD
++      ** when it has an open transaction, but never to DBMOD or FINISHED.
++      ** This is because in those states the code to roll back savepoint 
++      ** transactions may copy data from the sub-journal into the database 
++      ** file as well as into the page cache. Which would be incorrect in 
++      ** WAL mode.
++      */
++      pPager->eState = PAGER_WRITER_LOCKED;
++      pPager->dbHintSize = pPager->dbSize;
++      pPager->dbFileSize = pPager->dbSize;
++      pPager->dbOrigSize = pPager->dbSize;
++      pPager->journalOff = 0;
++    }
+ 
+-/*
+-** This function is called by the wal module when writing page content
+-** into the log file.
+-**
+-** This function returns a pointer to a buffer containing the encrypted
+-** page content. If a malloc fails, this function may return NULL.
+-*/
+-SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){
+-  void *aData = 0;
+-  CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData);
+-  return aData;
+-}
++    assert( rc==SQLITE_OK || pPager->eState==PAGER_READER );
++    assert( rc!=SQLITE_OK || pPager->eState==PAGER_WRITER_LOCKED );
++    assert( assert_pager_state(pPager) );
++  }
+ 
+-/*
+-** Return the current pager state
+-*/
+-SQLITE_PRIVATE int sqlite3PagerState(Pager *pPager){
+-  return pPager->eState;
++  PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager)));
++  return rc;
+ }
+-#endif /* SQLITE_HAS_CODEC */
+ 
+-#ifndef SQLITE_OMIT_AUTOVACUUM
+ /*
+-** Move the page pPg to location pgno in the file.
+-**
+-** There must be no references to the page previously located at
+-** pgno (which we call pPgOld) though that page is allowed to be
+-** in cache.  If the page previously located at pgno is not already
+-** in the rollback journal, it is not put there by by this routine.
+-**
+-** References to the page pPg remain valid. Updating any
+-** meta-data associated with pPg (i.e. data stored in the nExtra bytes
+-** allocated along with the page) is the responsibility of the caller.
+-**
+-** A transaction must be active when this routine is called. It used to be
+-** required that a statement transaction was not active, but this restriction
+-** has been removed (CREATE INDEX needs to move a page when a statement
+-** transaction is active).
+-**
+-** If the fourth argument, isCommit, is non-zero, then this page is being
+-** moved as part of a database reorganization just before the transaction 
+-** is being committed. In this case, it is guaranteed that the database page 
+-** pPg refers to will not be written to again within this transaction.
+-**
+-** This function may return SQLITE_NOMEM or an IO error code if an error
+-** occurs. Otherwise, it returns SQLITE_OK.
++** Mark a single data page as writeable. The page is written into the 
++** main journal or sub-journal as required. If the page is written into
++** one of the journals, the corresponding bit is set in the 
++** Pager.pInJournal bitvec and the PagerSavepoint.pInSavepoint bitvecs
++** of any open savepoints as appropriate.
+ */
+-SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
+-  PgHdr *pPgOld;               /* The page being overwritten. */
+-  Pgno needSyncPgno = 0;       /* Old value of pPg->pgno, if sync is required */
+-  int rc;                      /* Return code */
+-  Pgno origPgno;               /* The original page number */
++static int pager_write(PgHdr *pPg){
++  Pager *pPager = pPg->pPager;
++  int rc = SQLITE_OK;
++  int inJournal;
+ 
+-  assert( pPg->nRef>0 );
+-  assert( pPager->eState==PAGER_WRITER_CACHEMOD
++  /* This routine is not called unless a write-transaction has already 
++  ** been started. The journal file may or may not be open at this point.
++  ** It is never called in the ERROR state.
++  */
++  assert( pPager->eState==PAGER_WRITER_LOCKED
++       || pPager->eState==PAGER_WRITER_CACHEMOD
+        || pPager->eState==PAGER_WRITER_DBMOD
+   );
+   assert( assert_pager_state(pPager) );
++  assert( pPager->errCode==0 );
++  assert( pPager->readOnly==0 );
+ 
+-  /* In order to be able to rollback, an in-memory database must journal
+-  ** the page we are moving from.
+-  */
+-  if( MEMDB ){
+-    rc = sqlite3PagerWrite(pPg);
+-    if( rc ) return rc;
+-  }
++  CHECK_PAGE(pPg);
+ 
+-  /* If the page being moved is dirty and has not been saved by the latest
+-  ** savepoint, then save the current contents of the page into the 
+-  ** sub-journal now. This is required to handle the following scenario:
+-  **
+-  **   BEGIN;
+-  **     <journal page X, then modify it in memory>
+-  **     SAVEPOINT one;
+-  **       <Move page X to location Y>
+-  **     ROLLBACK TO one;
+-  **
+-  ** If page X were not written to the sub-journal here, it would not
+-  ** be possible to restore its contents when the "ROLLBACK TO one"
+-  ** statement were is processed.
++  /* The journal file needs to be opened. Higher level routines have already
++  ** obtained the necessary locks to begin the write-transaction, but the
++  ** rollback journal might not yet be open. Open it now if this is the case.
+   **
+-  ** subjournalPage() may need to allocate space to store pPg->pgno into
+-  ** one or more savepoint bitvecs. This is the reason this function
+-  ** may return SQLITE_NOMEM.
++  ** This is done before calling sqlite3PcacheMakeDirty() on the page. 
++  ** Otherwise, if it were done after calling sqlite3PcacheMakeDirty(), then
++  ** an error might occur and the pager would end up in WRITER_LOCKED state
++  ** with pages marked as dirty in the cache.
+   */
+-  if( pPg->flags&PGHDR_DIRTY
+-   && subjRequiresPage(pPg)
+-   && SQLITE_OK!=(rc = subjournalPage(pPg))
+-  ){
+-    return rc;
++  if( pPager->eState==PAGER_WRITER_LOCKED ){
++    rc = pager_open_journal(pPager);
++    if( rc!=SQLITE_OK ) return rc;
+   }
++  assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
++  assert( assert_pager_state(pPager) );
+ 
+-  PAGERTRACE(("MOVE %d page %d (needSync=%d) moves to %d\n", 
+-      PAGERID(pPager), pPg->pgno, (pPg->flags&PGHDR_NEED_SYNC)?1:0, pgno));
+-  IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno))
+-
+-  /* If the journal needs to be sync()ed before page pPg->pgno can
+-  ** be written to, store pPg->pgno in local variable needSyncPgno.
+-  **
+-  ** If the isCommit flag is set, there is no need to remember that
+-  ** the journal needs to be sync()ed before database page pPg->pgno 
+-  ** can be written to. The caller has already promised not to write to it.
++  /* Mark the page as dirty.  If the page has already been written
++  ** to the journal then we can return right away.
+   */
+-  if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){
+-    needSyncPgno = pPg->pgno;
+-    assert( pPager->journalMode==PAGER_JOURNALMODE_OFF ||
+-            pageInJournal(pPager, pPg) || pPg->pgno>pPager->dbOrigSize );
+-    assert( pPg->flags&PGHDR_DIRTY );
++  sqlite3PcacheMakeDirty(pPg);
++  inJournal = pageInJournal(pPager, pPg);
++  if( inJournal && (pPager->nSavepoint==0 || !subjRequiresPage(pPg)) ){
++    assert( !pagerUseWal(pPager) );
++  }else{
++  
++    /* The transaction journal now exists and we have a RESERVED or an
++    ** EXCLUSIVE lock on the main database file.  Write the current page to
++    ** the transaction journal if it is not there already.
++    */
++    if( !inJournal && !pagerUseWal(pPager) ){
++      assert( pagerUseWal(pPager)==0 );
++      if( pPg->pgno<=pPager->dbOrigSize && isOpen(pPager->jfd) ){
++        u32 cksum;
++        char *pData2;
++        i64 iOff = pPager->journalOff;
++
++        /* We should never write to the journal file the page that
++        ** contains the database locks.  The following assert verifies
++        ** that we do not. */
++        assert( pPg->pgno!=PAGER_MJ_PGNO(pPager) );
++
++        assert( pPager->journalHdr<=pPager->journalOff );
++        CODEC2(pPager, pPg->pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
++        cksum = pager_cksum(pPager, (u8*)pData2);
++
++        /* Even if an IO or diskfull error occurs while journalling the
++        ** page in the block above, set the need-sync flag for the page.
++        ** Otherwise, when the transaction is rolled back, the logic in
++        ** playback_one_page() will think that the page needs to be restored
++        ** in the database file. And if an IO error occurs while doing so,
++        ** then corruption may follow.
++        */
++        pPg->flags |= PGHDR_NEED_SYNC;
++
++        rc = write32bits(pPager->jfd, iOff, pPg->pgno);
++        if( rc!=SQLITE_OK ) return rc;
++        rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize, iOff+4);
++        if( rc!=SQLITE_OK ) return rc;
++        rc = write32bits(pPager->jfd, iOff+pPager->pageSize+4, cksum);
++        if( rc!=SQLITE_OK ) return rc;
++
++        IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, 
++                 pPager->journalOff, pPager->pageSize));
++        PAGER_INCR(sqlite3_pager_writej_count);
++        PAGERTRACE(("JOURNAL %d page %d needSync=%d hash(%08x)\n",
++             PAGERID(pPager), pPg->pgno, 
++             ((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg)));
++
++        pPager->journalOff += 8 + pPager->pageSize;
++        pPager->nRec++;
++        assert( pPager->pInJournal!=0 );
++        rc = sqlite3BitvecSet(pPager->pInJournal, pPg->pgno);
++        testcase( rc==SQLITE_NOMEM );
++        assert( rc==SQLITE_OK || rc==SQLITE_NOMEM );
++        rc |= addToSavepointBitvecs(pPager, pPg->pgno);
++        if( rc!=SQLITE_OK ){
++          assert( rc==SQLITE_NOMEM );
++          return rc;
++        }
++      }else{
++        if( pPager->eState!=PAGER_WRITER_DBMOD ){
++          pPg->flags |= PGHDR_NEED_SYNC;
++        }
++        PAGERTRACE(("APPEND %d page %d needSync=%d\n",
++                PAGERID(pPager), pPg->pgno,
++               ((pPg->flags&PGHDR_NEED_SYNC)?1:0)));
++      }
++    }
++  
++    /* If the statement journal is open and the page is not in it,
++    ** then write the current page to the statement journal.  Note that
++    ** the statement journal format differs from the standard journal format
++    ** in that it omits the checksums and the header.
++    */
++    if( pPager->nSavepoint>0 && subjRequiresPage(pPg) ){
++      rc = subjournalPage(pPg);
++    }
+   }
+ 
+-  /* If the cache contains a page with page-number pgno, remove it
+-  ** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for 
+-  ** page pgno before the 'move' operation, it needs to be retained 
+-  ** for the page moved there.
++  /* Update the database size and return.
+   */
+-  pPg->flags &= ~PGHDR_NEED_SYNC;
+-  pPgOld = sqlite3PagerLookup(pPager, pgno);
+-  assert( !pPgOld || pPgOld->nRef==1 );
+-  if( pPgOld ){
+-    pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
+-    if( MEMDB ){
+-      /* Do not discard pages from an in-memory database since we might
+-      ** need to rollback later.  Just move the page out of the way. */
+-      sqlite3PcacheMove(pPgOld, pPager->dbSize+1);
+-    }else{
+-      sqlite3PcacheDrop(pPgOld);
+-    }
++  if( pPager->dbSize<pPg->pgno ){
++    pPager->dbSize = pPg->pgno;
+   }
++  return rc;
++}
+ 
+-  origPgno = pPg->pgno;
+-  sqlite3PcacheMove(pPg, pgno);
+-  sqlite3PcacheMakeDirty(pPg);
++/*
++** This is a variant of sqlite3PagerWrite() that runs when the sector size
++** is larger than the page size.  SQLite makes the (reasonable) assumption that
++** all bytes of a sector are written together by hardware.  Hence, all bytes of
++** a sector need to be journalled in case of a power loss in the middle of
++** a write.
++**
++** Usually, the sector size is less than or equal to the page size, in which
++** case pages can be individually written.  This routine only runs in the exceptional
++** case where the page size is smaller than the sector size.
++*/
++static SQLITE_NOINLINE int pagerWriteLargeSector(PgHdr *pPg){
++  int rc = SQLITE_OK;            /* Return code */
++  Pgno nPageCount;               /* Total number of pages in database file */
++  Pgno pg1;                      /* First page of the sector pPg is located on. */
++  int nPage = 0;                 /* Number of pages starting at pg1 to journal */
++  int ii;                        /* Loop counter */
++  int needSync = 0;              /* True if any page has PGHDR_NEED_SYNC */
++  Pager *pPager = pPg->pPager;   /* The pager that owns pPg */
++  Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize);
+ 
+-  /* For an in-memory database, make sure the original page continues
+-  ** to exist, in case the transaction needs to roll back.  Use pPgOld
+-  ** as the original page since it has already been allocated.
++  /* Set the doNotSpill NOSYNC bit to 1. This is because we cannot allow
++  ** a journal header to be written between the pages journaled by
++  ** this function.
+   */
+-  if( MEMDB ){
+-    assert( pPgOld );
+-    sqlite3PcacheMove(pPgOld, origPgno);
+-    sqlite3PagerUnrefNotNull(pPgOld);
++  assert( !MEMDB );
++  assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)==0 );
++  pPager->doNotSpill |= SPILLFLAG_NOSYNC;
++
++  /* This trick assumes that both the page-size and sector-size are
++  ** an integer power of 2. It sets variable pg1 to the identifier
++  ** of the first page of the sector pPg is located on.
++  */
++  pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1;
 +
++  nPageCount = pPager->dbSize;
++  if( pPg->pgno>nPageCount ){
++    nPage = (pPg->pgno - pg1)+1;
++  }else if( (pg1+nPagePerSector-1)>nPageCount ){
++    nPage = nPageCount+1-pg1;
++  }else{
++    nPage = nPagePerSector;
+   }
++  assert(nPage>0);
++  assert(pg1<=pPg->pgno);
++  assert((pg1+nPage)>pPg->pgno);
+ 
+-  if( needSyncPgno ){
+-    /* If needSyncPgno is non-zero, then the journal file needs to be 
+-    ** sync()ed before any data is written to database file page needSyncPgno.
+-    ** Currently, no such page exists in the page-cache and the 
+-    ** "is journaled" bitvec flag has been set. This needs to be remedied by
+-    ** loading the page into the pager-cache and setting the PGHDR_NEED_SYNC
+-    ** flag.
+-    **
+-    ** If the attempt to load the page into the page-cache fails, (due
+-    ** to a malloc() or IO failure), clear the bit in the pInJournal[]
+-    ** array. Otherwise, if the page is loaded and written again in
+-    ** this transaction, it may be written to the database file before
+-    ** it is synced into the journal file. This way, it may end up in
+-    ** the journal file twice, but that is not a problem.
+-    */
+-    PgHdr *pPgHdr;
+-    rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr);
+-    if( rc!=SQLITE_OK ){
+-      if( needSyncPgno<=pPager->dbOrigSize ){
+-        assert( pPager->pTmpSpace!=0 );
+-        sqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace);
++  for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){
++    Pgno pg = pg1+ii;
++    PgHdr *pPage;
++    if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){
++      if( pg!=PAGER_MJ_PGNO(pPager) ){
++        rc = sqlite3PagerGet(pPager, pg, &pPage);
++        if( rc==SQLITE_OK ){
++          rc = pager_write(pPage);
++          if( pPage->flags&PGHDR_NEED_SYNC ){
++            needSync = 1;
++          }
++          sqlite3PagerUnrefNotNull(pPage);
++        }
+       }
+-      return rc;
++    }else if( (pPage = sqlite3PagerLookup(pPager, pg))!=0 ){
++      if( pPage->flags&PGHDR_NEED_SYNC ){
++        needSync = 1;
++      }
++      sqlite3PagerUnrefNotNull(pPage);
+     }
+-    pPgHdr->flags |= PGHDR_NEED_SYNC;
+-    sqlite3PcacheMakeDirty(pPgHdr);
+-    sqlite3PagerUnrefNotNull(pPgHdr);
+   }
+ 
+-  return SQLITE_OK;
+-}
+-#endif
++  /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages 
++  ** starting at pg1, then it needs to be set for all of them. Because
++  ** writing to any of these nPage pages may damage the others, the
++  ** journal file must contain sync()ed copies of all of them
++  ** before any of them can be written out to the database file.
++  */
++  if( rc==SQLITE_OK && needSync ){
++    assert( !MEMDB );
++    for(ii=0; ii<nPage; ii++){
++      PgHdr *pPage = sqlite3PagerLookup(pPager, pg1+ii);
++      if( pPage ){
++        pPage->flags |= PGHDR_NEED_SYNC;
++        sqlite3PagerUnrefNotNull(pPage);
++      }
++    }
++  }
+ 
+-/*
+-** The page handle passed as the first argument refers to a dirty page 
+-** with a page number other than iNew. This function changes the page's 
+-** page number to iNew and sets the value of the PgHdr.flags field to 
+-** the value passed as the third parameter.
+-*/
+-SQLITE_PRIVATE void sqlite3PagerRekey(DbPage *pPg, Pgno iNew, u16 flags){
+-  assert( pPg->pgno!=iNew );
+-  pPg->flags = flags;
+-  sqlite3PcacheMove(pPg, iNew);
++  assert( (pPager->doNotSpill & SPILLFLAG_NOSYNC)!=0 );
++  pPager->doNotSpill &= ~SPILLFLAG_NOSYNC;
++  return rc;
+ }
+ 
+ /*
+-** Return a pointer to the data for the specified page.
++** Mark a data page as writeable. This routine must be called before 
++** making changes to a page. The caller must check the return value 
++** of this function and be careful not to change any page data unless 
++** this routine returns SQLITE_OK.
++**
++** The difference between this function and pager_write() is that this
++** function also deals with the special case where 2 or more pages
++** fit on a single disk sector. In this case all co-resident pages
++** must have been written to the journal file before returning.
++**
++** If an error occurs, SQLITE_NOMEM or an IO error code is returned
++** as appropriate. Otherwise, SQLITE_OK.
+ */
+-SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *pPg){
+-  assert( pPg->nRef>0 || pPg->pPager->memDb );
+-  return pPg->pData;
++SQLITE_PRIVATE int sqlite3PagerWrite(PgHdr *pPg){
++  assert( (pPg->flags & PGHDR_MMAP)==0 );
++  assert( pPg->pPager->eState>=PAGER_WRITER_LOCKED );
++  assert( pPg->pPager->eState!=PAGER_ERROR );
++  assert( assert_pager_state(pPg->pPager) );
++  if( pPg->pPager->sectorSize > (u32)pPg->pPager->pageSize ){
++    return pagerWriteLargeSector(pPg);
++  }else{
++    return pager_write(pPg);
++  }
+ }
+ 
+ /*
+-** Return a pointer to the Pager.nExtra bytes of "extra" space 
+-** allocated along with the specified page.
++** Return TRUE if the page given in the argument was previously passed
++** to sqlite3PagerWrite().  In other words, return TRUE if it is ok
++** to change the content of the page.
+ */
+-SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *pPg){
+-  return pPg->pExtra;
++#ifndef NDEBUG
++SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage *pPg){
++  return pPg->flags&PGHDR_DIRTY;
+ }
++#endif
  
- /************** End of pager.c ***********************************************/
- /************** Begin file wal.c *********************************************/
-@@ -47711,3561 +51294,2887 @@
- ** Both readers can use the same hash table and mapping section to get
- ** the correct result.  There may be entries in the hash table with
- ** K>K0 but to the first reader, those entries will appear to be unused
+ /*
+-** Get/set the locking-mode for this pager. Parameter eMode must be one
+-** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or 
+-** PAGER_LOCKINGMODE_EXCLUSIVE. If the parameter is not _QUERY, then
+-** the locking-mode is set to the value specified.
++** A call to this routine tells the pager that it is not necessary to
++** write the information on page pPg back to the disk, even though
++** that page might be marked as dirty.  This happens, for example, when
++** the page has been added as a leaf of the freelist and so its
++** content no longer matters.
+ **
+-** The returned value is either PAGER_LOCKINGMODE_NORMAL or
+-** PAGER_LOCKINGMODE_EXCLUSIVE, indicating the current (possibly updated)
+-** locking-mode.
++** The overlying software layer calls this routine when all of the data
++** on the given page is unused. The pager marks the page as clean so
++** that it does not get written to disk.
++**
++** Tests show that this optimization can quadruple the speed of large 
++** DELETE operations.
+ */
+-SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *pPager, int eMode){
+-  assert( eMode==PAGER_LOCKINGMODE_QUERY
+-            || eMode==PAGER_LOCKINGMODE_NORMAL
+-            || eMode==PAGER_LOCKINGMODE_EXCLUSIVE );
+-  assert( PAGER_LOCKINGMODE_QUERY<0 );
+-  assert( PAGER_LOCKINGMODE_NORMAL>=0 && PAGER_LOCKINGMODE_EXCLUSIVE>=0 );
+-  assert( pPager->exclusiveMode || 0==sqlite3WalHeapMemory(pPager->pWal) );
+-  if( eMode>=0 && !pPager->tempFile && !sqlite3WalHeapMemory(pPager->pWal) ){
+-    pPager->exclusiveMode = (u8)eMode;
++SQLITE_PRIVATE void sqlite3PagerDontWrite(PgHdr *pPg){
++  Pager *pPager = pPg->pPager;
++  if( (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){
++    PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager)));
++    IOTRACE(("CLEAN %p %d\n", pPager, pPg->pgno))
++    pPg->flags |= PGHDR_DONT_WRITE;
++    pager_set_pagehash(pPg);
+   }
+-  return (int)pPager->exclusiveMode;
+ }
+ 
+ /*
+-** Set the journal-mode for this pager. Parameter eMode must be one of:
+-**
+-**    PAGER_JOURNALMODE_DELETE
+-**    PAGER_JOURNALMODE_TRUNCATE
+-**    PAGER_JOURNALMODE_PERSIST
+-**    PAGER_JOURNALMODE_OFF
+-**    PAGER_JOURNALMODE_MEMORY
+-**    PAGER_JOURNALMODE_WAL
+-**
+-** The journalmode is set to the value specified if the change is allowed.
+-** The change may be disallowed for the following reasons:
++** This routine is called to increment the value of the database file 
++** change-counter, stored as a 4-byte big-endian integer starting at 
++** byte offset 24 of the pager file.  The secondary change counter at
++** 92 is also updated, as is the SQLite version number at offset 96.
+ **
+-**   *  An in-memory database can only have its journal_mode set to _OFF
+-**      or _MEMORY.
++** But this only happens if the pPager->changeCountDone flag is false.
++** To avoid excess churning of page 1, the update only happens once.
++** See also the pager_write_changecounter() routine that does an 
++** unconditional update of the change counters.
+ **
+-**   *  Temporary databases cannot have _WAL journalmode.
++** If the isDirectMode flag is zero, then this is done by calling 
++** sqlite3PagerWrite() on page 1, then modifying the contents of the
++** page data. In this case the file will be updated when the current
++** transaction is committed.
+ **
+-** The returned indicate the current (possibly updated) journal-mode.
++** The isDirectMode flag may only be non-zero if the library was compiled
++** with the SQLITE_ENABLE_ATOMIC_WRITE macro defined. In this case,
++** if isDirect is non-zero, then the database file is updated directly
++** by writing an updated version of page 1 using a call to the 
++** sqlite3OsWrite() function.
+ */
+-SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){
+-  u8 eOld = pPager->journalMode;    /* Prior journalmode */
+-
+-#ifdef SQLITE_DEBUG
+-  /* The print_pager_state() routine is intended to be used by the debugger
+-  ** only.  We invoke it once here to suppress a compiler warning. */
+-  print_pager_state(pPager);
+-#endif
+-
++static int pager_incr_changecounter(Pager *pPager, int isDirectMode){
++  int rc = SQLITE_OK;
+ 
+-  /* The eMode parameter is always valid */
+-  assert(      eMode==PAGER_JOURNALMODE_DELETE
+-            || eMode==PAGER_JOURNALMODE_TRUNCATE
+-            || eMode==PAGER_JOURNALMODE_PERSIST
+-            || eMode==PAGER_JOURNALMODE_OFF 
+-            || eMode==PAGER_JOURNALMODE_WAL 
+-            || eMode==PAGER_JOURNALMODE_MEMORY );
++  assert( pPager->eState==PAGER_WRITER_CACHEMOD
++       || pPager->eState==PAGER_WRITER_DBMOD
++  );
++  assert( assert_pager_state(pPager) );
+ 
+-  /* This routine is only called from the OP_JournalMode opcode, and
+-  ** the logic there will never allow a temporary file to be changed
+-  ** to WAL mode.
++  /* Declare and initialize constant integer 'isDirect'. If the
++  ** atomic-write optimization is enabled in this build, then isDirect
++  ** is initialized to the value passed as the isDirectMode parameter
++  ** to this function. Otherwise, it is always set to zero.
++  **
++  ** The idea is that if the atomic-write optimization is not
++  ** enabled at compile time, the compiler can omit the tests of
++  ** 'isDirect' below, as well as the block enclosed in the
++  ** "if( isDirect )" condition.
+   */
+-  assert( pPager->tempFile==0 || eMode!=PAGER_JOURNALMODE_WAL );
++#ifndef SQLITE_ENABLE_ATOMIC_WRITE
++# define DIRECT_MODE 0
++  assert( isDirectMode==0 );
++  UNUSED_PARAMETER(isDirectMode);
++#else
++# define DIRECT_MODE isDirectMode
++#endif
+ 
+-  /* Do allow the journalmode of an in-memory database to be set to
+-  ** anything other than MEMORY or OFF
+-  */
+-  if( MEMDB ){
+-    assert( eOld==PAGER_JOURNALMODE_MEMORY || eOld==PAGER_JOURNALMODE_OFF );
+-    if( eMode!=PAGER_JOURNALMODE_MEMORY && eMode!=PAGER_JOURNALMODE_OFF ){
+-      eMode = eOld;
+-    }
+-  }
++  if( !pPager->changeCountDone && ALWAYS(pPager->dbSize>0) ){
++    PgHdr *pPgHdr;                /* Reference to page 1 */
+ 
+-  if( eMode!=eOld ){
++    assert( !pPager->tempFile && isOpen(pPager->fd) );
+ 
+-    /* Change the journal mode. */
+-    assert( pPager->eState!=PAGER_ERROR );
+-    pPager->journalMode = (u8)eMode;
++    /* Open page 1 of the file for writing. */
++    rc = sqlite3PagerGet(pPager, 1, &pPgHdr);
++    assert( pPgHdr==0 || rc==SQLITE_OK );
+ 
+-    /* When transistioning from TRUNCATE or PERSIST to any other journal
+-    ** mode except WAL, unless the pager is in locking_mode=exclusive mode,
+-    ** delete the journal file.
++    /* If page one was fetched successfully, and this function is not
++    ** operating in direct-mode, make page 1 writable.  When not in 
++    ** direct mode, page 1 is always held in cache and hence the PagerGet()
++    ** above is always successful - hence the ALWAYS on rc==SQLITE_OK.
+     */
+-    assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 );
+-    assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 );
+-    assert( (PAGER_JOURNALMODE_DELETE & 5)==0 );
+-    assert( (PAGER_JOURNALMODE_MEMORY & 5)==4 );
+-    assert( (PAGER_JOURNALMODE_OFF & 5)==0 );
+-    assert( (PAGER_JOURNALMODE_WAL & 5)==5 );
++    if( !DIRECT_MODE && ALWAYS(rc==SQLITE_OK) ){
++      rc = sqlite3PagerWrite(pPgHdr);
++    }
+ 
+-    assert( isOpen(pPager->fd) || pPager->exclusiveMode );
+-    if( !pPager->exclusiveMode && (eOld & 5)==1 && (eMode & 1)==0 ){
++    if( rc==SQLITE_OK ){
++      /* Actually do the update of the change counter */
++      pager_write_changecounter(pPgHdr);
+ 
+-      /* In this case we would like to delete the journal file. If it is
+-      ** not possible, then that is not a problem. Deleting the journal file
+-      ** here is an optimization only.
+-      **
+-      ** Before deleting the journal file, obtain a RESERVED lock on the
+-      ** database file. This ensures that the journal file is not deleted
+-      ** while it is in use by some other client.
+-      */
+-      sqlite3OsClose(pPager->jfd);
+-      if( pPager->eLock>=RESERVED_LOCK ){
+-        sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
+-      }else{
+-        int rc = SQLITE_OK;
+-        int state = pPager->eState;
+-        assert( state==PAGER_OPEN || state==PAGER_READER );
+-        if( state==PAGER_OPEN ){
+-          rc = sqlite3PagerSharedLock(pPager);
+-        }
+-        if( pPager->eState==PAGER_READER ){
+-          assert( rc==SQLITE_OK );
+-          rc = pagerLockDb(pPager, RESERVED_LOCK);
+-        }
++      /* If running in direct mode, write the contents of page 1 to the file. */
++      if( DIRECT_MODE ){
++        const void *zBuf;
++        assert( pPager->dbFileSize>0 );
++        CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM, zBuf);
+         if( rc==SQLITE_OK ){
+-          sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
++          rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0);
++          pPager->aStat[PAGER_STAT_WRITE]++;
+         }
+-        if( rc==SQLITE_OK && state==PAGER_READER ){
+-          pagerUnlockDb(pPager, SHARED_LOCK);
+-        }else if( state==PAGER_OPEN ){
+-          pager_unlock(pPager);
++        if( rc==SQLITE_OK ){
++          /* Update the pager's copy of the change-counter. Otherwise, the
++          ** next time a read transaction is opened the cache will be
++          ** flushed (as the change-counter values will not match).  */
++          const void *pCopy = (const void *)&((const char *)zBuf)[24];
++          memcpy(&pPager->dbFileVers, pCopy, sizeof(pPager->dbFileVers));
++          pPager->changeCountDone = 1;
+         }
+-        assert( state==pPager->eState );
++      }else{
++        pPager->changeCountDone = 1;
+       }
+-    }else if( eMode==PAGER_JOURNALMODE_OFF ){
+-      sqlite3OsClose(pPager->jfd);
+     }
+-  }
+ 
+-  /* Return the new journal mode */
+-  return (int)pPager->journalMode;
++    /* Release the page reference. */
++    sqlite3PagerUnref(pPgHdr);
++  }
++  return rc;
+ }
+ 
+ /*
+-** Return the current journal mode.
++** Sync the database file to disk. This is a no-op for in-memory databases
++** or pages with the Pager.noSync flag set.
++**
++** If successful, or if called on a pager for which it is a no-op, this
++** function returns SQLITE_OK. Otherwise, an IO error code is returned.
+ */
+-SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager *pPager){
+-  return (int)pPager->journalMode;
+-}
++SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager, const char *zMaster){
++  int rc = SQLITE_OK;
+ 
+-/*
+-** Return TRUE if the pager is in a state where it is OK to change the
+-** journalmode.  Journalmode changes can only happen when the database
+-** is unmodified.
+-*/
+-SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager *pPager){
+-  assert( assert_pager_state(pPager) );
+-  if( pPager->eState>=PAGER_WRITER_CACHEMOD ) return 0;
+-  if( NEVER(isOpen(pPager->jfd) && pPager->journalOff>0) ) return 0;
+-  return 1;
++  if( isOpen(pPager->fd) ){
++    void *pArg = (void*)zMaster;
++    rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg);
++    if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK;
++  }
++  if( rc==SQLITE_OK && !pPager->noSync ){
++    assert( !MEMDB );
++    rc = sqlite3OsSync(pPager->fd, pPager->syncFlags);
++  }
++  return rc;
+ }
+ 
+ /*
+-** Get/set the size-limit used for persistent journal files.
++** This function may only be called while a write-transaction is active in
++** rollback. If the connection is in WAL mode, this call is a no-op. 
++** Otherwise, if the connection does not already have an EXCLUSIVE lock on 
++** the database file, an attempt is made to obtain one.
+ **
+-** Setting the size limit to -1 means no limit is enforced.
+-** An attempt to set a limit smaller than -1 is a no-op.
++** If the EXCLUSIVE lock is already held or the attempt to obtain it is
++** successful, or the connection is in WAL mode, SQLITE_OK is returned.
++** Otherwise, either SQLITE_BUSY or an SQLITE_IOERR_XXX error code is 
++** returned.
+ */
+-SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){
+-  if( iLimit>=-1 ){
+-    pPager->journalSizeLimit = iLimit;
+-    sqlite3WalLimit(pPager->pWal, iLimit);
++SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager *pPager){
++  int rc = SQLITE_OK;
++  assert( pPager->eState==PAGER_WRITER_CACHEMOD 
++       || pPager->eState==PAGER_WRITER_DBMOD 
++       || pPager->eState==PAGER_WRITER_LOCKED 
++  );
++  assert( assert_pager_state(pPager) );
++  if( 0==pagerUseWal(pPager) ){
++    rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);
+   }
+-  return pPager->journalSizeLimit;
++  return rc;
+ }
+ 
+ /*
+-** Return a pointer to the pPager->pBackup variable. The backup module
+-** in backup.c maintains the content of this variable. This module
+-** uses it opaquely as an argument to sqlite3BackupRestart() and
+-** sqlite3BackupUpdate() only.
++** Sync the database file for the pager pPager. zMaster points to the name
++** of a master journal file that should be written into the individual
++** journal file. zMaster may be NULL, which is interpreted as no master
++** journal (a single database transaction).
++**
++** This routine ensures that:
++**
++**   * The database file change-counter is updated,
++**   * the journal is synced (unless the atomic-write optimization is used),
++**   * all dirty pages are written to the database file, 
++**   * the database file is truncated (if required), and
++**   * the database file synced. 
++**
++** The only thing that remains to commit the transaction is to finalize 
++** (delete, truncate or zero the first part of) the journal file (or 
++** delete the master journal file if specified).
++**
++** Note that if zMaster==NULL, this does not overwrite a previous value
++** passed to an sqlite3PagerCommitPhaseOne() call.
++**
++** If the final parameter - noSync - is true, then the database file itself
++** is not synced. The caller must call sqlite3PagerSync() directly to
++** sync the database file before calling CommitPhaseTwo() to delete the
++** journal file in this case.
+ */
+-SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){
+-  return &pPager->pBackup;
+-}
++SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(
++  Pager *pPager,                  /* Pager object */
++  const char *zMaster,            /* If not NULL, the master journal name */
++  int noSync                      /* True to omit the xSync on the db file */
++){
++  int rc = SQLITE_OK;             /* Return code */
+ 
+-#ifndef SQLITE_OMIT_VACUUM
+-/*
+-** Unless this is an in-memory or temporary database, clear the pager cache.
+-*/
+-SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *pPager){
+-  if( !MEMDB && pPager->tempFile==0 ) pager_reset(pPager);
+-}
+-#endif
++  assert( pPager->eState==PAGER_WRITER_LOCKED
++       || pPager->eState==PAGER_WRITER_CACHEMOD
++       || pPager->eState==PAGER_WRITER_DBMOD
++       || pPager->eState==PAGER_ERROR
++  );
++  assert( assert_pager_state(pPager) );
+ 
+-#ifndef SQLITE_OMIT_WAL
+-/*
+-** This function is called when the user invokes "PRAGMA wal_checkpoint",
+-** "PRAGMA wal_blocking_checkpoint" or calls the sqlite3_wal_checkpoint()
+-** or wal_blocking_checkpoint() API functions.
+-**
+-** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
+-*/
+-SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){
+-  int rc = SQLITE_OK;
+-  if( pPager->pWal ){
+-    rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
+-        (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
+-        pPager->pBusyHandlerArg,
+-        pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
+-        pnLog, pnCkpt
+-    );
+-  }
+-  return rc;
+-}
++  /* If a prior error occurred, report that error again. */
++  if( NEVER(pPager->errCode) ) return pPager->errCode;
+ 
+-SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){
+-  return sqlite3WalCallback(pPager->pWal);
+-}
++  PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", 
++      pPager->zFilename, zMaster, pPager->dbSize));
+ 
+-/*
+-** Return true if the underlying VFS for the given pager supports the
+-** primitives necessary for write-ahead logging.
+-*/
+-SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager){
+-  const sqlite3_io_methods *pMethods = pPager->fd->pMethods;
+-  return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap);
+-}
++  /* If no database changes have been made, return early. */
++  if( pPager->eState<PAGER_WRITER_CACHEMOD ) return SQLITE_OK;
+ 
+-/*
+-** Attempt to take an exclusive lock on the database file. If a PENDING lock
+-** is obtained instead, immediately release it.
+-*/
+-static int pagerExclusiveLock(Pager *pPager){
+-  int rc;                         /* Return code */
++  if( MEMDB ){
++    /* If this is an in-memory db, or no pages have been written to, or this
++    ** function has already been called, it is mostly a no-op.  However, any
++    ** backup in progress needs to be restarted.
++    */
++    sqlite3BackupRestart(pPager->pBackup);
++  }else{
++    if( pagerUseWal(pPager) ){
++      PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache);
++      PgHdr *pPageOne = 0;
++      if( pList==0 ){
++        /* Must have at least one page for the WAL commit flag.
++        ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */
++        rc = sqlite3PagerGet(pPager, 1, &pPageOne);
++        pList = pPageOne;
++        pList->pDirty = 0;
++      }
++      assert( rc==SQLITE_OK );
++      if( ALWAYS(pList) ){
++        rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1);
++      }
++      sqlite3PagerUnref(pPageOne);
++      if( rc==SQLITE_OK ){
++        sqlite3PcacheCleanAll(pPager->pPCache);
++      }
++    }else{
++      /* The following block updates the change-counter. Exactly how it
++      ** does this depends on whether or not the atomic-update optimization
++      ** was enabled at compile time, and if this transaction meets the 
++      ** runtime criteria to use the operation: 
++      **
++      **    * The file-system supports the atomic-write property for
++      **      blocks of size page-size, and 
++      **    * This commit is not part of a multi-file transaction, and
++      **    * Exactly one page has been modified and store in the journal file.
++      **
++      ** If the optimization was not enabled at compile time, then the
++      ** pager_incr_changecounter() function is called to update the change
++      ** counter in 'indirect-mode'. If the optimization is compiled in but
++      ** is not applicable to this transaction, call sqlite3JournalCreate()
++      ** to make sure the journal file has actually been created, then call
++      ** pager_incr_changecounter() to update the change-counter in indirect
++      ** mode. 
++      **
++      ** Otherwise, if the optimization is both enabled and applicable,
++      ** then call pager_incr_changecounter() to update the change-counter
++      ** in 'direct' mode. In this case the journal file will never be
++      ** created for this transaction.
++      */
++  #ifdef SQLITE_ENABLE_ATOMIC_WRITE
++      PgHdr *pPg;
++      assert( isOpen(pPager->jfd) 
++           || pPager->journalMode==PAGER_JOURNALMODE_OFF 
++           || pPager->journalMode==PAGER_JOURNALMODE_WAL 
++      );
++      if( !zMaster && isOpen(pPager->jfd) 
++       && pPager->journalOff==jrnlBufferSize(pPager) 
++       && pPager->dbSize>=pPager->dbOrigSize
++       && (0==(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty)
++      ){
++        /* Update the db file change counter via the direct-write method. The 
++        ** following call will modify the in-memory representation of page 1 
++        ** to include the updated change counter and then write page 1 
++        ** directly to the database file. Because of the atomic-write 
++        ** property of the host file-system, this is safe.
++        */
++        rc = pager_incr_changecounter(pPager, 1);
++      }else{
++        rc = sqlite3JournalCreate(pPager->jfd);
++        if( rc==SQLITE_OK ){
++          rc = pager_incr_changecounter(pPager, 0);
++        }
++      }
++  #else
++      rc = pager_incr_changecounter(pPager, 0);
++  #endif
++      if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
++  
++      /* Write the master journal name into the journal file. If a master 
++      ** journal file name has already been written to the journal file, 
++      ** or if zMaster is NULL (no master journal), then this call is a no-op.
++      */
++      rc = writeMasterJournal(pPager, zMaster);
++      if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
++  
++      /* Sync the journal file and write all dirty pages to the database.
++      ** If the atomic-update optimization is being used, this sync will not 
++      ** create the journal file or perform any real IO.
++      **
++      ** Because the change-counter page was just modified, unless the
++      ** atomic-update optimization is used it is almost certain that the
++      ** journal requires a sync here. However, in locking_mode=exclusive
++      ** on a system under memory pressure it is just possible that this is 
++      ** not the case. In this case it is likely enough that the redundant
++      ** xSync() call will be changed to a no-op by the OS anyhow. 
++      */
++      rc = syncJournal(pPager, 0);
++      if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
++  
++      rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache));
++      if( rc!=SQLITE_OK ){
++        assert( rc!=SQLITE_IOERR_BLOCKED );
++        goto commit_phase_one_exit;
++      }
++      sqlite3PcacheCleanAll(pPager->pPCache);
+ 
+-  assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK );
+-  rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
+-  if( rc!=SQLITE_OK ){
+-    /* If the attempt to grab the exclusive lock failed, release the 
+-    ** pending lock that may have been obtained instead.  */
+-    pagerUnlockDb(pPager, SHARED_LOCK);
++      /* If the file on disk is smaller than the database image, use 
++      ** pager_truncate to grow the file here. This can happen if the database
++      ** image was extended as part of the current transaction and then the
++      ** last page in the db image moved to the free-list. In this case the
++      ** last page is never written out to disk, leaving the database file
++      ** undersized. Fix this now if it is the case.  */
++      if( pPager->dbSize>pPager->dbFileSize ){
++        Pgno nNew = pPager->dbSize - (pPager->dbSize==PAGER_MJ_PGNO(pPager));
++        assert( pPager->eState==PAGER_WRITER_DBMOD );
++        rc = pager_truncate(pPager, nNew);
++        if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
++      }
++  
++      /* Finally, sync the database file. */
++      if( !noSync ){
++        rc = sqlite3PagerSync(pPager, zMaster);
++      }
++      IOTRACE(("DBSYNC %p\n", pPager))
++    }
+   }
+ 
++commit_phase_one_exit:
++  if( rc==SQLITE_OK && !pagerUseWal(pPager) ){
++    pPager->eState = PAGER_WRITER_FINISHED;
++  }
+   return rc;
+ }
+ 
++
+ /*
+-** Call sqlite3WalOpen() to open the WAL handle. If the pager is in 
+-** exclusive-locking mode when this function is called, take an EXCLUSIVE
+-** lock on the database file and use heap-memory to store the wal-index
+-** in. Otherwise, use the normal shared-memory.
++** When this function is called, the database file has been completely
++** updated to reflect the changes made by the current transaction and
++** synced to disk. The journal file still exists in the file-system 
++** though, and if a failure occurs at this point it will eventually
++** be used as a hot-journal and the current transaction rolled back.
++**
++** This function finalizes the journal file, either by deleting, 
++** truncating or partially zeroing it, so that it cannot be used 
++** for hot-journal rollback. Once this is done the transaction is
++** irrevocably committed.
++**
++** If an error occurs, an IO error code is returned and the pager
++** moves into the error state. Otherwise, SQLITE_OK is returned.
+ */
+-static int pagerOpenWal(Pager *pPager){
+-  int rc = SQLITE_OK;
++SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager *pPager){
++  int rc = SQLITE_OK;                  /* Return code */
+ 
+-  assert( pPager->pWal==0 && pPager->tempFile==0 );
+-  assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK );
++  /* This routine should not be called if a prior error has occurred.
++  ** But if (due to a coding error elsewhere in the system) it does get
++  ** called, just return the same error code without doing anything. */
++  if( NEVER(pPager->errCode) ) return pPager->errCode;
+ 
+-  /* If the pager is already in exclusive-mode, the WAL module will use 
+-  ** heap-memory for the wal-index instead of the VFS shared-memory 
+-  ** implementation. Take the exclusive lock now, before opening the WAL
+-  ** file, to make sure this is safe.
+-  */
+-  if( pPager->exclusiveMode ){
+-    rc = pagerExclusiveLock(pPager);
+-  }
++  assert( pPager->eState==PAGER_WRITER_LOCKED
++       || pPager->eState==PAGER_WRITER_FINISHED
++       || (pagerUseWal(pPager) && pPager->eState==PAGER_WRITER_CACHEMOD)
++  );
++  assert( assert_pager_state(pPager) );
+ 
+-  /* Open the connection to the log file. If this operation fails, 
+-  ** (e.g. due to malloc() failure), return an error code.
++  /* An optimization. If the database was not actually modified during
++  ** this transaction, the pager is running in exclusive-mode and is
++  ** using persistent journals, then this function is a no-op.
++  **
++  ** The start of the journal file currently contains a single journal 
++  ** header with the nRec field set to 0. If such a journal is used as
++  ** a hot-journal during hot-journal rollback, 0 changes will be made
++  ** to the database file. So there is no need to zero the journal 
++  ** header. Since the pager is in exclusive mode, there is no need
++  ** to drop any locks either.
+   */
+-  if( rc==SQLITE_OK ){
+-    rc = sqlite3WalOpen(pPager->pVfs,
+-        pPager->fd, pPager->zWal, pPager->exclusiveMode,
+-        pPager->journalSizeLimit, &pPager->pWal
+-    );
++  if( pPager->eState==PAGER_WRITER_LOCKED 
++   && pPager->exclusiveMode 
++   && pPager->journalMode==PAGER_JOURNALMODE_PERSIST
++  ){
++    assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) || !pPager->journalOff );
++    pPager->eState = PAGER_READER;
++    return SQLITE_OK;
+   }
+-  pagerFixMaplimit(pPager);
+ 
+-  return rc;
++  PAGERTRACE(("COMMIT %d\n", PAGERID(pPager)));
++  pPager->iDataVersion++;
++  rc = pager_end_transaction(pPager, pPager->setMaster, 1);
++  return pager_error(pPager, rc);
+ }
+ 
+-
+ /*
+-** The caller must be holding a SHARED lock on the database file to call
+-** this function.
++** If a write transaction is open, then all changes made within the 
++** transaction are reverted and the current write-transaction is closed.
++** The pager falls back to PAGER_READER state if successful, or PAGER_ERROR
++** state if an error occurs.
+ **
+-** If the pager passed as the first argument is open on a real database
+-** file (not a temp file or an in-memory database), and the WAL file
+-** is not already open, make an attempt to open it now. If successful,
+-** return SQLITE_OK. If an error occurs or the VFS used by the pager does 
+-** not support the xShmXXX() methods, return an error code. *pbOpen is
+-** not modified in either case.
++** If the pager is already in PAGER_ERROR state when this function is called,
++** it returns Pager.errCode immediately. No work is performed in this case.
+ **
+-** If the pager is open on a temp-file (or in-memory database), or if
+-** the WAL file is already open, set *pbOpen to 1 and return SQLITE_OK
+-** without doing anything.
++** Otherwise, in rollback mode, this function performs two functions:
++**
++**   1) It rolls back the journal file, restoring all database file and 
++**      in-memory cache pages to the state they were in when the transaction
++**      was opened, and
++**
++**   2) It finalizes the journal file, so that it is not used for hot
++**      rollback at any point in the future.
++**
++** Finalization of the journal file (task 2) is only performed if the 
++** rollback is successful.
++**
++** In WAL mode, all cache-entries containing data modified within the
++** current transaction are either expelled from the cache or reverted to
++** their pre-transaction state by re-reading data from the database or
++** WAL files. The WAL transaction is then closed.
+ */
+-SQLITE_PRIVATE int sqlite3PagerOpenWal(
+-  Pager *pPager,                  /* Pager object */
+-  int *pbOpen                     /* OUT: Set to true if call is a no-op */
+-){
+-  int rc = SQLITE_OK;             /* Return code */
++SQLITE_PRIVATE int sqlite3PagerRollback(Pager *pPager){
++  int rc = SQLITE_OK;                  /* Return code */
++  PAGERTRACE(("ROLLBACK %d\n", PAGERID(pPager)));
+ 
++  /* PagerRollback() is a no-op if called in READER or OPEN state. If
++  ** the pager is already in the ERROR state, the rollback is not 
++  ** attempted here. Instead, the error code is returned to the caller.
++  */
+   assert( assert_pager_state(pPager) );
+-  assert( pPager->eState==PAGER_OPEN   || pbOpen );
+-  assert( pPager->eState==PAGER_READER || !pbOpen );
+-  assert( pbOpen==0 || *pbOpen==0 );
+-  assert( pbOpen!=0 || (!pPager->tempFile && !pPager->pWal) );
+-
+-  if( !pPager->tempFile && !pPager->pWal ){
+-    if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN;
+-
+-    /* Close any rollback journal previously open */
+-    sqlite3OsClose(pPager->jfd);
++  if( pPager->eState==PAGER_ERROR ) return pPager->errCode;
++  if( pPager->eState<=PAGER_READER ) return SQLITE_OK;
+ 
+-    rc = pagerOpenWal(pPager);
+-    if( rc==SQLITE_OK ){
+-      pPager->journalMode = PAGER_JOURNALMODE_WAL;
+-      pPager->eState = PAGER_OPEN;
++  if( pagerUseWal(pPager) ){
++    int rc2;
++    rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1);
++    rc2 = pager_end_transaction(pPager, pPager->setMaster, 0);
++    if( rc==SQLITE_OK ) rc = rc2;
++  }else if( !isOpen(pPager->jfd) || pPager->eState==PAGER_WRITER_LOCKED ){
++    int eState = pPager->eState;
++    rc = pager_end_transaction(pPager, 0, 0);
++    if( !MEMDB && eState>PAGER_WRITER_LOCKED ){
++      /* This can happen using journal_mode=off. Move the pager to the error 
++      ** state to indicate that the contents of the cache may not be trusted.
++      ** Any active readers will get SQLITE_ABORT.
++      */
++      pPager->errCode = SQLITE_ABORT;
++      pPager->eState = PAGER_ERROR;
++      return rc;
+     }
+   }else{
+-    *pbOpen = 1;
++    rc = pager_playback(pPager, 0);
+   }
+ 
+-  return rc;
++  assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK );
++  assert( rc==SQLITE_OK || rc==SQLITE_FULL || rc==SQLITE_CORRUPT
++          || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR 
++          || rc==SQLITE_CANTOPEN
++  );
++
++  /* If an error occurs during a ROLLBACK, we can no longer trust the pager
++  ** cache. So call pager_error() on the way out to make any error persistent.
++  */
++  return pager_error(pPager, rc);
+ }
+ 
+ /*
+-** This function is called to close the connection to the log file prior
+-** to switching from WAL to rollback mode.
+-**
+-** Before closing the log file, this function attempts to take an 
+-** EXCLUSIVE lock on the database file. If this cannot be obtained, an
+-** error (SQLITE_BUSY) is returned and the log connection is not closed.
+-** If successful, the EXCLUSIVE lock is not released before returning.
++** Return TRUE if the database file is opened read-only.  Return FALSE
++** if the database is (in theory) writable.
+ */
+-SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager){
+-  int rc = SQLITE_OK;
++SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager *pPager){
++  return pPager->readOnly;
++}
+ 
+-  assert( pPager->journalMode==PAGER_JOURNALMODE_WAL );
++/*
++** Return the number of references to the pager.
++*/
++SQLITE_PRIVATE int sqlite3PagerRefcount(Pager *pPager){
++  return sqlite3PcacheRefCount(pPager->pPCache);
++}
+ 
+-  /* If the log file is not already open, but does exist in the file-system,
+-  ** it may need to be checkpointed before the connection can switch to
+-  ** rollback mode. Open it now so this can happen.
+-  */
+-  if( !pPager->pWal ){
+-    int logexists = 0;
+-    rc = pagerLockDb(pPager, SHARED_LOCK);
+-    if( rc==SQLITE_OK ){
+-      rc = sqlite3OsAccess(
+-          pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &logexists
+-      );
+-    }
+-    if( rc==SQLITE_OK && logexists ){
+-      rc = pagerOpenWal(pPager);
+-    }
+-  }
+-    
+-  /* Checkpoint and close the log. Because an EXCLUSIVE lock is held on
+-  ** the database file, the log and log-summary files will be deleted.
+-  */
+-  if( rc==SQLITE_OK && pPager->pWal ){
+-    rc = pagerExclusiveLock(pPager);
+-    if( rc==SQLITE_OK ){
+-      rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags,
+-                           pPager->pageSize, (u8*)pPager->pTmpSpace);
+-      pPager->pWal = 0;
+-      pagerFixMaplimit(pPager);
+-    }
+-  }
+-  return rc;
++/*
++** Return the approximate number of bytes of memory currently
++** used by the pager and its associated cache.
++*/
++SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager *pPager){
++  int perPageSize = pPager->pageSize + pPager->nExtra + sizeof(PgHdr)
++                                     + 5*sizeof(void*);
++  return perPageSize*sqlite3PcachePagecount(pPager->pPCache)
++           + sqlite3MallocSize(pPager)
++           + pPager->pageSize;
+ }
+ 
+-#endif /* !SQLITE_OMIT_WAL */
++/*
++** Return the number of references to the specified page.
++*/
++SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage *pPage){
++  return sqlite3PcachePageRefcount(pPage);
++}
+ 
+-#ifdef SQLITE_ENABLE_ZIPVFS
++#ifdef SQLITE_TEST
+ /*
+-** A read-lock must be held on the pager when this function is called. If
+-** the pager is in WAL mode and the WAL file currently contains one or more
+-** frames, return the size in bytes of the page images stored within the
+-** WAL frames. Otherwise, if this is not a WAL database or the WAL file
+-** is empty, return 0.
++** This routine is used for testing and analysis only.
+ */
+-SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){
+-  assert( pPager->eState>=PAGER_READER );
+-  return sqlite3WalFramesize(pPager->pWal);
++SQLITE_PRIVATE int *sqlite3PagerStats(Pager *pPager){
++  static int a[11];
++  a[0] = sqlite3PcacheRefCount(pPager->pPCache);
++  a[1] = sqlite3PcachePagecount(pPager->pPCache);
++  a[2] = sqlite3PcacheGetCachesize(pPager->pPCache);
++  a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize;
++  a[4] = pPager->eState;
++  a[5] = pPager->errCode;
++  a[6] = pPager->aStat[PAGER_STAT_HIT];
++  a[7] = pPager->aStat[PAGER_STAT_MISS];
++  a[8] = 0;  /* Used to be pPager->nOvfl */
++  a[9] = pPager->nRead;
++  a[10] = pPager->aStat[PAGER_STAT_WRITE];
++  return a;
+ }
+ #endif
+ 
+-
+-#endif /* SQLITE_OMIT_DISKIO */
+-
+-/************** End of pager.c ***********************************************/
+-/************** Begin file wal.c *********************************************/
+ /*
+-** 2010 February 1
+-**
+-** The author disclaims copyright to this source code.  In place of
+-** a legal notice, here is a blessing:
+-**
+-**    May you do good and not evil.
+-**    May you find forgiveness for yourself and forgive others.
+-**    May you share freely, never taking more than you give.
+-**
+-*************************************************************************
+-**
+-** This file contains the implementation of a write-ahead log (WAL) used in 
+-** "journal_mode=WAL" mode.
+-**
+-** WRITE-AHEAD LOG (WAL) FILE FORMAT
+-**
+-** A WAL file consists of a header followed by zero or more "frames".
+-** Each frame records the revised content of a single page from the
+-** database file.  All changes to the database are recorded by writing
+-** frames into the WAL.  Transactions commit when a frame is written that
+-** contains a commit marker.  A single WAL can and usually does record 
+-** multiple transactions.  Periodically, the content of the WAL is
+-** transferred back into the database file in an operation called a
+-** "checkpoint".
+-**
+-** A single WAL file can be used multiple times.  In other words, the
+-** WAL can fill up with frames and then be checkpointed and then new
+-** frames can overwrite the old ones.  A WAL always grows from beginning
+-** toward the end.  Checksums and counters attached to each frame are
+-** used to determine which frames within the WAL are valid and which
+-** are leftovers from prior checkpoints.
+-**
+-** The WAL header is 32 bytes in size and consists of the following eight
+-** big-endian 32-bit unsigned integer values:
+-**
+-**     0: Magic number.  0x377f0682 or 0x377f0683
+-**     4: File format version.  Currently 3007000
+-**     8: Database page size.  Example: 1024
+-**    12: Checkpoint sequence number
+-**    16: Salt-1, random integer incremented with each checkpoint
+-**    20: Salt-2, a different random integer changing with each ckpt
+-**    24: Checksum-1 (first part of checksum for first 24 bytes of header).
+-**    28: Checksum-2 (second part of checksum for first 24 bytes of header).
+-**
+-** Immediately following the wal-header are zero or more frames. Each
+-** frame consists of a 24-byte frame-header followed by a <page-size> bytes
+-** of page data. The frame-header is six big-endian 32-bit unsigned 
+-** integer values, as follows:
+-**
+-**     0: Page number.
+-**     4: For commit records, the size of the database image in pages 
+-**        after the commit. For all other records, zero.
+-**     8: Salt-1 (copied from the header)
+-**    12: Salt-2 (copied from the header)
+-**    16: Checksum-1.
+-**    20: Checksum-2.
+-**
+-** A frame is considered valid if and only if the following conditions are
+-** true:
+-**
+-**    (1) The salt-1 and salt-2 values in the frame-header match
+-**        salt values in the wal-header
+-**
+-**    (2) The checksum values in the final 8 bytes of the frame-header
+-**        exactly match the checksum computed consecutively on the
+-**        WAL header and the first 8 bytes and the content of all frames
+-**        up to and including the current frame.
+-**
+-** The checksum is computed using 32-bit big-endian integers if the
+-** magic number in the first 4 bytes of the WAL is 0x377f0683 and it
+-** is computed using little-endian if the magic number is 0x377f0682.
+-** The checksum values are always stored in the frame header in a
+-** big-endian format regardless of which byte order is used to compute
+-** the checksum.  The checksum is computed by interpreting the input as
+-** an even number of unsigned 32-bit integers: x[0] through x[N].  The
+-** algorithm used for the checksum is as follows:
+-** 
+-**   for i from 0 to n-1 step 2:
+-**     s0 += x[i] + s1;
+-**     s1 += x[i+1] + s0;
+-**   endfor
+-**
+-** Note that s0 and s1 are both weighted checksums using fibonacci weights
+-** in reverse order (the largest fibonacci weight occurs on the first element
+-** of the sequence being summed.)  The s1 value spans all 32-bit 
+-** terms of the sequence whereas s0 omits the final term.
+-**
+-** On a checkpoint, the WAL is first VFS.xSync-ed, then valid content of the
+-** WAL is transferred into the database, then the database is VFS.xSync-ed.
+-** The VFS.xSync operations serve as write barriers - all writes launched
+-** before the xSync must complete before any write that launches after the
+-** xSync begins.
+-**
+-** After each checkpoint, the salt-1 value is incremented and the salt-2
+-** value is randomized.  This prevents old and new frames in the WAL from
+-** being considered valid at the same time and being checkpointing together
+-** following a crash.
+-**
+-** READER ALGORITHM
+-**
+-** To read a page from the database (call it page number P), a reader
+-** first checks the WAL to see if it contains page P.  If so, then the
+-** last valid instance of page P that is a followed by a commit frame
+-** or is a commit frame itself becomes the value read.  If the WAL
+-** contains no copies of page P that are valid and which are a commit
+-** frame or are followed by a commit frame, then page P is read from
+-** the database file.
+-**
+-** To start a read transaction, the reader records the index of the last
+-** valid frame in the WAL.  The reader uses this recorded "mxFrame" value
+-** for all subsequent read operations.  New transactions can be appended
+-** to the WAL, but as long as the reader uses its original mxFrame value
+-** and ignores the newly appended content, it will see a consistent snapshot
+-** of the database from a single point in time.  This technique allows
+-** multiple concurrent readers to view different versions of the database
+-** content simultaneously.
+-**
+-** The reader algorithm in the previous paragraphs works correctly, but 
+-** because frames for page P can appear anywhere within the WAL, the
+-** reader has to scan the entire WAL looking for page P frames.  If the
+-** WAL is large (multiple megabytes is typical) that scan can be slow,
+-** and read performance suffers.  To overcome this problem, a separate
+-** data structure called the wal-index is maintained to expedite the
+-** search for frames of a particular page.
+-** 
+-** WAL-INDEX FORMAT
+-**
+-** Conceptually, the wal-index is shared memory, though VFS implementations
+-** might choose to implement the wal-index using a mmapped file.  Because
+-** the wal-index is shared memory, SQLite does not support journal_mode=WAL 
+-** on a network filesystem.  All users of the database must be able to
+-** share memory.
+-**
+-** The wal-index is transient.  After a crash, the wal-index can (and should
+-** be) reconstructed from the original WAL file.  In fact, the VFS is required
+-** to either truncate or zero the header of the wal-index when the last
+-** connection to it closes.  Because the wal-index is transient, it can
+-** use an architecture-specific format; it does not have to be cross-platform.
+-** Hence, unlike the database and WAL file formats which store all values
+-** as big endian, the wal-index can store multi-byte values in the native
+-** byte order of the host computer.
+-**
+-** The purpose of the wal-index is to answer this question quickly:  Given
+-** a page number P and a maximum frame index M, return the index of the 
+-** last frame in the wal before frame M for page P in the WAL, or return
+-** NULL if there are no frames for page P in the WAL prior to M.
+-**
+-** The wal-index consists of a header region, followed by an one or
+-** more index blocks.  
+-**
+-** The wal-index header contains the total number of frames within the WAL
+-** in the mxFrame field.
+-**
+-** Each index block except for the first contains information on 
+-** HASHTABLE_NPAGE frames. The first index block contains information on
+-** HASHTABLE_NPAGE_ONE frames. The values of HASHTABLE_NPAGE_ONE and 
+-** HASHTABLE_NPAGE are selected so that together the wal-index header and
+-** first index block are the same size as all other index blocks in the
+-** wal-index.
+-**
+-** Each index block contains two sections, a page-mapping that contains the
+-** database page number associated with each wal frame, and a hash-table 
+-** that allows readers to query an index block for a specific page number.
+-** The page-mapping is an array of HASHTABLE_NPAGE (or HASHTABLE_NPAGE_ONE
+-** for the first index block) 32-bit page numbers. The first entry in the 
+-** first index-block contains the database page number corresponding to the
+-** first frame in the WAL file. The first entry in the second index block
+-** in the WAL file corresponds to the (HASHTABLE_NPAGE_ONE+1)th frame in
+-** the log, and so on.
+-**
+-** The last index block in a wal-index usually contains less than the full
+-** complement of HASHTABLE_NPAGE (or HASHTABLE_NPAGE_ONE) page-numbers,
+-** depending on the contents of the WAL file. This does not change the
+-** allocated size of the page-mapping array - the page-mapping array merely
+-** contains unused entries.
+-**
+-** Even without using the hash table, the last frame for page P
+-** can be found by scanning the page-mapping sections of each index block
+-** starting with the last index block and moving toward the first, and
+-** within each index block, starting at the end and moving toward the
+-** beginning.  The first entry that equals P corresponds to the frame
+-** holding the content for that page.
+-**
+-** The hash table consists of HASHTABLE_NSLOT 16-bit unsigned integers.
+-** HASHTABLE_NSLOT = 2*HASHTABLE_NPAGE, and there is one entry in the
+-** hash table for each page number in the mapping section, so the hash 
+-** table is never more than half full.  The expected number of collisions 
+-** prior to finding a match is 1.  Each entry of the hash table is an
+-** 1-based index of an entry in the mapping section of the same
+-** index block.   Let K be the 1-based index of the largest entry in
+-** the mapping section.  (For index blocks other than the last, K will
+-** always be exactly HASHTABLE_NPAGE (4096) and for the last index block
+-** K will be (mxFrame%HASHTABLE_NPAGE).)  Unused slots of the hash table
+-** contain a value of 0.
++** Parameter eStat must be either SQLITE_DBSTATUS_CACHE_HIT or
++** SQLITE_DBSTATUS_CACHE_MISS. Before returning, *pnVal is incremented by the
++** current cache hit or miss count, according to the value of eStat. If the 
++** reset parameter is non-zero, the cache hit or miss count is zeroed before 
++** returning.
++*/
++SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){
++
++  assert( eStat==SQLITE_DBSTATUS_CACHE_HIT
++       || eStat==SQLITE_DBSTATUS_CACHE_MISS
++       || eStat==SQLITE_DBSTATUS_CACHE_WRITE
++  );
++
++  assert( SQLITE_DBSTATUS_CACHE_HIT+1==SQLITE_DBSTATUS_CACHE_MISS );
++  assert( SQLITE_DBSTATUS_CACHE_HIT+2==SQLITE_DBSTATUS_CACHE_WRITE );
++  assert( PAGER_STAT_HIT==0 && PAGER_STAT_MISS==1 && PAGER_STAT_WRITE==2 );
++
++  *pnVal += pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT];
++  if( reset ){
++    pPager->aStat[eStat - SQLITE_DBSTATUS_CACHE_HIT] = 0;
++  }
++}
++
++/*
++** Return true if this is an in-memory pager.
++*/
++SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
++  return MEMDB;
++}
++
++/*
++** Check that there are at least nSavepoint savepoints open. If there are
++** currently less than nSavepoints open, then open one or more savepoints
++** to make up the difference. If the number of savepoints is already
++** equal to nSavepoint, then this function is a no-op.
+ **
+-** To look for page P in the hash table, first compute a hash iKey on
+-** P as follows:
++** If a memory allocation fails, SQLITE_NOMEM is returned. If an error 
++** occurs while opening the sub-journal file, then an IO error code is
++** returned. Otherwise, SQLITE_OK.
++*/
++SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){
++  int rc = SQLITE_OK;                       /* Return code */
++  int nCurrent = pPager->nSavepoint;        /* Current number of savepoints */
++
++  assert( pPager->eState>=PAGER_WRITER_LOCKED );
++  assert( assert_pager_state(pPager) );
++
++  if( nSavepoint>nCurrent && pPager->useJournal ){
++    int ii;                                 /* Iterator variable */
++    PagerSavepoint *aNew;                   /* New Pager.aSavepoint array */
++
++    /* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM
++    ** if the allocation fails. Otherwise, zero the new portion in case a 
++    ** malloc failure occurs while populating it in the for(...) loop below.
++    */
++    aNew = (PagerSavepoint *)sqlite3Realloc(
++        pPager->aSavepoint, sizeof(PagerSavepoint)*nSavepoint
++    );
++    if( !aNew ){
++      return SQLITE_NOMEM;
++    }
++    memset(&aNew[nCurrent], 0, (nSavepoint-nCurrent) * sizeof(PagerSavepoint));
++    pPager->aSavepoint = aNew;
++
++    /* Populate the PagerSavepoint structures just allocated. */
++    for(ii=nCurrent; ii<nSavepoint; ii++){
++      aNew[ii].nOrig = pPager->dbSize;
++      if( isOpen(pPager->jfd) && pPager->journalOff>0 ){
++        aNew[ii].iOffset = pPager->journalOff;
++      }else{
++        aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager);
++      }
++      aNew[ii].iSubRec = pPager->nSubRec;
++      aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize);
++      if( !aNew[ii].pInSavepoint ){
++        return SQLITE_NOMEM;
++      }
++      if( pagerUseWal(pPager) ){
++        sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData);
++      }
++      pPager->nSavepoint = ii+1;
++    }
++    assert( pPager->nSavepoint==nSavepoint );
++    assertTruncateConstraint(pPager);
++  }
++
++  return rc;
++}
++
++/*
++** This function is called to rollback or release (commit) a savepoint.
++** The savepoint to release or rollback need not be the most recently 
++** created savepoint.
+ **
+-**      iKey = (P * 383) % HASHTABLE_NSLOT
++** Parameter op is always either SAVEPOINT_ROLLBACK or SAVEPOINT_RELEASE.
++** If it is SAVEPOINT_RELEASE, then release and destroy the savepoint with
++** index iSavepoint. If it is SAVEPOINT_ROLLBACK, then rollback all changes
++** that have occurred since the specified savepoint was created.
+ **
+-** Then start scanning entries of the hash table, starting with iKey
+-** (wrapping around to the beginning when the end of the hash table is
+-** reached) until an unused hash slot is found. Let the first unused slot
+-** be at index iUnused.  (iUnused might be less than iKey if there was
+-** wrap-around.) Because the hash table is never more than half full,
+-** the search is guaranteed to eventually hit an unused entry.  Let 
+-** iMax be the value between iKey and iUnused, closest to iUnused,
+-** where aHash[iMax]==P.  If there is no iMax entry (if there exists
+-** no hash slot such that aHash[i]==p) then page P is not in the
+-** current index block.  Otherwise the iMax-th mapping entry of the
+-** current index block corresponds to the last entry that references 
+-** page P.
++** The savepoint to rollback or release is identified by parameter 
++** iSavepoint. A value of 0 means to operate on the outermost savepoint
++** (the first created). A value of (Pager.nSavepoint-1) means operate
++** on the most recently created savepoint. If iSavepoint is greater than
++** (Pager.nSavepoint-1), then this function is a no-op.
+ **
+-** A hash search begins with the last index block and moves toward the
+-** first index block, looking for entries corresponding to page P.  On
+-** average, only two or three slots in each index block need to be
+-** examined in order to either find the last entry for page P, or to
+-** establish that no such entry exists in the block.  Each index block
+-** holds over 4000 entries.  So two or three index blocks are sufficient
+-** to cover a typical 10 megabyte WAL file, assuming 1K pages.  8 or 10
+-** comparisons (on average) suffice to either locate a frame in the
+-** WAL or to establish that the frame does not exist in the WAL.  This
+-** is much faster than scanning the entire 10MB WAL.
++** If a negative value is passed to this function, then the current
++** transaction is rolled back. This is different to calling 
++** sqlite3PagerRollback() because this function does not terminate
++** the transaction or unlock the database, it just restores the 
++** contents of the database to its original state. 
+ **
+-** Note that entries are added in order of increasing K.  Hence, one
+-** reader might be using some value K0 and a second reader that started
+-** at a later time (after additional transactions were added to the WAL
+-** and to the wal-index) might be using a different value K1, where K1>K0.
+-** Both readers can use the same hash table and mapping section to get
+-** the correct result.  There may be entries in the hash table with
+-** K>K0 but to the first reader, those entries will appear to be unused
 -** slots in the hash table and so the first reader will get an answer as
 -** if no values greater than K0 had ever been inserted into the hash table
 -** in the first place - which is what reader one wants.  Meanwhile, the
 -** second reader using K1 will see additional values that were inserted
 -** later, which is exactly what reader two wants.  
--**
++** In any case, all savepoints with an index greater than iSavepoint 
++** are destroyed. If this is a release operation (op==SAVEPOINT_RELEASE),
++** then savepoint iSavepoint is also destroyed.
+ **
 -** When a rollback occurs, the value of K is decreased. Hash table entries
 -** that correspond to frames greater than the new K value are removed
 -** from the hash table at this point.
 -*/
 -#ifndef SQLITE_OMIT_WAL
--
--
--/*
++** This function may return SQLITE_NOMEM if a memory allocation fails,
++** or an IO error code if an IO error occurs while rolling back a 
++** savepoint. If no errors occur, SQLITE_OK is returned.
++*/ 
++SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){
++  int rc = pPager->errCode;       /* Return code */
++
++  assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK );
++  assert( iSavepoint>=0 || op==SAVEPOINT_ROLLBACK );
++
++  if( rc==SQLITE_OK && iSavepoint<pPager->nSavepoint ){
++    int ii;            /* Iterator variable */
++    int nNew;          /* Number of remaining savepoints after this op. */
++
++    /* Figure out how many savepoints will still be active after this
++    ** operation. Store this value in nNew. Then free resources associated 
++    ** with any savepoints that are destroyed by this operation.
++    */
++    nNew = iSavepoint + (( op==SAVEPOINT_RELEASE ) ? 0 : 1);
++    for(ii=nNew; ii<pPager->nSavepoint; ii++){
++      sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
++    }
++    pPager->nSavepoint = nNew;
++
++    /* If this is a release of the outermost savepoint, truncate 
++    ** the sub-journal to zero bytes in size. */
++    if( op==SAVEPOINT_RELEASE ){
++      if( nNew==0 && isOpen(pPager->sjfd) ){
++        /* Only truncate if it is an in-memory sub-journal. */
++        if( sqlite3IsMemJournal(pPager->sjfd) ){
++          rc = sqlite3OsTruncate(pPager->sjfd, 0);
++          assert( rc==SQLITE_OK );
++        }
++        pPager->nSubRec = 0;
++      }
++    }
++    /* Else this is a rollback operation, playback the specified savepoint.
++    ** If this is a temp-file, it is possible that the journal file has
++    ** not yet been opened. In this case there have been no changes to
++    ** the database file, so the playback operation can be skipped.
++    */
++    else if( pagerUseWal(pPager) || isOpen(pPager->jfd) ){
++      PagerSavepoint *pSavepoint = (nNew==0)?0:&pPager->aSavepoint[nNew-1];
++      rc = pagerPlaybackSavepoint(pPager, pSavepoint);
++      assert(rc!=SQLITE_DONE);
++    }
++  }
+ 
++  return rc;
++}
+ 
+ /*
 -** Trace output macros
--*/
++** Return the full pathname of the database file.
++**
++** Except, if the pager is in-memory only, then return an empty string if
++** nullIfMemDb is true.  This routine is called with nullIfMemDb==1 when
++** used to report the filename to the user, for compatibility with legacy
++** behavior.  But when the Btree needs to know the filename for matching to
++** shared cache, it uses nullIfMemDb==0 so that in-memory databases can
++** participate in shared-cache.
+ */
 -#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
 -SQLITE_PRIVATE int sqlite3WalTrace = 0;
 -# define WALTRACE(X)  if(sqlite3WalTrace) sqlite3DebugPrintf X
 -#else
 -# define WALTRACE(X)
 -#endif
--
--/*
++SQLITE_PRIVATE const char *sqlite3PagerFilename(Pager *pPager, int nullIfMemDb){
++  return (nullIfMemDb && pPager->memDb) ? "" : pPager->zFilename;
++}
+ 
+ /*
 -** The maximum (and only) versions of the wal and wal-index formats
 -** that may be interpreted by this version of SQLite.
 -**
@@ -4144,38 +36943,86 @@
 -** checksum test is successful) and finds that the version field is not
 -** WALINDEX_MAX_VERSION, then no read-transaction is opened and SQLite
 -** returns SQLITE_CANTOPEN.
--*/
++** Return the VFS structure for the pager.
+ */
 -#define WAL_MAX_VERSION      3007000
 -#define WALINDEX_MAX_VERSION 3007000
--
--/*
++SQLITE_PRIVATE const sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){
++  return pPager->pVfs;
++}
+ 
+ /*
 -** Indices of various locking bytes.   WAL_NREADER is the number
 -** of available reader locks and should be at least 3.
--*/
++** Return the file handle for the database file associated
++** with the pager.  This might return NULL if the file has
++** not yet been opened.
+ */
 -#define WAL_WRITE_LOCK         0
 -#define WAL_ALL_BUT_WRITE      1
 -#define WAL_CKPT_LOCK          1
 -#define WAL_RECOVER_LOCK       2
 -#define WAL_READ_LOCK(I)       (3+(I))
 -#define WAL_NREADER            (SQLITE_SHM_NLOCK-3)
--
--
++SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){
++  return pPager->fd;
++}
+ 
++/*
++** Return the full pathname of the journal file.
++*/
++SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager *pPager){
++  return pPager->zJournal;
++}
+ 
 -/* Object declarations */
 -typedef struct WalIndexHdr WalIndexHdr;
 -typedef struct WalIterator WalIterator;
 -typedef struct WalCkptInfo WalCkptInfo;
--
--
--/*
++/*
++** Return true if fsync() calls are disabled for this pager.  Return FALSE
++** if fsync()s are executed normally.
++*/
++SQLITE_PRIVATE int sqlite3PagerNosync(Pager *pPager){
++  return pPager->noSync;
++}
+ 
++#ifdef SQLITE_HAS_CODEC
++/*
++** Set or retrieve the codec for this pager
++*/
++SQLITE_PRIVATE void sqlite3PagerSetCodec(
++  Pager *pPager,
++  void *(*xCodec)(void*,void*,Pgno,int),
++  void (*xCodecSizeChng)(void*,int,int),
++  void (*xCodecFree)(void*),
++  void *pCodec
++){
++  if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
++  pPager->xCodec = pPager->memDb ? 0 : xCodec;
++  pPager->xCodecSizeChng = xCodecSizeChng;
++  pPager->xCodecFree = xCodecFree;
++  pPager->pCodec = pCodec;
++  pagerReportSize(pPager);
++}
++SQLITE_PRIVATE void *sqlite3PagerGetCodec(Pager *pPager){
++  return pPager->pCodec;
++}
+ 
+ /*
 -** The following object holds a copy of the wal-index header content.
 -**
 -** The actual header in the wal-index consists of two copies of this
 -** object.
--**
++** This function is called by the wal module when writing page content
++** into the log file.
+ **
 -** The szPage value can be any power of 2 between 512 and 32768, inclusive.
 -** Or it can be 1 to represent a 65536-byte page.  The latter case was
 -** added in 3.7.1 when support for 64K pages was added.  
--*/
++** This function returns a pointer to a buffer containing the encrypted
++** page content. If a malloc fails, this function may return NULL.
+ */
 -struct WalIndexHdr {
 -  u32 iVersion;                   /* Wal-index version */
 -  u32 unused;                     /* Unused (padding) field */
@@ -4189,8 +37036,13 @@
 -  u32 aSalt[2];                   /* Two salt values copied from WAL header */
 -  u32 aCksum[2];                  /* Checksum over all prior fields */
 -};
--
--/*
++SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){
++  void *aData = 0;
++  CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData);
++  return aData;
++}
+ 
+ /*
 -** A copy of the following object occurs in the wal-index immediately
 -** following the second copy of the WalIndexHdr.  This object stores
 -** information used by checkpoint.
@@ -4202,7 +37054,17 @@
 -** holding the WAL_CKPT_LOCK lock (which includes a recovery thread).
 -** However, a WAL_WRITE_LOCK thread can move the value of nBackfill from
 -** mxFrame back to zero when the WAL is reset.
--**
++** Return the current pager state
++*/
++SQLITE_PRIVATE int sqlite3PagerState(Pager *pPager){
++  return pPager->eState;
++}
++#endif /* SQLITE_HAS_CODEC */
++
++#ifndef SQLITE_OMIT_AUTOVACUUM
++/*
++** Move the page pPg to location pgno in the file.
+ **
 -** There is one entry in aReadMark[] for each reader lock.  If a reader
 -** holds read-lock K, then the value in aReadMark[K] is no greater than
 -** the mxFrame for that reader.  The value READMARK_NOT_USED (0xffffffff)
@@ -4211,12 +37073,19 @@
 -** to avoid having to offset aReadMark[] indexs by one.  Readers holding
 -** WAL_READ_LOCK(0) always ignore the entire WAL and read all content
 -** directly from the database.
--**
++** There must be no references to the page previously located at
++** pgno (which we call pPgOld) though that page is allowed to be
++** in cache.  If the page previously located at pgno is not already
++** in the rollback journal, it is not put there by by this routine.
+ **
 -** The value of aReadMark[K] may only be changed by a thread that
 -** is holding an exclusive lock on WAL_READ_LOCK(K).  Thus, the value of
 -** aReadMark[K] cannot changed while there is a reader is using that mark
 -** since the reader will be holding a shared lock on WAL_READ_LOCK(K).
--**
++** References to the page pPg remain valid. Updating any
++** meta-data associated with pPg (i.e. data stored in the nExtra bytes
++** allocated along with the page) is the responsibility of the caller.
+ **
 -** The checkpointer may only transfer frames from WAL to database where
 -** the frame numbers are less than or equal to every aReadMark[] that is
 -** in use (that is, every aReadMark[j] for which there is a corresponding
@@ -4228,24 +37097,44 @@
 -** will choose aReadMark[0] which has value 0 and hence such reader will
 -** get all their all content directly from the database file and ignore 
 -** the WAL.
--**
++** A transaction must be active when this routine is called. It used to be
++** required that a statement transaction was not active, but this restriction
++** has been removed (CREATE INDEX needs to move a page when a statement
++** transaction is active).
+ **
 -** Writers normally append new frames to the end of the WAL.  However,
 -** if nBackfill equals mxFrame (meaning that all WAL content has been
 -** written back into the database) and if no readers are using the WAL
 -** (in other words, if there are no WAL_READ_LOCK(i) where i>0) then
 -** the writer will first "reset" the WAL back to the beginning and start
 -** writing new content beginning at frame 1.
--**
++** If the fourth argument, isCommit, is non-zero, then this page is being
++** moved as part of a database reorganization just before the transaction 
++** is being committed. In this case, it is guaranteed that the database page 
++** pPg refers to will not be written to again within this transaction.
+ **
 -** We assume that 32-bit loads are atomic and so no locks are needed in
 -** order to read from any aReadMark[] entries.
--*/
++** This function may return SQLITE_NOMEM or an IO error code if an error
++** occurs. Otherwise, it returns SQLITE_OK.
+ */
 -struct WalCkptInfo {
 -  u32 nBackfill;                  /* Number of WAL frames backfilled into DB */
 -  u32 aReadMark[WAL_NREADER];     /* Reader marks */
 -};
 -#define READMARK_NOT_USED  0xffffffff
--
--
++SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){
++  PgHdr *pPgOld;               /* The page being overwritten. */
++  Pgno needSyncPgno = 0;       /* Old value of pPg->pgno, if sync is required */
++  int rc;                      /* Return code */
++  Pgno origPgno;               /* The original page number */
+ 
++  assert( pPg->nRef>0 );
++  assert( pPager->eState==PAGER_WRITER_CACHEMOD
++       || pPager->eState==PAGER_WRITER_DBMOD
++  );
++  assert( assert_pager_state(pPager) );
+ 
 -/* A block of WALINDEX_LOCK_RESERVED bytes beginning at
 -** WALINDEX_LOCK_OFFSET is reserved for locks. Since some systems
 -** only support mandatory file-locks, we do not read or write data
@@ -4254,14 +37143,48 @@
 -#define WALINDEX_LOCK_OFFSET   (sizeof(WalIndexHdr)*2 + sizeof(WalCkptInfo))
 -#define WALINDEX_LOCK_RESERVED 16
 -#define WALINDEX_HDR_SIZE      (WALINDEX_LOCK_OFFSET+WALINDEX_LOCK_RESERVED)
--
++  /* In order to be able to rollback, an in-memory database must journal
++  ** the page we are moving from.
++  */
++  if( MEMDB ){
++    rc = sqlite3PagerWrite(pPg);
++    if( rc ) return rc;
++  }
+ 
 -/* Size of header before each frame in wal */
 -#define WAL_FRAME_HDRSIZE 24
--
++  /* If the page being moved is dirty and has not been saved by the latest
++  ** savepoint, then save the current contents of the page into the 
++  ** sub-journal now. This is required to handle the following scenario:
++  **
++  **   BEGIN;
++  **     <journal page X, then modify it in memory>
++  **     SAVEPOINT one;
++  **       <Move page X to location Y>
++  **     ROLLBACK TO one;
++  **
++  ** If page X were not written to the sub-journal here, it would not
++  ** be possible to restore its contents when the "ROLLBACK TO one"
++  ** statement were is processed.
++  **
++  ** subjournalPage() may need to allocate space to store pPg->pgno into
++  ** one or more savepoint bitvecs. This is the reason this function
++  ** may return SQLITE_NOMEM.
++  */
++  if( pPg->flags&PGHDR_DIRTY
++   && subjRequiresPage(pPg)
++   && SQLITE_OK!=(rc = subjournalPage(pPg))
++  ){
++    return rc;
++  }
+ 
 -/* Size of write ahead log header, including checksum. */
 -/* #define WAL_HDRSIZE 24 */
 -#define WAL_HDRSIZE 32
--
++  PAGERTRACE(("MOVE %d page %d (needSync=%d) moves to %d\n", 
++      PAGERID(pPager), pPg->pgno, (pPg->flags&PGHDR_NEED_SYNC)?1:0, pgno));
++  IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno))
+ 
 -/* WAL magic value. Either this value, or the same value with the least
 -** significant bit also set (WAL_MAGIC | 0x00000001) is stored in 32-bit
 -** big-endian format in the first 4 bytes of a WAL file.
@@ -4272,7 +37195,82 @@
 -** all data as 32-bit little-endian words.
 -*/
 -#define WAL_MAGIC 0x377f0682
--
++  /* If the journal needs to be sync()ed before page pPg->pgno can
++  ** be written to, store pPg->pgno in local variable needSyncPgno.
++  **
++  ** If the isCommit flag is set, there is no need to remember that
++  ** the journal needs to be sync()ed before database page pPg->pgno 
++  ** can be written to. The caller has already promised not to write to it.
++  */
++  if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){
++    needSyncPgno = pPg->pgno;
++    assert( pPager->journalMode==PAGER_JOURNALMODE_OFF ||
++            pageInJournal(pPager, pPg) || pPg->pgno>pPager->dbOrigSize );
++    assert( pPg->flags&PGHDR_DIRTY );
++  }
++
++  /* If the cache contains a page with page-number pgno, remove it
++  ** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for 
++  ** page pgno before the 'move' operation, it needs to be retained 
++  ** for the page moved there.
++  */
++  pPg->flags &= ~PGHDR_NEED_SYNC;
++  pPgOld = sqlite3PagerLookup(pPager, pgno);
++  assert( !pPgOld || pPgOld->nRef==1 );
++  if( pPgOld ){
++    pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
++    if( MEMDB ){
++      /* Do not discard pages from an in-memory database since we might
++      ** need to rollback later.  Just move the page out of the way. */
++      sqlite3PcacheMove(pPgOld, pPager->dbSize+1);
++    }else{
++      sqlite3PcacheDrop(pPgOld);
++    }
++  }
++
++  origPgno = pPg->pgno;
++  sqlite3PcacheMove(pPg, pgno);
++  sqlite3PcacheMakeDirty(pPg);
++
++  /* For an in-memory database, make sure the original page continues
++  ** to exist, in case the transaction needs to roll back.  Use pPgOld
++  ** as the original page since it has already been allocated.
++  */
++  if( MEMDB ){
++    assert( pPgOld );
++    sqlite3PcacheMove(pPgOld, origPgno);
++    sqlite3PagerUnrefNotNull(pPgOld);
++  }
++
++  if( needSyncPgno ){
++    /* If needSyncPgno is non-zero, then the journal file needs to be 
++    ** sync()ed before any data is written to database file page needSyncPgno.
++    ** Currently, no such page exists in the page-cache and the 
++    ** "is journaled" bitvec flag has been set. This needs to be remedied by
++    ** loading the page into the pager-cache and setting the PGHDR_NEED_SYNC
++    ** flag.
++    **
++    ** If the attempt to load the page into the page-cache fails, (due
++    ** to a malloc() or IO failure), clear the bit in the pInJournal[]
++    ** array. Otherwise, if the page is loaded and written again in
++    ** this transaction, it may be written to the database file before
++    ** it is synced into the journal file. This way, it may end up in
++    ** the journal file twice, but that is not a problem.
++    */
++    PgHdr *pPgHdr;
++    rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr);
++    if( rc!=SQLITE_OK ){
++      if( needSyncPgno<=pPager->dbOrigSize ){
++        assert( pPager->pTmpSpace!=0 );
++        sqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace);
++      }
++      return rc;
++    }
++    pPgHdr->flags |= PGHDR_NEED_SYNC;
++    sqlite3PcacheMakeDirty(pPgHdr);
++    sqlite3PagerUnrefNotNull(pPgHdr);
++  }
+ 
 -/*
 -** Return the offset of frame iFrame in the write-ahead log file, 
 -** assuming a database page size of szPage bytes. The offset returned
@@ -4281,11 +37279,18 @@
 -#define walFrameOffset(iFrame, szPage) (                               \
 -  WAL_HDRSIZE + ((iFrame)-1)*(i64)((szPage)+WAL_FRAME_HDRSIZE)         \
 -)
--
--/*
++  return SQLITE_OK;
++}
++#endif
+ 
+ /*
 -** An open write-ahead log file is represented by an instance of the
 -** following object.
--*/
++** The page handle passed as the first argument refers to a dirty page 
++** with a page number other than iNew. This function changes the page's 
++** page number to iNew and sets the value of the PgHdr.flags field to 
++** the value passed as the third parameter.
+ */
 -struct Wal {
 -  sqlite3_vfs *pVfs;         /* The VFS used to create pDbFd */
 -  sqlite3_file *pDbFd;       /* File handle for the database file */
@@ -4312,40 +37317,84 @@
 -  u8 lockError;              /* True if a locking error has occurred */
 -#endif
 -};
--
--/*
++SQLITE_PRIVATE void sqlite3PagerRekey(DbPage *pPg, Pgno iNew, u16 flags){
++  assert( pPg->pgno!=iNew );
++  pPg->flags = flags;
++  sqlite3PcacheMove(pPg, iNew);
++}
+ 
+ /*
 -** Candidate values for Wal.exclusiveMode.
--*/
++** Return a pointer to the data for the specified page.
+ */
 -#define WAL_NORMAL_MODE     0
 -#define WAL_EXCLUSIVE_MODE  1     
 -#define WAL_HEAPMEMORY_MODE 2
--
--/*
++SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *pPg){
++  assert( pPg->nRef>0 || pPg->pPager->memDb );
++  return pPg->pData;
++}
+ 
+ /*
 -** Possible values for WAL.readOnly
--*/
++** Return a pointer to the Pager.nExtra bytes of "extra" space 
++** allocated along with the specified page.
+ */
 -#define WAL_RDWR        0    /* Normal read/write connection */
 -#define WAL_RDONLY      1    /* The WAL file is readonly */
 -#define WAL_SHM_RDONLY  2    /* The SHM file is readonly */
--
--/*
++SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *pPg){
++  return pPg->pExtra;
++}
+ 
+ /*
 -** Each page of the wal-index mapping contains a hash-table made up of
 -** an array of HASHTABLE_NSLOT elements of the following type.
--*/
++** Get/set the locking-mode for this pager. Parameter eMode must be one
++** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or 
++** PAGER_LOCKINGMODE_EXCLUSIVE. If the parameter is not _QUERY, then
++** the locking-mode is set to the value specified.
++**
++** The returned value is either PAGER_LOCKINGMODE_NORMAL or
++** PAGER_LOCKINGMODE_EXCLUSIVE, indicating the current (possibly updated)
++** locking-mode.
+ */
 -typedef u16 ht_slot;
--
--/*
++SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *pPager, int eMode){
++  assert( eMode==PAGER_LOCKINGMODE_QUERY
++            || eMode==PAGER_LOCKINGMODE_NORMAL
++            || eMode==PAGER_LOCKINGMODE_EXCLUSIVE );
++  assert( PAGER_LOCKINGMODE_QUERY<0 );
++  assert( PAGER_LOCKINGMODE_NORMAL>=0 && PAGER_LOCKINGMODE_EXCLUSIVE>=0 );
++  assert( pPager->exclusiveMode || 0==sqlite3WalHeapMemory(pPager->pWal) );
++  if( eMode>=0 && !pPager->tempFile && !sqlite3WalHeapMemory(pPager->pWal) ){
++    pPager->exclusiveMode = (u8)eMode;
++  }
++  return (int)pPager->exclusiveMode;
++}
+ 
+ /*
 -** This structure is used to implement an iterator that loops through
 -** all frames in the WAL in database page order. Where two or more frames
 -** correspond to the same database page, the iterator visits only the 
 -** frame most recently written to the WAL (in other words, the frame with
 -** the largest index).
--**
++** Set the journal-mode for this pager. Parameter eMode must be one of:
+ **
 -** The internals of this structure are only accessed by:
--**
++**    PAGER_JOURNALMODE_DELETE
++**    PAGER_JOURNALMODE_TRUNCATE
++**    PAGER_JOURNALMODE_PERSIST
++**    PAGER_JOURNALMODE_OFF
++**    PAGER_JOURNALMODE_MEMORY
++**    PAGER_JOURNALMODE_WAL
+ **
 -**   walIteratorInit() - Create a new iterator,
 -**   walIteratorNext() - Step an iterator,
 -**   walIteratorFree() - Free an iterator.
--**
++** The journalmode is set to the value specified if the change is allowed.
++** The change may be disallowed for the following reasons:
+ **
 -** This functionality is used by the checkpoint code (see walCheckpoint()).
 -*/
 -struct WalIterator {
@@ -4364,26 +37413,38 @@
 -** Define the parameters of the hash tables in the wal-index file. There
 -** is a hash-table following every HASHTABLE_NPAGE page numbers in the
 -** wal-index.
--**
++**   *  An in-memory database can only have its journal_mode set to _OFF
++**      or _MEMORY.
+ **
 -** Changing any of these constants will alter the wal-index format and
 -** create incompatibilities.
--*/
++**   *  Temporary databases cannot have _WAL journalmode.
++**
++** The returned indicate the current (possibly updated) journal-mode.
+ */
 -#define HASHTABLE_NPAGE      4096                 /* Must be power of 2 */
 -#define HASHTABLE_HASH_1     383                  /* Should be prime */
 -#define HASHTABLE_NSLOT      (HASHTABLE_NPAGE*2)  /* Must be a power of 2 */
--
++SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){
++  u8 eOld = pPager->journalMode;    /* Prior journalmode */
+ 
 -/* 
 -** The block of page numbers associated with the first hash-table in a
 -** wal-index is smaller than usual. This is so that there is a complete
 -** hash-table on each aligned 32KB page of the wal-index.
 -*/
 -#define HASHTABLE_NPAGE_ONE  (HASHTABLE_NPAGE - (WALINDEX_HDR_SIZE/sizeof(u32)))
--
++#ifdef SQLITE_DEBUG
++  /* The print_pager_state() routine is intended to be used by the debugger
++  ** only.  We invoke it once here to suppress a compiler warning. */
++  print_pager_state(pPager);
++#endif
+ 
 -/* The wal-index is divided into pages of WALINDEX_PGSZ bytes each. */
 -#define WALINDEX_PGSZ   (                                         \
 -    sizeof(ht_slot)*HASHTABLE_NSLOT + HASHTABLE_NPAGE*sizeof(u32) \
 -)
--
+ 
 -/*
 -** Obtain a pointer to the iPage'th page of the wal-index. The wal-index
 -** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are
@@ -4395,22 +37456,42 @@
 -*/
 -static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
 -  int rc = SQLITE_OK;
--
++  /* The eMode parameter is always valid */
++  assert(      eMode==PAGER_JOURNALMODE_DELETE
++            || eMode==PAGER_JOURNALMODE_TRUNCATE
++            || eMode==PAGER_JOURNALMODE_PERSIST
++            || eMode==PAGER_JOURNALMODE_OFF 
++            || eMode==PAGER_JOURNALMODE_WAL 
++            || eMode==PAGER_JOURNALMODE_MEMORY );
+ 
 -  /* Enlarge the pWal->apWiData[] array if required */
 -  if( pWal->nWiData<=iPage ){
 -    int nByte = sizeof(u32*)*(iPage+1);
 -    volatile u32 **apNew;
--    apNew = (volatile u32 **)sqlite3_realloc((void *)pWal->apWiData, nByte);
+-    apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
 -    if( !apNew ){
 -      *ppPage = 0;
 -      return SQLITE_NOMEM;
--    }
++  /* This routine is only called from the OP_JournalMode opcode, and
++  ** the logic there will never allow a temporary file to be changed
++  ** to WAL mode.
++  */
++  assert( pPager->tempFile==0 || eMode!=PAGER_JOURNALMODE_WAL );
++
++  /* Do allow the journalmode of an in-memory database to be set to
++  ** anything other than MEMORY or OFF
++  */
++  if( MEMDB ){
++    assert( eOld==PAGER_JOURNALMODE_MEMORY || eOld==PAGER_JOURNALMODE_OFF );
++    if( eMode!=PAGER_JOURNALMODE_MEMORY && eMode!=PAGER_JOURNALMODE_OFF ){
++      eMode = eOld;
+     }
 -    memset((void*)&apNew[pWal->nWiData], 0,
 -           sizeof(u32*)*(iPage+1-pWal->nWiData));
 -    pWal->apWiData = apNew;
 -    pWal->nWiData = iPage+1;
--  }
--
+   }
+ 
 -  /* Request a pointer to the required page from the VFS */
 -  if( pWal->apWiData[iPage]==0 ){
 -    if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
@@ -4423,36 +37504,102 @@
 -      if( rc==SQLITE_READONLY ){
 -        pWal->readOnly |= WAL_SHM_RDONLY;
 -        rc = SQLITE_OK;
--      }
--    }
--  }
--
++  if( eMode!=eOld ){
++
++    /* Change the journal mode. */
++    assert( pPager->eState!=PAGER_ERROR );
++    pPager->journalMode = (u8)eMode;
++
++    /* When transistioning from TRUNCATE or PERSIST to any other journal
++    ** mode except WAL, unless the pager is in locking_mode=exclusive mode,
++    ** delete the journal file.
++    */
++    assert( (PAGER_JOURNALMODE_TRUNCATE & 5)==1 );
++    assert( (PAGER_JOURNALMODE_PERSIST & 5)==1 );
++    assert( (PAGER_JOURNALMODE_DELETE & 5)==0 );
++    assert( (PAGER_JOURNALMODE_MEMORY & 5)==4 );
++    assert( (PAGER_JOURNALMODE_OFF & 5)==0 );
++    assert( (PAGER_JOURNALMODE_WAL & 5)==5 );
++
++    assert( isOpen(pPager->fd) || pPager->exclusiveMode );
++    if( !pPager->exclusiveMode && (eOld & 5)==1 && (eMode & 1)==0 ){
++
++      /* In this case we would like to delete the journal file. If it is
++      ** not possible, then that is not a problem. Deleting the journal file
++      ** here is an optimization only.
++      **
++      ** Before deleting the journal file, obtain a RESERVED lock on the
++      ** database file. This ensures that the journal file is not deleted
++      ** while it is in use by some other client.
++      */
++      sqlite3OsClose(pPager->jfd);
++      if( pPager->eLock>=RESERVED_LOCK ){
++        sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
++      }else{
++        int rc = SQLITE_OK;
++        int state = pPager->eState;
++        assert( state==PAGER_OPEN || state==PAGER_READER );
++        if( state==PAGER_OPEN ){
++          rc = sqlite3PagerSharedLock(pPager);
++        }
++        if( pPager->eState==PAGER_READER ){
++          assert( rc==SQLITE_OK );
++          rc = pagerLockDb(pPager, RESERVED_LOCK);
++        }
++        if( rc==SQLITE_OK ){
++          sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
++        }
++        if( rc==SQLITE_OK && state==PAGER_READER ){
++          pagerUnlockDb(pPager, SHARED_LOCK);
++        }else if( state==PAGER_OPEN ){
++          pager_unlock(pPager);
++        }
++        assert( state==pPager->eState );
+       }
++    }else if( eMode==PAGER_JOURNALMODE_OFF ){
++      sqlite3OsClose(pPager->jfd);
+     }
+   }
+ 
 -  *ppPage = pWal->apWiData[iPage];
 -  assert( iPage==0 || *ppPage || rc!=SQLITE_OK );
 -  return rc;
--}
--
--/*
++  /* Return the new journal mode */
++  return (int)pPager->journalMode;
+ }
+ 
+ /*
 -** Return a pointer to the WalCkptInfo structure in the wal-index.
--*/
++** Return the current journal mode.
+ */
 -static volatile WalCkptInfo *walCkptInfo(Wal *pWal){
 -  assert( pWal->nWiData>0 && pWal->apWiData[0] );
 -  return (volatile WalCkptInfo*)&(pWal->apWiData[0][sizeof(WalIndexHdr)/2]);
--}
--
--/*
++SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager *pPager){
++  return (int)pPager->journalMode;
+ }
+ 
+ /*
 -** Return a pointer to the WalIndexHdr structure in the wal-index.
--*/
++** Return TRUE if the pager is in a state where it is OK to change the
++** journalmode.  Journalmode changes can only happen when the database
++** is unmodified.
+ */
 -static volatile WalIndexHdr *walIndexHdr(Wal *pWal){
 -  assert( pWal->nWiData>0 && pWal->apWiData[0] );
 -  return (volatile WalIndexHdr*)pWal->apWiData[0];
--}
--
--/*
++SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager *pPager){
++  assert( assert_pager_state(pPager) );
++  if( pPager->eState>=PAGER_WRITER_CACHEMOD ) return 0;
++  if( NEVER(isOpen(pPager->jfd) && pPager->journalOff>0) ) return 0;
++  return 1;
+ }
+ 
+ /*
 -** The argument to this macro must be of type u32. On a little-endian
 -** architecture, it returns the u32 value that results from interpreting
 -** the 4 bytes as a big-endian value. On a big-endian architecture, it
--** returns the value that would be produced by intepreting the 4 bytes
+-** returns the value that would be produced by interpreting the 4 bytes
 -** of the input value as a little-endian integer.
 -*/
 -#define BYTESWAP32(x) ( \
@@ -4466,9 +37613,12 @@
 -** initial values of 0 and 0 if aIn==NULL).
 -**
 -** The checksum is written back into aOut[] before returning.
--**
++** Get/set the size-limit used for persistent journal files.
+ **
 -** nByte must be a positive multiple of 8.
--*/
++** Setting the size limit to -1 means no limit is enforced.
++** An attempt to set a limit smaller than -1 is a no-op.
+ */
 -static void walChecksumBytes(
 -  int nativeCksum, /* True for native byte-order, false for non-native */
 -  u8 *a,           /* Content to be checksummed */
@@ -4510,14 +37660,23 @@
 -static void walShmBarrier(Wal *pWal){
 -  if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){
 -    sqlite3OsShmBarrier(pWal->pDbFd);
--  }
--}
--
--/*
++SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){
++  if( iLimit>=-1 ){
++    pPager->journalSizeLimit = iLimit;
++    sqlite3WalLimit(pPager->pWal, iLimit);
+   }
++  return pPager->journalSizeLimit;
+ }
+ 
+ /*
 -** Write the header information in pWal->hdr into the wal-index.
 -**
 -** The checksum on pWal->hdr is updated before it is written.
--*/
++** Return a pointer to the pPager->pBackup variable. The backup module
++** in backup.c maintains the content of this variable. This module
++** uses it opaquely as an argument to sqlite3BackupRestart() and
++** sqlite3BackupUpdate() only.
+ */
 -static void walIndexWriteHdr(Wal *pWal){
 -  volatile WalIndexHdr *aHdr = walIndexHdr(pWal);
 -  const int nCksum = offsetof(WalIndexHdr, aCksum);
@@ -4529,9 +37688,12 @@
 -  memcpy((void *)&aHdr[1], (void *)&pWal->hdr, sizeof(WalIndexHdr));
 -  walShmBarrier(pWal);
 -  memcpy((void *)&aHdr[0], (void *)&pWal->hdr, sizeof(WalIndexHdr));
--}
--
--/*
++SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){
++  return &pPager->pBackup;
+ }
+ 
++#ifndef SQLITE_OMIT_VACUUM
+ /*
 -** This function encodes a single frame header and writes it to a buffer
 -** supplied by the caller. A frame-header is made up of a series of 
 -** 4-byte big-endian integers, as follows:
@@ -4543,7 +37705,8 @@
 -**    12: Salt-2 (copied from the wal-header)
 -**    16: Checksum-1.
 -**    20: Checksum-2.
--*/
++** Unless this is an in-memory or temporary database, clear the pager cache.
+ */
 -static void walEncodeFrame(
 -  Wal *pWal,                      /* The write-ahead log */
 -  u32 iPage,                      /* Database page number for frame */
@@ -4564,13 +37727,22 @@
 -
 -  sqlite3Put4byte(&aFrame[16], aCksum[0]);
 -  sqlite3Put4byte(&aFrame[20], aCksum[1]);
--}
--
--/*
++SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *pPager){
++  if( !MEMDB && pPager->tempFile==0 ) pager_reset(pPager);
+ }
++#endif
+ 
++#ifndef SQLITE_OMIT_WAL
+ /*
 -** Check to see if the frame with header in aFrame[] and content
 -** in aData[] is valid.  If it is a valid frame, fill *piPage and
 -** *pnTruncate and return true.  Return if the frame is not valid.
--*/
++** This function is called when the user invokes "PRAGMA wal_checkpoint",
++** "PRAGMA wal_blocking_checkpoint" or calls the sqlite3_wal_checkpoint()
++** or wal_blocking_checkpoint() API functions.
++**
++** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART.
+ */
 -static int walDecodeFrame(
 -  Wal *pWal,                      /* The write-ahead log */
 -  u32 *piPage,                    /* OUT: Database page number for frame */
@@ -4610,7 +37782,16 @@
 -  ){
 -    /* Checksum failed. */
 -    return 0;
--  }
++SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, int eMode, int *pnLog, int *pnCkpt){
++  int rc = SQLITE_OK;
++  if( pPager->pWal ){
++    rc = sqlite3WalCheckpoint(pPager->pWal, eMode,
++        (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler),
++        pPager->pBusyHandlerArg,
++        pPager->ckptSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace,
++        pnLog, pnCkpt
++    );
+   }
 -
 -  /* If we reach this point, the frame is valid.  Return the page number
 -  ** and the new database size.
@@ -4618,26 +37799,15 @@
 -  *piPage = pgno;
 -  *pnTruncate = sqlite3Get4byte(&aFrame[4]);
 -  return 1;
--}
-+** slots in the hash table and so the first reader will get an answer as
-+** if no values greater than K0 had ever been inserted into the hash table
-+** in the first place - which is what reader one wants.  Meanwhile, the
-+** second reader using K1 will see additional values that were inserted
-+** later, which is exactly what reader two wants.  
-+**
-+** When a rollback occurs, the value of K is decreased. Hash table entries
-+** that correspond to frames greater than the new K value are removed
-+** from the hash table at this point.
-+*/
-+#ifndef SQLITE_OMIT_WAL
- 
++  return rc;
+ }
  
+-
 -#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
- /*
+-/*
 -** Names of locks.  This routine is used to provide debugging output and is not
 -** a part of an ordinary build.
-+** Trace output macros
- */
+-*/
 -static const char *walLockName(int lockIdx){
 -  if( lockIdx==WAL_WRITE_LOCK ){
 -    return "WRITE-LOCK";
@@ -4651,32 +37821,20 @@
 -                     lockIdx-WAL_READ_LOCK(0));
 -    return zName;
 -  }
--}
++SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){
++  return sqlite3WalCallback(pPager->pWal);
+ }
 -#endif /*defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */
 -    
-+#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
-+SQLITE_PRIVATE int sqlite3WalTrace = 0;
-+# define WALTRACE(X)  if(sqlite3WalTrace) sqlite3DebugPrintf X
-+#else
-+# define WALTRACE(X)
-+#endif
  
  /*
 -** Set or release locks on the WAL.  Locks are either shared or exclusive.
 -** A lock cannot be moved directly between shared and exclusive - it must go
 -** through the unlocked state first.
-+** The maximum (and only) versions of the wal and wal-index formats
-+** that may be interpreted by this version of SQLite.
- **
+-**
 -** In locking_mode=EXCLUSIVE, all of these routines become no-ops.
-+** If a client begins recovering a WAL file and finds that (a) the checksum
-+** values in the wal-header are correct and (b) the version field is not
-+** WAL_MAX_VERSION, recovery fails and SQLite returns SQLITE_CANTOPEN.
-+**
-+** Similarly, if a client successfully reads a wal-index header (i.e. the 
-+** checksum test is successful) and finds that the version field is not
-+** WALINDEX_MAX_VERSION, then no read-transaction is opened and SQLite
-+** returns SQLITE_CANTOPEN.
++** Return true if the underlying VFS for the given pager supports the
++** primitives necessary for write-ahead logging.
  */
 -static int walLockShared(Wal *pWal, int lockIdx){
 -  int rc;
@@ -4693,17 +37851,37 @@
 -  (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
 -                         SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED);
 -  WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx)));
--}
--static int walLockExclusive(Wal *pWal, int lockIdx, int n){
++SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager){
++  const sqlite3_io_methods *pMethods = pPager->fd->pMethods;
++  return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap);
+ }
+-static int walLockExclusive(Wal *pWal, int lockIdx, int n, int fBlock){
 -  int rc;
 -  if( pWal->exclusiveMode ) return SQLITE_OK;
+-  if( fBlock ) sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_WAL_BLOCK, 0);
 -  rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
 -                        SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE);
 -  WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal,
 -            walLockName(lockIdx), n, rc ? "failed" : "ok"));
 -  VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
--  return rc;
--}
++
++/*
++** Attempt to take an exclusive lock on the database file. If a PENDING lock
++** is obtained instead, immediately release it.
++*/
++static int pagerExclusiveLock(Pager *pPager){
++  int rc;                         /* Return code */
++
++  assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK );
++  rc = pagerLockDb(pPager, EXCLUSIVE_LOCK);
++  if( rc!=SQLITE_OK ){
++    /* If the attempt to grab the exclusive lock failed, release the 
++    ** pending lock that may have been obtained instead.  */
++    pagerUnlockDb(pPager, SHARED_LOCK);
++  }
++
+   return rc;
+ }
 -static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){
 -  if( pWal->exclusiveMode ) return;
 -  (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
@@ -4711,14 +37889,16 @@
 -  WALTRACE(("WAL%p: release EXCLUSIVE-%s cnt=%d\n", pWal,
 -             walLockName(lockIdx), n));
 -}
-+#define WAL_MAX_VERSION      3007000
-+#define WALINDEX_MAX_VERSION 3007000
  
  /*
 -** Compute a hash on a page number.  The resulting hash value must land
 -** between 0 and (HASHTABLE_NSLOT-1).  The walHashNext() function advances
 -** the hash to the next value in the event of a collision.
--*/
++** Call sqlite3WalOpen() to open the WAL handle. If the pager is in 
++** exclusive-locking mode when this function is called, take an EXCLUSIVE
++** lock on the database file and use heap-memory to store the wal-index
++** in. Otherwise, use the normal shared-memory.
+ */
 -static int walHash(u32 iPage){
 -  assert( iPage>0 );
 -  assert( (HASHTABLE_NSLOT & (HASHTABLE_NSLOT-1))==0 );
@@ -4726,23 +37906,61 @@
 -}
 -static int walNextHash(int iPriorHash){
 -  return (iPriorHash+1)&(HASHTABLE_NSLOT-1);
--}
--
++static int pagerOpenWal(Pager *pPager){
++  int rc = SQLITE_OK;
++
++  assert( pPager->pWal==0 && pPager->tempFile==0 );
++  assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK );
++
++  /* If the pager is already in exclusive-mode, the WAL module will use 
++  ** heap-memory for the wal-index instead of the VFS shared-memory 
++  ** implementation. Take the exclusive lock now, before opening the WAL
++  ** file, to make sure this is safe.
++  */
++  if( pPager->exclusiveMode ){
++    rc = pagerExclusiveLock(pPager);
++  }
++
++  /* Open the connection to the log file. If this operation fails, 
++  ** (e.g. due to malloc() failure), return an error code.
++  */
++  if( rc==SQLITE_OK ){
++    rc = sqlite3WalOpen(pPager->pVfs,
++        pPager->fd, pPager->zWal, pPager->exclusiveMode,
++        pPager->journalSizeLimit, &pPager->pWal
++    );
++  }
++  pagerFixMaplimit(pPager);
++
++  return rc;
+ }
+ 
 -/* 
 -** Return pointers to the hash table and page number array stored on
 -** page iHash of the wal-index. The wal-index is broken into 32KB pages
 -** numbered starting from 0.
--**
++
++/*
++** The caller must be holding a SHARED lock on the database file to call
++** this function.
+ **
 -** Set output variable *paHash to point to the start of the hash table
 -** in the wal-index file. Set *piZero to one less than the frame 
 -** number of the first frame indexed by this hash table. If a
 -** slot in the hash table is set to N, it refers to frame number 
 -** (*piZero+N) in the log.
--**
++** If the pager passed as the first argument is open on a real database
++** file (not a temp file or an in-memory database), and the WAL file
++** is not already open, make an attempt to open it now. If successful,
++** return SQLITE_OK. If an error occurs or the VFS used by the pager does 
++** not support the xShmXXX() methods, return an error code. *pbOpen is
++** not modified in either case.
+ **
 -** Finally, set *paPgno so that *paPgno[1] is the page number of the
 -** first frame indexed by the hash table, frame (*piZero+1).
-+** Indices of various locking bytes.   WAL_NREADER is the number
-+** of available reader locks and should be at least 3.
++** If the pager is open on a temp-file (or in-memory database), or if
++** the WAL file is already open, set *pbOpen to 1 and return SQLITE_OK
++** without doing anything.
  */
 -static int walHashGet(
 -  Wal *pWal,                      /* WAL handle */
@@ -4750,22 +37968,27 @@
 -  volatile ht_slot **paHash,      /* OUT: Pointer to hash index */
 -  volatile u32 **paPgno,          /* OUT: Pointer to page number array */
 -  u32 *piZero                     /* OUT: Frame associated with *paPgno[0] */
--){
++SQLITE_PRIVATE int sqlite3PagerOpenWal(
++  Pager *pPager,                  /* Pager object */
++  int *pbOpen                     /* OUT: Set to true if call is a no-op */
+ ){
 -  int rc;                         /* Return code */
 -  volatile u32 *aPgno;
--
++  int rc = SQLITE_OK;             /* Return code */
+ 
 -  rc = walIndexPage(pWal, iHash, &aPgno);
 -  assert( rc==SQLITE_OK || iHash>0 );
-+#define WAL_WRITE_LOCK         0
-+#define WAL_ALL_BUT_WRITE      1
-+#define WAL_CKPT_LOCK          1
-+#define WAL_RECOVER_LOCK       2
-+#define WAL_READ_LOCK(I)       (3+(I))
-+#define WAL_NREADER            (SQLITE_SHM_NLOCK-3)
++  assert( assert_pager_state(pPager) );
++  assert( pPager->eState==PAGER_OPEN   || pbOpen );
++  assert( pPager->eState==PAGER_READER || !pbOpen );
++  assert( pbOpen==0 || *pbOpen==0 );
++  assert( pbOpen!=0 || (!pPager->tempFile && !pPager->pWal) );
  
 -  if( rc==SQLITE_OK ){
 -    u32 iZero;
 -    volatile ht_slot *aHash;
++  if( !pPager->tempFile && !pPager->pWal ){
++    if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN;
  
 -    aHash = (volatile ht_slot *)&aPgno[HASHTABLE_NPAGE];
 -    if( iHash==0 ){
@@ -4773,25 +37996,38 @@
 -      iZero = 0;
 -    }else{
 -      iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE;
--    }
++    /* Close any rollback journal previously open */
++    sqlite3OsClose(pPager->jfd);
++
++    rc = pagerOpenWal(pPager);
++    if( rc==SQLITE_OK ){
++      pPager->journalMode = PAGER_JOURNALMODE_WAL;
++      pPager->eState = PAGER_OPEN;
+     }
 -  
 -    *paPgno = &aPgno[-1];
 -    *paHash = aHash;
 -    *piZero = iZero;
--  }
--  return rc;
--}
-+/* Object declarations */
-+typedef struct WalIndexHdr WalIndexHdr;
-+typedef struct WalIterator WalIterator;
-+typedef struct WalCkptInfo WalCkptInfo;
++  }else{
++    *pbOpen = 1;
+   }
++
+   return rc;
+ }
  
--/*
+ /*
 -** Return the number of the wal-index page that contains the hash-table
 -** and page-number array that contain entries corresponding to WAL frame
 -** iFrame. The wal-index is broken up into 32KB pages. Wal-index pages 
 -** are numbered starting from 0.
--*/
++** This function is called to close the connection to the log file prior
++** to switching from WAL to rollback mode.
++**
++** Before closing the log file, this function attempts to take an 
++** EXCLUSIVE lock on the database file. If this cannot be obtained, an
++** error (SQLITE_BUSY) is returned and the log connection is not closed.
++** If successful, the EXCLUSIVE lock is not released before returning.
+ */
 -static int walFramePage(u32 iFrame){
 -  int iHash = (iFrame+HASHTABLE_NPAGE-HASHTABLE_NPAGE_ONE-1) / HASHTABLE_NPAGE;
 -  assert( (iHash==0 || iFrame>HASHTABLE_NPAGE_ONE)
@@ -4802,95 +38038,70 @@
 -  );
 -  return iHash;
 -}
++SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager){
++  int rc = SQLITE_OK;
  
- /*
+-/*
 -** Return the page number associated with frame iFrame in this WAL.
-+** The following object holds a copy of the wal-index header content.
-+**
-+** The actual header in the wal-index consists of two copies of this
-+** object.
-+**
-+** The szPage value can be any power of 2 between 512 and 32768, inclusive.
-+** Or it can be 1 to represent a 65536-byte page.  The latter case was
-+** added in 3.7.1 when support for 64K pages was added.  
- */
+-*/
 -static u32 walFramePgno(Wal *pWal, u32 iFrame){
 -  int iHash = walFramePage(iFrame);
 -  if( iHash==0 ){
 -    return pWal->apWiData[0][WALINDEX_HDR_SIZE/sizeof(u32) + iFrame - 1];
--  }
++  assert( pPager->journalMode==PAGER_JOURNALMODE_WAL );
++
++  /* If the log file is not already open, but does exist in the file-system,
++  ** it may need to be checkpointed before the connection can switch to
++  ** rollback mode. Open it now so this can happen.
++  */
++  if( !pPager->pWal ){
++    int logexists = 0;
++    rc = pagerLockDb(pPager, SHARED_LOCK);
++    if( rc==SQLITE_OK ){
++      rc = sqlite3OsAccess(
++          pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &logexists
++      );
++    }
++    if( rc==SQLITE_OK && logexists ){
++      rc = pagerOpenWal(pPager);
++    }
+   }
 -  return pWal->apWiData[iHash][(iFrame-1-HASHTABLE_NPAGE_ONE)%HASHTABLE_NPAGE];
--}
-+struct WalIndexHdr {
-+  u32 iVersion;                   /* Wal-index version */
-+  u32 unused;                     /* Unused (padding) field */
-+  u32 iChange;                    /* Counter incremented each transaction */
-+  u8 isInit;                      /* 1 when initialized */
-+  u8 bigEndCksum;                 /* True if checksums in WAL are big-endian */
-+  u16 szPage;                     /* Database page size in bytes. 1==64K */
-+  u32 mxFrame;                    /* Index of last valid frame in the WAL */
-+  u32 nPage;                      /* Size of database in pages */
-+  u32 aFrameCksum[2];             /* Checksum of last frame in log */
-+  u32 aSalt[2];                   /* Two salt values copied from WAL header */
-+  u32 aCksum[2];                  /* Checksum over all prior fields */
-+};
++    
++  /* Checkpoint and close the log. Because an EXCLUSIVE lock is held on
++  ** the database file, the log and log-summary files will be deleted.
++  */
++  if( rc==SQLITE_OK && pPager->pWal ){
++    rc = pagerExclusiveLock(pPager);
++    if( rc==SQLITE_OK ){
++      rc = sqlite3WalClose(pPager->pWal, pPager->ckptSyncFlags,
++                           pPager->pageSize, (u8*)pPager->pTmpSpace);
++      pPager->pWal = 0;
++      pagerFixMaplimit(pPager);
++    }
++  }
++  return rc;
+ }
  
++#endif /* !SQLITE_OMIT_WAL */
++
++#ifdef SQLITE_ENABLE_ZIPVFS
  /*
 -** Remove entries from the hash table that point to WAL slots greater
 -** than pWal->hdr.mxFrame.
-+** A copy of the following object occurs in the wal-index immediately
-+** following the second copy of the WalIndexHdr.  This object stores
-+** information used by checkpoint.
- **
+-**
 -** This function is called whenever pWal->hdr.mxFrame is decreased due
 -** to a rollback or savepoint.
-+** nBackfill is the number of frames in the WAL that have been written
-+** back into the database. (We call the act of moving content from WAL to
-+** database "backfilling".)  The nBackfill number is never greater than
-+** WalIndexHdr.mxFrame.  nBackfill can only be increased by threads
-+** holding the WAL_CKPT_LOCK lock (which includes a recovery thread).
-+** However, a WAL_WRITE_LOCK thread can move the value of nBackfill from
-+** mxFrame back to zero when the WAL is reset.
- **
+-**
 -** At most only the hash table containing pWal->hdr.mxFrame needs to be
 -** updated.  Any later hash tables will be automatically cleared when
 -** pWal->hdr.mxFrame advances to the point where those hash tables are
 -** actually needed.
-+** There is one entry in aReadMark[] for each reader lock.  If a reader
-+** holds read-lock K, then the value in aReadMark[K] is no greater than
-+** the mxFrame for that reader.  The value READMARK_NOT_USED (0xffffffff)
-+** for any aReadMark[] means that entry is unused.  aReadMark[0] is 
-+** a special case; its value is never used and it exists as a place-holder
-+** to avoid having to offset aReadMark[] indexs by one.  Readers holding
-+** WAL_READ_LOCK(0) always ignore the entire WAL and read all content
-+** directly from the database.
-+**
-+** The value of aReadMark[K] may only be changed by a thread that
-+** is holding an exclusive lock on WAL_READ_LOCK(K).  Thus, the value of
-+** aReadMark[K] cannot changed while there is a reader is using that mark
-+** since the reader will be holding a shared lock on WAL_READ_LOCK(K).
-+**
-+** The checkpointer may only transfer frames from WAL to database where
-+** the frame numbers are less than or equal to every aReadMark[] that is
-+** in use (that is, every aReadMark[j] for which there is a corresponding
-+** WAL_READ_LOCK(j)).  New readers (usually) pick the aReadMark[] with the
-+** largest value and will increase an unused aReadMark[] to mxFrame if there
-+** is not already an aReadMark[] equal to mxFrame.  The exception to the
-+** previous sentence is when nBackfill equals mxFrame (meaning that everything
-+** in the WAL has been backfilled into the database) then new readers
-+** will choose aReadMark[0] which has value 0 and hence such reader will
-+** get all their all content directly from the database file and ignore 
-+** the WAL.
-+**
-+** Writers normally append new frames to the end of the WAL.  However,
-+** if nBackfill equals mxFrame (meaning that all WAL content has been
-+** written back into the database) and if no readers are using the WAL
-+** (in other words, if there are no WAL_READ_LOCK(i) where i>0) then
-+** the writer will first "reset" the WAL back to the beginning and start
-+** writing new content beginning at frame 1.
-+**
-+** We assume that 32-bit loads are atomic and so no locks are needed in
-+** order to read from any aReadMark[] entries.
++** A read-lock must be held on the pager when this function is called. If
++** the pager is in WAL mode and the WAL file currently contains one or more
++** frames, return the size in bytes of the page images stored within the
++** WAL frames. Otherwise, if this is not a WAL database or the WAL file
++** is empty, return 0.
  */
 -static void walCleanupHash(Wal *pWal){
 -  volatile ht_slot *aHash = 0;    /* Pointer to hash table to clear */
@@ -4899,11 +38110,11 @@
 -  int iLimit = 0;                 /* Zero values greater than this */
 -  int nByte;                      /* Number of bytes to zero in aPgno[] */
 -  int i;                          /* Used to iterate through aHash[] */
-+struct WalCkptInfo {
-+  u32 nBackfill;                  /* Number of WAL frames backfilled into DB */
-+  u32 aReadMark[WAL_NREADER];     /* Reader marks */
-+};
-+#define READMARK_NOT_USED  0xffffffff
++SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){
++  assert( pPager->eState>=PAGER_READER );
++  return sqlite3WalFramesize(pPager->pWal);
++}
++#endif
  
 -  assert( pWal->writeLock );
 -  testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE-1 );
@@ -4911,14 +38122,7 @@
 -  testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE+1 );
  
 -  if( pWal->hdr.mxFrame==0 ) return;
-+/* A block of WALINDEX_LOCK_RESERVED bytes beginning at
-+** WALINDEX_LOCK_OFFSET is reserved for locks. Since some systems
-+** only support mandatory file-locks, we do not read or write data
-+** from the region of the file on which locks are applied.
-+*/
-+#define WALINDEX_LOCK_OFFSET   (sizeof(WalIndexHdr)*2 + sizeof(WalCkptInfo))
-+#define WALINDEX_LOCK_RESERVED 16
-+#define WALINDEX_HDR_SIZE      (WALINDEX_LOCK_OFFSET+WALINDEX_LOCK_RESERVED)
++#endif /* SQLITE_OMIT_DISKIO */
  
 -  /* Obtain pointers to the hash-table and page-number array containing 
 -  ** the entry that corresponds to frame pWal->hdr.mxFrame. It is guaranteed
@@ -4927,8 +38131,11 @@
 -  assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) );
 -  assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] );
 -  walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &aHash, &aPgno, &iZero);
-+/* Size of header before each frame in wal */
-+#define WAL_FRAME_HDRSIZE 24
++/* BEGIN SQLCIPHER */
++#ifdef SQLITE_HAS_CODEC
++SQLITE_PRIVATE void sqlite3pager_get_codec(Pager *pPager, void **ctx) {
++  *ctx = pPager->pCodec;
++}
  
 -  /* Zero all hash-table entries that correspond to frame numbers greater
 -  ** than pWal->hdr.mxFrame.
@@ -4946,9 +38153,9 @@
 -  */
 -  nByte = (int)((char *)aHash - (char *)&aPgno[iLimit+1]);
 -  memset((void *)&aPgno[iLimit+1], 0, nByte);
-+/* Size of write ahead log header, including checksum. */
-+/* #define WAL_HDRSIZE 24 */
-+#define WAL_HDRSIZE 32
++SQLITE_PRIVATE int sqlite3pager_is_mj_pgno(Pager *pPager, Pgno pgno) {
++  return (PAGER_MJ_PGNO(pPager) == pgno) ? 1 : 0;
++}
  
 -#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
 -  /* Verify that the every entry in the mapping region is still reachable
@@ -4965,73 +38172,288 @@
 -    }
 -  }
 -#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
--}
-+/* WAL magic value. Either this value, or the same value with the least
-+** significant bit also set (WAL_MAGIC | 0x00000001) is stored in 32-bit
-+** big-endian format in the first 4 bytes of a WAL file.
-+**
-+** If the LSB is set, then the checksums for each frame within the WAL
-+** file are calculated by treating all data as an array of 32-bit 
-+** big-endian words. Otherwise, they are calculated by interpreting 
-+** all data as 32-bit little-endian words.
-+*/
-+#define WAL_MAGIC 0x377f0682
++SQLITE_PRIVATE sqlite3_file *sqlite3Pager_get_fd(Pager *pPager) {
++  return (isOpen(pPager->fd)) ? pPager->fd : NULL;
++}
++
++SQLITE_PRIVATE void sqlite3pager_sqlite3PagerSetCodec(
++  Pager *pPager,
++  void *(*xCodec)(void*,void*,Pgno,int),
++  void (*xCodecSizeChng)(void*,int,int),
++  void (*xCodecFree)(void*),
++  void *pCodec
++){
++  sqlite3PagerSetCodec(pPager, xCodec, xCodecSizeChng, xCodecFree, pCodec); 
++}
++
++SQLITE_PRIVATE void sqlite3pager_sqlite3PagerSetError( Pager *pPager, int error) {
++  pPager->errCode = error;
+ }
  
++#endif
++/* END SQLCIPHER */
++
++
++/************** End of pager.c ***********************************************/
++/************** Begin file wal.c *********************************************/
 +/*
-+** Return the offset of frame iFrame in the write-ahead log file, 
-+** assuming a database page size of szPage bytes. The offset returned
-+** is to the start of the write-ahead log frame-header.
++** 2010 February 1
++**
++** The author disclaims copyright to this source code.  In place of
++** a legal notice, here is a blessing:
++**
++**    May you do good and not evil.
++**    May you find forgiveness for yourself and forgive others.
++**    May you share freely, never taking more than you give.
++**
++*************************************************************************
++**
++** This file contains the implementation of a write-ahead log (WAL) used in 
++** "journal_mode=WAL" mode.
++**
++** WRITE-AHEAD LOG (WAL) FILE FORMAT
++**
++** A WAL file consists of a header followed by zero or more "frames".
++** Each frame records the revised content of a single page from the
++** database file.  All changes to the database are recorded by writing
++** frames into the WAL.  Transactions commit when a frame is written that
++** contains a commit marker.  A single WAL can and usually does record 
++** multiple transactions.  Periodically, the content of the WAL is
++** transferred back into the database file in an operation called a
++** "checkpoint".
++**
++** A single WAL file can be used multiple times.  In other words, the
++** WAL can fill up with frames and then be checkpointed and then new
++** frames can overwrite the old ones.  A WAL always grows from beginning
++** toward the end.  Checksums and counters attached to each frame are
++** used to determine which frames within the WAL are valid and which
++** are leftovers from prior checkpoints.
++**
++** The WAL header is 32 bytes in size and consists of the following eight
++** big-endian 32-bit unsigned integer values:
++**
++**     0: Magic number.  0x377f0682 or 0x377f0683
++**     4: File format version.  Currently 3007000
++**     8: Database page size.  Example: 1024
++**    12: Checkpoint sequence number
++**    16: Salt-1, random integer incremented with each checkpoint
++**    20: Salt-2, a different random integer changing with each ckpt
++**    24: Checksum-1 (first part of checksum for first 24 bytes of header).
++**    28: Checksum-2 (second part of checksum for first 24 bytes of header).
++**
++** Immediately following the wal-header are zero or more frames. Each
++** frame consists of a 24-byte frame-header followed by a <page-size> bytes
++** of page data. The frame-header is six big-endian 32-bit unsigned 
++** integer values, as follows:
++**
++**     0: Page number.
++**     4: For commit records, the size of the database image in pages 
++**        after the commit. For all other records, zero.
++**     8: Salt-1 (copied from the header)
++**    12: Salt-2 (copied from the header)
++**    16: Checksum-1.
++**    20: Checksum-2.
++**
++** A frame is considered valid if and only if the following conditions are
++** true:
++**
++**    (1) The salt-1 and salt-2 values in the frame-header match
++**        salt values in the wal-header
++**
++**    (2) The checksum values in the final 8 bytes of the frame-header
++**        exactly match the checksum computed consecutively on the
++**        WAL header and the first 8 bytes and the content of all frames
++**        up to and including the current frame.
++**
++** The checksum is computed using 32-bit big-endian integers if the
++** magic number in the first 4 bytes of the WAL is 0x377f0683 and it
++** is computed using little-endian if the magic number is 0x377f0682.
++** The checksum values are always stored in the frame header in a
++** big-endian format regardless of which byte order is used to compute
++** the checksum.  The checksum is computed by interpreting the input as
++** an even number of unsigned 32-bit integers: x[0] through x[N].  The
++** algorithm used for the checksum is as follows:
++** 
++**   for i from 0 to n-1 step 2:
++**     s0 += x[i] + s1;
++**     s1 += x[i+1] + s0;
++**   endfor
++**
++** Note that s0 and s1 are both weighted checksums using fibonacci weights
++** in reverse order (the largest fibonacci weight occurs on the first element
++** of the sequence being summed.)  The s1 value spans all 32-bit 
++** terms of the sequence whereas s0 omits the final term.
++**
++** On a checkpoint, the WAL is first VFS.xSync-ed, then valid content of the
++** WAL is transferred into the database, then the database is VFS.xSync-ed.
++** The VFS.xSync operations serve as write barriers - all writes launched
++** before the xSync must complete before any write that launches after the
++** xSync begins.
++**
++** After each checkpoint, the salt-1 value is incremented and the salt-2
++** value is randomized.  This prevents old and new frames in the WAL from
++** being considered valid at the same time and being checkpointing together
++** following a crash.
++**
++** READER ALGORITHM
++**
++** To read a page from the database (call it page number P), a reader
++** first checks the WAL to see if it contains page P.  If so, then the
++** last valid instance of page P that is a followed by a commit frame
++** or is a commit frame itself becomes the value read.  If the WAL
++** contains no copies of page P that are valid and which are a commit
++** frame or are followed by a commit frame, then page P is read from
++** the database file.
++**
++** To start a read transaction, the reader records the index of the last
++** valid frame in the WAL.  The reader uses this recorded "mxFrame" value
++** for all subsequent read operations.  New transactions can be appended
++** to the WAL, but as long as the reader uses its original mxFrame value
++** and ignores the newly appended content, it will see a consistent snapshot
++** of the database from a single point in time.  This technique allows
++** multiple concurrent readers to view different versions of the database
++** content simultaneously.
++**
++** The reader algorithm in the previous paragraphs works correctly, but 
++** because frames for page P can appear anywhere within the WAL, the
++** reader has to scan the entire WAL looking for page P frames.  If the
++** WAL is large (multiple megabytes is typical) that scan can be slow,
++** and read performance suffers.  To overcome this problem, a separate
++** data structure called the wal-index is maintained to expedite the
++** search for frames of a particular page.
++** 
++** WAL-INDEX FORMAT
++**
++** Conceptually, the wal-index is shared memory, though VFS implementations
++** might choose to implement the wal-index using a mmapped file.  Because
++** the wal-index is shared memory, SQLite does not support journal_mode=WAL 
++** on a network filesystem.  All users of the database must be able to
++** share memory.
++**
++** The wal-index is transient.  After a crash, the wal-index can (and should
++** be) reconstructed from the original WAL file.  In fact, the VFS is required
++** to either truncate or zero the header of the wal-index when the last
++** connection to it closes.  Because the wal-index is transient, it can
++** use an architecture-specific format; it does not have to be cross-platform.
++** Hence, unlike the database and WAL file formats which store all values
++** as big endian, the wal-index can store multi-byte values in the native
++** byte order of the host computer.
++**
++** The purpose of the wal-index is to answer this question quickly:  Given
++** a page number P and a maximum frame index M, return the index of the 
++** last frame in the wal before frame M for page P in the WAL, or return
++** NULL if there are no frames for page P in the WAL prior to M.
++**
++** The wal-index consists of a header region, followed by an one or
++** more index blocks.  
++**
++** The wal-index header contains the total number of frames within the WAL
++** in the mxFrame field.
++**
++** Each index block except for the first contains information on 
++** HASHTABLE_NPAGE frames. The first index block contains information on
++** HASHTABLE_NPAGE_ONE frames. The values of HASHTABLE_NPAGE_ONE and 
++** HASHTABLE_NPAGE are selected so that together the wal-index header and
++** first index block are the same size as all other index blocks in the
++** wal-index.
++**
++** Each index block contains two sections, a page-mapping that contains the
++** database page number associated with each wal frame, and a hash-table 
++** that allows readers to query an index block for a specific page number.
++** The page-mapping is an array of HASHTABLE_NPAGE (or HASHTABLE_NPAGE_ONE
++** for the first index block) 32-bit page numbers. The first entry in the 
++** first index-block contains the database page number corresponding to the
++** first frame in the WAL file. The first entry in the second index block
++** in the WAL file corresponds to the (HASHTABLE_NPAGE_ONE+1)th frame in
++** the log, and so on.
++**
++** The last index block in a wal-index usually contains less than the full
++** complement of HASHTABLE_NPAGE (or HASHTABLE_NPAGE_ONE) page-numbers,
++** depending on the contents of the WAL file. This does not change the
++** allocated size of the page-mapping array - the page-mapping array merely
++** contains unused entries.
++**
++** Even without using the hash table, the last frame for page P
++** can be found by scanning the page-mapping sections of each index block
++** starting with the last index block and moving toward the first, and
++** within each index block, starting at the end and moving toward the
++** beginning.  The first entry that equals P corresponds to the frame
++** holding the content for that page.
++**
++** The hash table consists of HASHTABLE_NSLOT 16-bit unsigned integers.
++** HASHTABLE_NSLOT = 2*HASHTABLE_NPAGE, and there is one entry in the
++** hash table for each page number in the mapping section, so the hash 
++** table is never more than half full.  The expected number of collisions 
++** prior to finding a match is 1.  Each entry of the hash table is an
++** 1-based index of an entry in the mapping section of the same
++** index block.   Let K be the 1-based index of the largest entry in
++** the mapping section.  (For index blocks other than the last, K will
++** always be exactly HASHTABLE_NPAGE (4096) and for the last index block
++** K will be (mxFrame%HASHTABLE_NPAGE).)  Unused slots of the hash table
++** contain a value of 0.
++**
++** To look for page P in the hash table, first compute a hash iKey on
++** P as follows:
++**
++**      iKey = (P * 383) % HASHTABLE_NSLOT
++**
++** Then start scanning entries of the hash table, starting with iKey
++** (wrapping around to the beginning when the end of the hash table is
++** reached) until an unused hash slot is found. Let the first unused slot
++** be at index iUnused.  (iUnused might be less than iKey if there was
++** wrap-around.) Because the hash table is never more than half full,
++** the search is guaranteed to eventually hit an unused entry.  Let 
++** iMax be the value between iKey and iUnused, closest to iUnused,
++** where aHash[iMax]==P.  If there is no iMax entry (if there exists
++** no hash slot such that aHash[i]==p) then page P is not in the
++** current index block.  Otherwise the iMax-th mapping entry of the
++** current index block corresponds to the last entry that references 
++** page P.
++**
++** A hash search begins with the last index block and moves toward the
++** first index block, looking for entries corresponding to page P.  On
++** average, only two or three slots in each index block need to be
++** examined in order to either find the last entry for page P, or to
++** establish that no such entry exists in the block.  Each index block
++** holds over 4000 entries.  So two or three index blocks are sufficient
++** to cover a typical 10 megabyte WAL file, assuming 1K pages.  8 or 10
++** comparisons (on average) suffice to either locate a frame in the
++** WAL or to establish that the frame does not exist in the WAL.  This
++** is much faster than scanning the entire 10MB WAL.
++**
++** Note that entries are added in order of increasing K.  Hence, one
++** reader might be using some value K0 and a second reader that started
++** at a later time (after additional transactions were added to the WAL
++** and to the wal-index) might be using a different value K1, where K1>K0.
++** Both readers can use the same hash table and mapping section to get
++** the correct result.  There may be entries in the hash table with
++** K>K0 but to the first reader, those entries will appear to be unused
++** slots in the hash table and so the first reader will get an answer as
++** if no values greater than K0 had ever been inserted into the hash table
++** in the first place - which is what reader one wants.  Meanwhile, the
++** second reader using K1 will see additional values that were inserted
++** later, which is exactly what reader two wants.  
++**
++** When a rollback occurs, the value of K is decreased. Hash table entries
++** that correspond to frames greater than the new K value are removed
++** from the hash table at this point.
 +*/
-+#define walFrameOffset(iFrame, szPage) (                               \
-+  WAL_HDRSIZE + ((iFrame)-1)*(i64)((szPage)+WAL_FRAME_HDRSIZE)         \
-+)
++#ifndef SQLITE_OMIT_WAL
++
  
  /*
 -** Set an entry in the wal-index that will map database page number
 -** pPage into WAL frame iFrame.
-+** An open write-ahead log file is represented by an instance of the
-+** following object.
++** Trace output macros
  */
 -static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
 -  int rc;                         /* Return code */
 -  u32 iZero = 0;                  /* One less than frame number of aPgno[1] */
 -  volatile u32 *aPgno = 0;        /* Page number array */
 -  volatile ht_slot *aHash = 0;    /* Hash table */
-+struct Wal {
-+  sqlite3_vfs *pVfs;         /* The VFS used to create pDbFd */
-+  sqlite3_file *pDbFd;       /* File handle for the database file */
-+  sqlite3_file *pWalFd;      /* File handle for WAL file */
-+  u32 iCallback;             /* Value to pass to log callback (or 0) */
-+  i64 mxWalSize;             /* Truncate WAL to this size upon reset */
-+  int nWiData;               /* Size of array apWiData */
-+  int szFirstBlock;          /* Size of first block written to WAL file */
-+  volatile u32 **apWiData;   /* Pointer to wal-index content in memory */
-+  u32 szPage;                /* Database page size */
-+  i16 readLock;              /* Which read lock is being held.  -1 for none */
-+  u8 syncFlags;              /* Flags to use to sync header writes */
-+  u8 exclusiveMode;          /* Non-zero if connection is in exclusive mode */
-+  u8 writeLock;              /* True if in a write transaction */
-+  u8 ckptLock;               /* True if holding a checkpoint lock */
-+  u8 readOnly;               /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */
-+  u8 truncateOnCommit;       /* True to truncate WAL file on commit */
-+  u8 syncHeader;             /* Fsync the WAL header if true */
-+  u8 padToSectorBoundary;    /* Pad transactions out to the next sector */
-+  WalIndexHdr hdr;           /* Wal-index header for current transaction */
-+  const char *zWalName;      /* Name of WAL file */
-+  u32 nCkpt;                 /* Checkpoint sequence counter in the wal-header */
-+#ifdef SQLITE_DEBUG
-+  u8 lockError;              /* True if a locking error has occurred */
-+#endif
-+};
- 
+-
 -  rc = walHashGet(pWal, walFramePage(iFrame), &aHash, &aPgno, &iZero);
-+/*
-+** Candidate values for Wal.exclusiveMode.
-+*/
-+#define WAL_NORMAL_MODE     0
-+#define WAL_EXCLUSIVE_MODE  1     
-+#define WAL_HEAPMEMORY_MODE 2
- 
+-
 -  /* Assuming the wal-index file was successfully mapped, populate the
 -  ** page number array and hash table entry.
 -  */
@@ -5039,29 +38461,18 @@
 -    int iKey;                     /* Hash table key */
 -    int idx;                      /* Value to write to hash-table slot */
 -    int nCollide;                 /* Number of hash collisions */
-+/*
-+** Possible values for WAL.readOnly
-+*/
-+#define WAL_RDWR        0    /* Normal read/write connection */
-+#define WAL_RDONLY      1    /* The WAL file is readonly */
-+#define WAL_SHM_RDONLY  2    /* The SHM file is readonly */
- 
+-
 -    idx = iFrame - iZero;
 -    assert( idx <= HASHTABLE_NSLOT/2 + 1 );
 -    
 -    /* If this is the first entry to be added to this hash-table, zero the
--    ** entire hash table and aPgno[] array before proceding. 
+-    ** entire hash table and aPgno[] array before proceeding. 
 -    */
 -    if( idx==1 ){
 -      int nByte = (int)((u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]);
 -      memset((void*)&aPgno[1], 0, nByte);
 -    }
-+/*
-+** Each page of the wal-index mapping contains a hash-table made up of
-+** an array of HASHTABLE_NSLOT elements of the following type.
-+*/
-+typedef u16 ht_slot;
- 
+-
 -    /* If the entry in aPgno[] is already set, then the previous writer
 -    ** must have exited unexpectedly in the middle of a transaction (after
 -    ** writing one or more dirty pages to the WAL to free up memory). 
@@ -5072,33 +38483,7 @@
 -      walCleanupHash(pWal);
 -      assert( !aPgno[idx] );
 -    }
-+/*
-+** This structure is used to implement an iterator that loops through
-+** all frames in the WAL in database page order. Where two or more frames
-+** correspond to the same database page, the iterator visits only the 
-+** frame most recently written to the WAL (in other words, the frame with
-+** the largest index).
-+**
-+** The internals of this structure are only accessed by:
-+**
-+**   walIteratorInit() - Create a new iterator,
-+**   walIteratorNext() - Step an iterator,
-+**   walIteratorFree() - Free an iterator.
-+**
-+** This functionality is used by the checkpoint code (see walCheckpoint()).
-+*/
-+struct WalIterator {
-+  int iPrior;                     /* Last result returned from the iterator */
-+  int nSegment;                   /* Number of entries in aSegment[] */
-+  struct WalSegment {
-+    int iNext;                    /* Next slot in aIndex[] not yet returned */
-+    ht_slot *aIndex;              /* i0, i1, i2... such that aPgno[iN] ascend */
-+    u32 *aPgno;                   /* Array of page numbers. */
-+    int nEntry;                   /* Nr. of entries in aPgno[] and aIndex[] */
-+    int iZero;                    /* Frame number associated with aPgno[0] */
-+  } aSegment[1];                  /* One for every 32KB page in the wal-index */
-+};
- 
+-
 -    /* Write the aPgno[] array entry and the hash-table slot. */
 -    nCollide = idx;
 -    for(iKey=walHash(iPage); aHash[iKey]; iKey=walNextHash(iKey)){
@@ -5106,18 +38491,7 @@
 -    }
 -    aPgno[idx] = iPage;
 -    aHash[iKey] = (ht_slot)idx;
-+/*
-+** Define the parameters of the hash tables in the wal-index file. There
-+** is a hash-table following every HASHTABLE_NPAGE page numbers in the
-+** wal-index.
-+**
-+** Changing any of these constants will alter the wal-index format and
-+** create incompatibilities.
-+*/
-+#define HASHTABLE_NPAGE      4096                 /* Must be power of 2 */
-+#define HASHTABLE_HASH_1     383                  /* Should be prime */
-+#define HASHTABLE_NSLOT      (HASHTABLE_NPAGE*2)  /* Must be a power of 2 */
- 
+-
 -#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
 -    /* Verify that the number of entries in the hash table exactly equals
 -    ** the number of entries in the mapping region.
@@ -5128,13 +38502,7 @@
 -      for(i=0; i<HASHTABLE_NSLOT; i++){ if( aHash[i] ) nEntry++; }
 -      assert( nEntry==idx );
 -    }
-+/* 
-+** The block of page numbers associated with the first hash-table in a
-+** wal-index is smaller than usual. This is so that there is a complete
-+** hash-table on each aligned 32KB page of the wal-index.
-+*/
-+#define HASHTABLE_NPAGE_ONE  (HASHTABLE_NPAGE - (WALINDEX_HDR_SIZE/sizeof(u32)))
- 
+-
 -    /* Verify that the every entry in the mapping region is reachable
 -    ** via the hash table.  This turns out to be a really, really expensive
 -    ** thing to check, so only do this occasionally - not on every
@@ -5148,78 +38516,40 @@
 -        }
 -        assert( aHash[iKey]==i );
 -      }
-+/* The wal-index is divided into pages of WALINDEX_PGSZ bytes each. */
-+#define WALINDEX_PGSZ   (                                         \
-+    sizeof(ht_slot)*HASHTABLE_NSLOT + HASHTABLE_NPAGE*sizeof(u32) \
-+)
-+
-+/*
-+** Obtain a pointer to the iPage'th page of the wal-index. The wal-index
-+** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are
-+** numbered from zero.
-+**
-+** If this call is successful, *ppPage is set to point to the wal-index
-+** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs,
-+** then an SQLite error code is returned and *ppPage is set to 0.
-+*/
-+static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
-+  int rc = SQLITE_OK;
-+
-+  /* Enlarge the pWal->apWiData[] array if required */
-+  if( pWal->nWiData<=iPage ){
-+    int nByte = sizeof(u32*)*(iPage+1);
-+    volatile u32 **apNew;
-+    apNew = (volatile u32 **)sqlite3_realloc((void *)pWal->apWiData, nByte);
-+    if( !apNew ){
-+      *ppPage = 0;
-+      return SQLITE_NOMEM;
-     }
+-    }
 -#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
-+    memset((void*)&apNew[pWal->nWiData], 0,
-+           sizeof(u32*)*(iPage+1-pWal->nWiData));
-+    pWal->apWiData = apNew;
-+    pWal->nWiData = iPage+1;
-   }
- 
-+  /* Request a pointer to the required page from the VFS */
-+  if( pWal->apWiData[iPage]==0 ){
-+    if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
-+      pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ);
-+      if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM;
-+    }else{
-+      rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, 
-+          pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
-+      );
-+      if( rc==SQLITE_READONLY ){
-+        pWal->readOnly |= WAL_SHM_RDONLY;
-+        rc = SQLITE_OK;
-+      }
-+    }
-+  }
- 
-+  *ppPage = pWal->apWiData[iPage];
-+  assert( iPage==0 || *ppPage || rc!=SQLITE_OK );
-   return rc;
- }
- 
-+/*
-+** Return a pointer to the WalCkptInfo structure in the wal-index.
-+*/
-+static volatile WalCkptInfo *walCkptInfo(Wal *pWal){
-+  assert( pWal->nWiData>0 && pWal->apWiData[0] );
-+  return (volatile WalCkptInfo*)&(pWal->apWiData[0][sizeof(WalIndexHdr)/2]);
-+}
+-  }
+-
+-
+-  return rc;
+-}
+-
++#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
++SQLITE_PRIVATE int sqlite3WalTrace = 0;
++# define WALTRACE(X)  if(sqlite3WalTrace) sqlite3DebugPrintf X
++#else
++# define WALTRACE(X)
++#endif
  
  /*
 -** Recover the wal-index by reading the write-ahead log file. 
--**
++** The maximum (and only) versions of the wal and wal-index formats
++** that may be interpreted by this version of SQLite.
+ **
 -** This routine first tries to establish an exclusive lock on the
 -** wal-index to prevent other threads/processes from doing anything
 -** with the WAL or wal-index while recovery is running.  The
 -** WAL_RECOVER_LOCK is also held so that other threads will know
 -** that this thread is running recovery.  If unable to establish
 -** the necessary locks, this routine returns SQLITE_BUSY.
-+** Return a pointer to the WalIndexHdr structure in the wal-index.
++** If a client begins recovering a WAL file and finds that (a) the checksum
++** values in the wal-header are correct and (b) the version field is not
++** WAL_MAX_VERSION, recovery fails and SQLite returns SQLITE_CANTOPEN.
++**
++** Similarly, if a client successfully reads a wal-index header (i.e. the 
++** checksum test is successful) and finds that the version field is not
++** WALINDEX_MAX_VERSION, then no read-transaction is opened and SQLite
++** returns SQLITE_CANTOPEN.
  */
 -static int walIndexRecover(Wal *pWal){
 -  int rc;                         /* Return Code */
@@ -5227,11 +38557,7 @@
 -  u32 aFrameCksum[2] = {0, 0};
 -  int iLock;                      /* Lock offset to lock for checkpoint */
 -  int nLock;                      /* Number of locks to hold */
-+static volatile WalIndexHdr *walIndexHdr(Wal *pWal){
-+  assert( pWal->nWiData>0 && pWal->apWiData[0] );
-+  return (volatile WalIndexHdr*)pWal->apWiData[0];
-+}
- 
+-
 -  /* Obtain an exclusive lock on all byte in the locking range not already
 -  ** locked by the caller. The caller is guaranteed to have locked the
 -  ** WAL_WRITE_LOCK byte, and may have also locked the WAL_CKPT_LOCK byte.
@@ -5244,54 +38570,19 @@
 -  assert( pWal->writeLock );
 -  iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock;
 -  nLock = SQLITE_SHM_NLOCK - iLock;
--  rc = walLockExclusive(pWal, iLock, nLock);
+-  rc = walLockExclusive(pWal, iLock, nLock, 0);
 -  if( rc ){
 -    return rc;
 -  }
 -  WALTRACE(("WAL%p: recovery begin...\n", pWal));
-+/*
-+** The argument to this macro must be of type u32. On a little-endian
-+** architecture, it returns the u32 value that results from interpreting
-+** the 4 bytes as a big-endian value. On a big-endian architecture, it
-+** returns the value that would be produced by intepreting the 4 bytes
-+** of the input value as a little-endian integer.
-+*/
-+#define BYTESWAP32(x) ( \
-+    (((x)&0x000000FF)<<24) + (((x)&0x0000FF00)<<8)  \
-+  + (((x)&0x00FF0000)>>8)  + (((x)&0xFF000000)>>24) \
-+)
- 
+-
 -  memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
-+/*
-+** Generate or extend an 8 byte checksum based on the data in 
-+** array aByte[] and the initial values of aIn[0] and aIn[1] (or
-+** initial values of 0 and 0 if aIn==NULL).
-+**
-+** The checksum is written back into aOut[] before returning.
-+**
-+** nByte must be a positive multiple of 8.
-+*/
-+static void walChecksumBytes(
-+  int nativeCksum, /* True for native byte-order, false for non-native */
-+  u8 *a,           /* Content to be checksummed */
-+  int nByte,       /* Bytes of content in a[].  Must be a multiple of 8. */
-+  const u32 *aIn,  /* Initial checksum value input */
-+  u32 *aOut        /* OUT: Final checksum value output */
-+){
-+  u32 s1, s2;
-+  u32 *aData = (u32 *)a;
-+  u32 *aEnd = (u32 *)&a[nByte];
- 
+-
 -  rc = sqlite3OsFileSize(pWal->pWalFd, &nSize);
 -  if( rc!=SQLITE_OK ){
 -    goto recovery_error;
-+  if( aIn ){
-+    s1 = aIn[0];
-+    s2 = aIn[1];
-+  }else{
-+    s1 = s2 = 0;
-   }
- 
+-  }
+-
 -  if( nSize>WAL_HDRSIZE ){
 -    u8 aBuf[WAL_HDRSIZE];         /* Buffer to load WAL header into */
 -    u8 *aFrame = 0;               /* Malloc'd buffer to load entire frame */
@@ -5349,7 +38640,7 @@
 -
 -    /* Malloc a buffer to read frames into. */
 -    szFrame = szPage + WAL_FRAME_HDRSIZE;
--    aFrame = (u8 *)sqlite3_malloc(szFrame);
+-    aFrame = (u8 *)sqlite3_malloc64(szFrame);
 -    if( !aFrame ){
 -      rc = SQLITE_NOMEM;
 -      goto recovery_error;
@@ -5382,22 +38673,11 @@
 -        aFrameCksum[1] = pWal->hdr.aFrameCksum[1];
 -      }
 -    }
-+  assert( nByte>=8 );
-+  assert( (nByte&0x00000007)==0 );
- 
+-
 -    sqlite3_free(aFrame);
-+  if( nativeCksum ){
-+    do {
-+      s1 += *aData++ + s2;
-+      s2 += *aData++ + s1;
-+    }while( aData<aEnd );
-+  }else{
-+    do {
-+      s1 += BYTESWAP32(aData[0]) + s2;
-+      s2 += BYTESWAP32(aData[1]) + s1;
-+      aData += 2;
-+    }while( aData<aEnd );
-   }
+-  }
++#define WAL_MAX_VERSION      3007000
++#define WALINDEX_MAX_VERSION 3007000
  
 -finished:
 -  if( rc==SQLITE_OK ){
@@ -5406,7 +38686,17 @@
 -    pWal->hdr.aFrameCksum[0] = aFrameCksum[0];
 -    pWal->hdr.aFrameCksum[1] = aFrameCksum[1];
 -    walIndexWriteHdr(pWal);
--
++/*
++** Indices of various locking bytes.   WAL_NREADER is the number
++** of available reader locks and should be at least 3.
++*/
++#define WAL_WRITE_LOCK         0
++#define WAL_ALL_BUT_WRITE      1
++#define WAL_CKPT_LOCK          1
++#define WAL_RECOVER_LOCK       2
++#define WAL_READ_LOCK(I)       (3+(I))
++#define WAL_NREADER            (SQLITE_SHM_NLOCK-3)
+ 
 -    /* Reset the checkpoint-header. This is safe because this thread is 
 -    ** currently holding locks that exclude all other readers, writers and
 -    ** checkpointers.
@@ -5416,9 +38706,6 @@
 -    pInfo->aReadMark[0] = 0;
 -    for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
 -    if( pWal->hdr.mxFrame ) pInfo->aReadMark[1] = pWal->hdr.mxFrame;
-+  aOut[0] = s1;
-+  aOut[1] = s2;
-+}
  
 -    /* If more than one frame was recovered from the log file, report an
 -    ** event via sqlite3_log(). This is to help with identifying performance
@@ -5431,22 +38718,28 @@
 -          pWal->hdr.mxFrame, pWal->zWalName
 -      );
 -    }
-+static void walShmBarrier(Wal *pWal){
-+  if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){
-+    sqlite3OsShmBarrier(pWal->pDbFd);
-   }
--
+-  }
++/* Object declarations */
++typedef struct WalIndexHdr WalIndexHdr;
++typedef struct WalIterator WalIterator;
++typedef struct WalCkptInfo WalCkptInfo;
+ 
 -recovery_error:
 -  WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok"));
 -  walUnlockExclusive(pWal, iLock, nLock);
 -  return rc;
- }
+-}
  
  /*
 -** Close an open wal-index.
-+** Write the header information in pWal->hdr into the wal-index.
++** The following object holds a copy of the wal-index header content.
 +**
-+** The checksum on pWal->hdr is updated before it is written.
++** The actual header in the wal-index consists of two copies of this
++** object.
++**
++** The szPage value can be any power of 2 between 512 and 32768, inclusive.
++** Or it can be 1 to represent a 65536-byte page.  The latter case was
++** added in 3.7.1 when support for 64K pages was added.  
  */
 -static void walIndexClose(Wal *pWal, int isDelete){
 -  if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
@@ -5458,44 +38751,81 @@
 -  }else{
 -    sqlite3OsShmUnmap(pWal->pDbFd, isDelete);
 -  }
-+static void walIndexWriteHdr(Wal *pWal){
-+  volatile WalIndexHdr *aHdr = walIndexHdr(pWal);
-+  const int nCksum = offsetof(WalIndexHdr, aCksum);
-+
-+  assert( pWal->writeLock );
-+  pWal->hdr.isInit = 1;
-+  pWal->hdr.iVersion = WALINDEX_MAX_VERSION;
-+  walChecksumBytes(1, (u8*)&pWal->hdr, nCksum, 0, pWal->hdr.aCksum);
-+  memcpy((void *)&aHdr[1], (void *)&pWal->hdr, sizeof(WalIndexHdr));
-+  walShmBarrier(pWal);
-+  memcpy((void *)&aHdr[0], (void *)&pWal->hdr, sizeof(WalIndexHdr));
- }
+-}
++struct WalIndexHdr {
++  u32 iVersion;                   /* Wal-index version */
++  u32 unused;                     /* Unused (padding) field */
++  u32 iChange;                    /* Counter incremented each transaction */
++  u8 isInit;                      /* 1 when initialized */
++  u8 bigEndCksum;                 /* True if checksums in WAL are big-endian */
++  u16 szPage;                     /* Database page size in bytes. 1==64K */
++  u32 mxFrame;                    /* Index of last valid frame in the WAL */
++  u32 nPage;                      /* Size of database in pages */
++  u32 aFrameCksum[2];             /* Checksum of last frame in log */
++  u32 aSalt[2];                   /* Two salt values copied from WAL header */
++  u32 aCksum[2];                  /* Checksum over all prior fields */
++};
  
 -/* 
 -** Open a connection to the WAL file zWalName. The database file must 
 -** already be opened on connection pDbFd. The buffer that zWalName points
 -** to must remain valid for the lifetime of the returned Wal* handle.
--**
++/*
++** A copy of the following object occurs in the wal-index immediately
++** following the second copy of the WalIndexHdr.  This object stores
++** information used by checkpoint.
+ **
 -** A SHARED lock should be held on the database file when this function
 -** is called. The purpose of this SHARED lock is to prevent any other
 -** client from unlinking the WAL or wal-index file. If another process
 -** were to do this just after this client opened one of these files, the
 -** system would be badly broken.
-+/*
-+** This function encodes a single frame header and writes it to a buffer
-+** supplied by the caller. A frame-header is made up of a series of 
-+** 4-byte big-endian integers, as follows:
++** nBackfill is the number of frames in the WAL that have been written
++** back into the database. (We call the act of moving content from WAL to
++** database "backfilling".)  The nBackfill number is never greater than
++** WalIndexHdr.mxFrame.  nBackfill can only be increased by threads
++** holding the WAL_CKPT_LOCK lock (which includes a recovery thread).
++** However, a WAL_WRITE_LOCK thread can move the value of nBackfill from
++** mxFrame back to zero when the WAL is reset.
  **
 -** If the log file is successfully opened, SQLITE_OK is returned and 
 -** *ppWal is set to point to a new WAL handle. If an error occurs,
 -** an SQLite error code is returned and *ppWal is left unmodified.
-+**     0: Page number.
-+**     4: For commit records, the size of the database image in pages 
-+**        after the commit. For all other records, zero.
-+**     8: Salt-1 (copied from the wal-header)
-+**    12: Salt-2 (copied from the wal-header)
-+**    16: Checksum-1.
-+**    20: Checksum-2.
++** There is one entry in aReadMark[] for each reader lock.  If a reader
++** holds read-lock K, then the value in aReadMark[K] is no greater than
++** the mxFrame for that reader.  The value READMARK_NOT_USED (0xffffffff)
++** for any aReadMark[] means that entry is unused.  aReadMark[0] is 
++** a special case; its value is never used and it exists as a place-holder
++** to avoid having to offset aReadMark[] indexs by one.  Readers holding
++** WAL_READ_LOCK(0) always ignore the entire WAL and read all content
++** directly from the database.
++**
++** The value of aReadMark[K] may only be changed by a thread that
++** is holding an exclusive lock on WAL_READ_LOCK(K).  Thus, the value of
++** aReadMark[K] cannot changed while there is a reader is using that mark
++** since the reader will be holding a shared lock on WAL_READ_LOCK(K).
++**
++** The checkpointer may only transfer frames from WAL to database where
++** the frame numbers are less than or equal to every aReadMark[] that is
++** in use (that is, every aReadMark[j] for which there is a corresponding
++** WAL_READ_LOCK(j)).  New readers (usually) pick the aReadMark[] with the
++** largest value and will increase an unused aReadMark[] to mxFrame if there
++** is not already an aReadMark[] equal to mxFrame.  The exception to the
++** previous sentence is when nBackfill equals mxFrame (meaning that everything
++** in the WAL has been backfilled into the database) then new readers
++** will choose aReadMark[0] which has value 0 and hence such reader will
++** get all their all content directly from the database file and ignore 
++** the WAL.
++**
++** Writers normally append new frames to the end of the WAL.  However,
++** if nBackfill equals mxFrame (meaning that all WAL content has been
++** written back into the database) and if no readers are using the WAL
++** (in other words, if there are no WAL_READ_LOCK(i) where i>0) then
++** the writer will first "reset" the WAL back to the beginning and start
++** writing new content beginning at frame 1.
++**
++** We assume that 32-bit loads are atomic and so no locks are needed in
++** order to read from any aReadMark[] entries.
  */
 -SQLITE_PRIVATE int sqlite3WalOpen(
 -  sqlite3_vfs *pVfs,              /* vfs module to open wal and wal-index */
@@ -5504,28 +38834,18 @@
 -  int bNoShm,                     /* True to run in heap-memory mode */
 -  i64 mxWalSize,                  /* Truncate WAL to this size on reset */
 -  Wal **ppWal                     /* OUT: Allocated Wal handle */
-+static void walEncodeFrame(
-+  Wal *pWal,                      /* The write-ahead log */
-+  u32 iPage,                      /* Database page number for frame */
-+  u32 nTruncate,                  /* New db size (or 0 for non-commit frames) */
-+  u8 *aData,                      /* Pointer to page data */
-+  u8 *aFrame                      /* OUT: Write encoded frame here */
- ){
+-){
 -  int rc;                         /* Return Code */
 -  Wal *pRet;                      /* Object to allocate and return */
 -  int flags;                      /* Flags passed to OsOpen() */
-+  int nativeCksum;                /* True for native byte-order checksums */
-+  u32 *aCksum = pWal->hdr.aFrameCksum;
-+  assert( WAL_FRAME_HDRSIZE==24 );
-+  sqlite3Put4byte(&aFrame[0], iPage);
-+  sqlite3Put4byte(&aFrame[4], nTruncate);
-+  memcpy(&aFrame[8], pWal->hdr.aSalt, 8);
- 
+-
 -  assert( zWalName && zWalName[0] );
 -  assert( pDbFd );
-+  nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
-+  walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
-+  walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
++struct WalCkptInfo {
++  u32 nBackfill;                  /* Number of WAL frames backfilled into DB */
++  u32 aReadMark[WAL_NREADER];     /* Reader marks */
++};
++#define READMARK_NOT_USED  0xffffffff
  
 -  /* In the amalgamation, the os_unix.c and os_win.c source files come before
 -  ** this source file.  Verify that the #defines of the locking byte offsets
@@ -5537,38 +38857,24 @@
 -#ifdef UNIX_SHM_BASE
 -  assert( UNIX_SHM_BASE==WALINDEX_LOCK_OFFSET );
 -#endif
-+  sqlite3Put4byte(&aFrame[16], aCksum[0]);
-+  sqlite3Put4byte(&aFrame[20], aCksum[1]);
-+}
  
-+/*
-+** Check to see if the frame with header in aFrame[] and content
-+** in aData[] is valid.  If it is a valid frame, fill *piPage and
-+** *pnTruncate and return true.  Return if the frame is not valid.
++/* A block of WALINDEX_LOCK_RESERVED bytes beginning at
++** WALINDEX_LOCK_OFFSET is reserved for locks. Since some systems
++** only support mandatory file-locks, we do not read or write data
++** from the region of the file on which locks are applied.
 +*/
-+static int walDecodeFrame(
-+  Wal *pWal,                      /* The write-ahead log */
-+  u32 *piPage,                    /* OUT: Database page number for frame */
-+  u32 *pnTruncate,                /* OUT: New db size (or 0 if not commit) */
-+  u8 *aData,                      /* Pointer to page data (for checksum) */
-+  u8 *aFrame                      /* Frame data */
-+){
-+  int nativeCksum;                /* True for native byte-order checksums */
-+  u32 *aCksum = pWal->hdr.aFrameCksum;
-+  u32 pgno;                       /* Page number of the frame */
-+  assert( WAL_FRAME_HDRSIZE==24 );
++#define WALINDEX_LOCK_OFFSET   (sizeof(WalIndexHdr)*2 + sizeof(WalCkptInfo))
++#define WALINDEX_LOCK_RESERVED 16
++#define WALINDEX_HDR_SIZE      (WALINDEX_LOCK_OFFSET+WALINDEX_LOCK_RESERVED)
  
 -  /* Allocate an instance of struct Wal to return. */
 -  *ppWal = 0;
 -  pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile);
 -  if( !pRet ){
 -    return SQLITE_NOMEM;
-+  /* A frame is only valid if the salt values in the frame-header
-+  ** match the salt values in the wal-header. 
-+  */
-+  if( memcmp(&pWal->hdr.aSalt, &aFrame[8], 8)!=0 ){
-+    return 0;
-   }
+-  }
++/* Size of header before each frame in wal */
++#define WAL_FRAME_HDRSIZE 24
  
 -  pRet->pVfs = pVfs;
 -  pRet->pWalFd = (sqlite3_file *)&pRet[1];
@@ -5579,18 +38885,26 @@
 -  pRet->syncHeader = 1;
 -  pRet->padToSectorBoundary = 1;
 -  pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE);
--
++/* Size of write ahead log header, including checksum. */
++/* #define WAL_HDRSIZE 24 */
++#define WAL_HDRSIZE 32
+ 
 -  /* Open file handle on the write-ahead log file. */
 -  flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL);
 -  rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags);
 -  if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){
 -    pRet->readOnly = WAL_RDONLY;
-+  /* A frame is only valid if the page number is creater than zero.
-+  */
-+  pgno = sqlite3Get4byte(&aFrame[0]);
-+  if( pgno==0 ){
-+    return 0;
-   }
+-  }
++/* WAL magic value. Either this value, or the same value with the least
++** significant bit also set (WAL_MAGIC | 0x00000001) is stored in 32-bit
++** big-endian format in the first 4 bytes of a WAL file.
++**
++** If the LSB is set, then the checksums for each frame within the WAL
++** file are calculated by treating all data as an array of 32-bit 
++** big-endian words. Otherwise, they are calculated by interpreting 
++** all data as 32-bit little-endian words.
++*/
++#define WAL_MAGIC 0x377f0682
  
 -  if( rc!=SQLITE_OK ){
 -    walIndexClose(pRet, 0);
@@ -5604,55 +38918,52 @@
 -    }
 -    *ppWal = pRet;
 -    WALTRACE(("WAL%d: opened\n", pRet));
-+  /* A frame is only valid if a checksum of the WAL header,
-+  ** all prior frams, the first 16 bytes of this frame-header, 
-+  ** and the frame-data matches the checksum in the last 8 
-+  ** bytes of this frame-header.
-+  */
-+  nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
-+  walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
-+  walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
-+  if( aCksum[0]!=sqlite3Get4byte(&aFrame[16]) 
-+   || aCksum[1]!=sqlite3Get4byte(&aFrame[20]) 
-+  ){
-+    /* Checksum failed. */
-+    return 0;
-   }
+-  }
 -  return rc;
-+
-+  /* If we reach this point, the frame is valid.  Return the page number
-+  ** and the new database size.
-+  */
-+  *piPage = pgno;
-+  *pnTruncate = sqlite3Get4byte(&aFrame[4]);
-+  return 1;
- }
+-}
++/*
++** Return the offset of frame iFrame in the write-ahead log file, 
++** assuming a database page size of szPage bytes. The offset returned
++** is to the start of the write-ahead log frame-header.
++*/
++#define walFrameOffset(iFrame, szPage) (                               \
++  WAL_HDRSIZE + ((iFrame)-1)*(i64)((szPage)+WAL_FRAME_HDRSIZE)         \
++)
  
-+
-+#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
  /*
 -** Change the size to which the WAL file is trucated on each reset.
-+** Names of locks.  This routine is used to provide debugging output and is not
-+** a part of an ordinary build.
++** An open write-ahead log file is represented by an instance of the
++** following object.
  */
 -SQLITE_PRIVATE void sqlite3WalLimit(Wal *pWal, i64 iLimit){
 -  if( pWal ) pWal->mxWalSize = iLimit;
-+static const char *walLockName(int lockIdx){
-+  if( lockIdx==WAL_WRITE_LOCK ){
-+    return "WRITE-LOCK";
-+  }else if( lockIdx==WAL_CKPT_LOCK ){
-+    return "CKPT-LOCK";
-+  }else if( lockIdx==WAL_RECOVER_LOCK ){
-+    return "RECOVER-LOCK";
-+  }else{
-+    static char zName[15];
-+    sqlite3_snprintf(sizeof(zName), zName, "READ-LOCK[%d]",
-+                     lockIdx-WAL_READ_LOCK(0));
-+    return zName;
-+  }
- }
-+#endif /*defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */
-+    
+-}
++struct Wal {
++  sqlite3_vfs *pVfs;         /* The VFS used to create pDbFd */
++  sqlite3_file *pDbFd;       /* File handle for the database file */
++  sqlite3_file *pWalFd;      /* File handle for WAL file */
++  u32 iCallback;             /* Value to pass to log callback (or 0) */
++  i64 mxWalSize;             /* Truncate WAL to this size upon reset */
++  int nWiData;               /* Size of array apWiData */
++  int szFirstBlock;          /* Size of first block written to WAL file */
++  volatile u32 **apWiData;   /* Pointer to wal-index content in memory */
++  u32 szPage;                /* Database page size */
++  i16 readLock;              /* Which read lock is being held.  -1 for none */
++  u8 syncFlags;              /* Flags to use to sync header writes */
++  u8 exclusiveMode;          /* Non-zero if connection is in exclusive mode */
++  u8 writeLock;              /* True if in a write transaction */
++  u8 ckptLock;               /* True if holding a checkpoint lock */
++  u8 readOnly;               /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */
++  u8 truncateOnCommit;       /* True to truncate WAL file on commit */
++  u8 syncHeader;             /* Fsync the WAL header if true */
++  u8 padToSectorBoundary;    /* Pad transactions out to the next sector */
++  WalIndexHdr hdr;           /* Wal-index header for current transaction */
++  const char *zWalName;      /* Name of WAL file */
++  u32 nCkpt;                 /* Checkpoint sequence counter in the wal-header */
++#ifdef SQLITE_DEBUG
++  u8 lockError;              /* True if a locking error has occurred */
++#endif
++};
  
  /*
 -** Find the smallest page number out of all pages held in the WAL that
@@ -5660,13 +38971,10 @@
 -** same WalIterator object.   Write into *piFrame the frame index where
 -** that page was last written into the WAL.  Write into *piPage the page
 -** number.
-+** Set or release locks on the WAL.  Locks are either shared or exclusive.
-+** A lock cannot be moved directly between shared and exclusive - it must go
-+** through the unlocked state first.
- **
+-**
 -** Return 0 on success.  If there are no pages in the WAL with a page
 -** number larger than *piPage, then return 1.
-+** In locking_mode=EXCLUSIVE, all of these routines become no-ops.
++** Candidate values for Wal.exclusiveMode.
  */
 -static int walIteratorNext(
 -  WalIterator *p,               /* Iterator */
@@ -5676,7 +38984,10 @@
 -  u32 iMin;                     /* Result pgno must be greater than iMin */
 -  u32 iRet = 0xFFFFFFFF;        /* 0xffffffff is never a valid page number */
 -  int i;                        /* For looping through segments */
--
++#define WAL_NORMAL_MODE     0
++#define WAL_EXCLUSIVE_MODE  1     
++#define WAL_HEAPMEMORY_MODE 2
+ 
 -  iMin = p->iPrior;
 -  assert( iMin<0xffffffff );
 -  for(i=p->nSegment-1; i>=0; i--){
@@ -5693,42 +39004,21 @@
 -      pSegment->iNext++;
 -    }
 -  }
--
++/*
++** Possible values for WAL.readOnly
++*/
++#define WAL_RDWR        0    /* Normal read/write connection */
++#define WAL_RDONLY      1    /* The WAL file is readonly */
++#define WAL_SHM_RDONLY  2    /* The SHM file is readonly */
+ 
 -  *piPage = p->iPrior = iRet;
 -  return (iRet==0xFFFFFFFF);
-+static int walLockShared(Wal *pWal, int lockIdx){
-+  int rc;
-+  if( pWal->exclusiveMode ) return SQLITE_OK;
-+  rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
-+                        SQLITE_SHM_LOCK | SQLITE_SHM_SHARED);
-+  WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal,
-+            walLockName(lockIdx), rc ? "failed" : "ok"));
-+  VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
-+  return rc;
-+}
-+static void walUnlockShared(Wal *pWal, int lockIdx){
-+  if( pWal->exclusiveMode ) return;
-+  (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
-+                         SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED);
-+  WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx)));
-+}
-+static int walLockExclusive(Wal *pWal, int lockIdx, int n){
-+  int rc;
-+  if( pWal->exclusiveMode ) return SQLITE_OK;
-+  rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
-+                        SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE);
-+  WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal,
-+            walLockName(lockIdx), n, rc ? "failed" : "ok"));
-+  VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
-+  return rc;
-+}
-+static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){
-+  if( pWal->exclusiveMode ) return;
-+  (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
-+                         SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE);
-+  WALTRACE(("WAL%p: release EXCLUSIVE-%s cnt=%d\n", pWal,
-+             walLockName(lockIdx), n));
- }
+-}
++/*
++** Each page of the wal-index mapping contains a hash-table made up of
++** an array of HASHTABLE_NSLOT elements of the following type.
++*/
++typedef u16 ht_slot;
  
  /*
 -** This function merges two sorted lists into a single sorted list.
@@ -5736,46 +39026,75 @@
 -** aLeft[] and aRight[] are arrays of indices.  The sort key is
 -** aContent[aLeft[]] and aContent[aRight[]].  Upon entry, the following
 -** is guaranteed for all J<K:
--**
++** This structure is used to implement an iterator that loops through
++** all frames in the WAL in database page order. Where two or more frames
++** correspond to the same database page, the iterator visits only the 
++** frame most recently written to the WAL (in other words, the frame with
++** the largest index).
+ **
 -**        aContent[aLeft[J]] < aContent[aLeft[K]]
 -**        aContent[aRight[J]] < aContent[aRight[K]]
--**
++** The internals of this structure are only accessed by:
+ **
 -** This routine overwrites aRight[] with a new (probably longer) sequence
 -** of indices such that the aRight[] contains every index that appears in
 -** either aLeft[] or the old aRight[] and such that the second condition
 -** above is still met.
--**
++**   walIteratorInit() - Create a new iterator,
++**   walIteratorNext() - Step an iterator,
++**   walIteratorFree() - Free an iterator.
+ **
 -** The aContent[aLeft[X]] values will be unique for all X.  And the
 -** aContent[aRight[X]] values will be unique too.  But there might be
 -** one or more combinations of X and Y such that
-+** Compute a hash on a page number.  The resulting hash value must land
-+** between 0 and (HASHTABLE_NSLOT-1).  The walHashNext() function advances
-+** the hash to the next value in the event of a collision.
++** This functionality is used by the checkpoint code (see walCheckpoint()).
 +*/
-+static int walHash(u32 iPage){
-+  assert( iPage>0 );
-+  assert( (HASHTABLE_NSLOT & (HASHTABLE_NSLOT-1))==0 );
-+  return (iPage*HASHTABLE_HASH_1) & (HASHTABLE_NSLOT-1);
-+}
-+static int walNextHash(int iPriorHash){
-+  return (iPriorHash+1)&(HASHTABLE_NSLOT-1);
-+}
++struct WalIterator {
++  int iPrior;                     /* Last result returned from the iterator */
++  int nSegment;                   /* Number of entries in aSegment[] */
++  struct WalSegment {
++    int iNext;                    /* Next slot in aIndex[] not yet returned */
++    ht_slot *aIndex;              /* i0, i1, i2... such that aPgno[iN] ascend */
++    u32 *aPgno;                   /* Array of page numbers. */
++    int nEntry;                   /* Nr. of entries in aPgno[] and aIndex[] */
++    int iZero;                    /* Frame number associated with aPgno[0] */
++  } aSegment[1];                  /* One for every 32KB page in the wal-index */
++};
 +
-+/* 
-+** Return pointers to the hash table and page number array stored on
-+** page iHash of the wal-index. The wal-index is broken into 32KB pages
-+** numbered starting from 0.
++/*
++** Define the parameters of the hash tables in the wal-index file. There
++** is a hash-table following every HASHTABLE_NPAGE page numbers in the
++** wal-index.
  **
 -**      aLeft[X]!=aRight[Y]  &&  aContent[aLeft[X]] == aContent[aRight[Y]]
-+** Set output variable *paHash to point to the start of the hash table
-+** in the wal-index file. Set *piZero to one less than the frame 
-+** number of the first frame indexed by this hash table. If a
-+** slot in the hash table is set to N, it refers to frame number 
-+** (*piZero+N) in the log.
++** Changing any of these constants will alter the wal-index format and
++** create incompatibilities.
++*/
++#define HASHTABLE_NPAGE      4096                 /* Must be power of 2 */
++#define HASHTABLE_HASH_1     383                  /* Should be prime */
++#define HASHTABLE_NSLOT      (HASHTABLE_NPAGE*2)  /* Must be a power of 2 */
++
++/* 
++** The block of page numbers associated with the first hash-table in a
++** wal-index is smaller than usual. This is so that there is a complete
++** hash-table on each aligned 32KB page of the wal-index.
++*/
++#define HASHTABLE_NPAGE_ONE  (HASHTABLE_NPAGE - (WALINDEX_HDR_SIZE/sizeof(u32)))
++
++/* The wal-index is divided into pages of WALINDEX_PGSZ bytes each. */
++#define WALINDEX_PGSZ   (                                         \
++    sizeof(ht_slot)*HASHTABLE_NSLOT + HASHTABLE_NPAGE*sizeof(u32) \
++)
++
++/*
++** Obtain a pointer to the iPage'th page of the wal-index. The wal-index
++** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are
++** numbered from zero.
  **
 -** When that happens, omit the aLeft[X] and use the aRight[Y] index.
-+** Finally, set *paPgno so that *paPgno[1] is the page number of the
-+** first frame indexed by the hash table, frame (*piZero+1).
++** If this call is successful, *ppPage is set to point to the wal-index
++** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs,
++** then an SQLite error code is returned and *ppPage is set to 0.
  */
 -static void walMerge(
 -  const u32 *aContent,            /* Pages in wal - keys for the sort */
@@ -5784,87 +39103,83 @@
 -  ht_slot **paRight,              /* IN/OUT: Right hand input list */
 -  int *pnRight,                   /* IN/OUT: Elements in *paRight */
 -  ht_slot *aTmp                   /* Temporary buffer */
-+static int walHashGet(
-+  Wal *pWal,                      /* WAL handle */
-+  int iHash,                      /* Find the iHash'th table */
-+  volatile ht_slot **paHash,      /* OUT: Pointer to hash index */
-+  volatile u32 **paPgno,          /* OUT: Pointer to page number array */
-+  u32 *piZero                     /* OUT: Frame associated with *paPgno[0] */
- ){
+-){
 -  int iLeft = 0;                  /* Current index in aLeft */
 -  int iRight = 0;                 /* Current index in aRight */
 -  int iOut = 0;                   /* Current index in output buffer */
 -  int nRight = *pnRight;
 -  ht_slot *aRight = *paRight;
-+  int rc;                         /* Return code */
-+  volatile u32 *aPgno;
++static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
++  int rc = SQLITE_OK;
  
 -  assert( nLeft>0 && nRight>0 );
 -  while( iRight<nRight || iLeft<nLeft ){
 -    ht_slot logpage;
 -    Pgno dbpage;
-+  rc = walIndexPage(pWal, iHash, &aPgno);
-+  assert( rc==SQLITE_OK || iHash>0 );
++  /* Enlarge the pWal->apWiData[] array if required */
++  if( pWal->nWiData<=iPage ){
++    int nByte = sizeof(u32*)*(iPage+1);
++    volatile u32 **apNew;
++    apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
++    if( !apNew ){
++      *ppPage = 0;
++      return SQLITE_NOMEM;
++    }
++    memset((void*)&apNew[pWal->nWiData], 0,
++           sizeof(u32*)*(iPage+1-pWal->nWiData));
++    pWal->apWiData = apNew;
++    pWal->nWiData = iPage+1;
++  }
  
 -    if( (iLeft<nLeft) 
 -     && (iRight>=nRight || aContent[aLeft[iLeft]]<aContent[aRight[iRight]])
 -    ){
 -      logpage = aLeft[iLeft++];
-+  if( rc==SQLITE_OK ){
-+    u32 iZero;
-+    volatile ht_slot *aHash;
-+
-+    aHash = (volatile ht_slot *)&aPgno[HASHTABLE_NPAGE];
-+    if( iHash==0 ){
-+      aPgno = &aPgno[WALINDEX_HDR_SIZE/sizeof(u32)];
-+      iZero = 0;
++  /* Request a pointer to the required page from the VFS */
++  if( pWal->apWiData[iPage]==0 ){
++    if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
++      pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ);
++      if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM;
      }else{
 -      logpage = aRight[iRight++];
-+      iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE;
++      rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, 
++          pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
++      );
++      if( rc==SQLITE_READONLY ){
++        pWal->readOnly |= WAL_SHM_RDONLY;
++        rc = SQLITE_OK;
++      }
      }
 -    dbpage = aContent[logpage];
-+  
-+    *paPgno = &aPgno[-1];
-+    *paHash = aHash;
-+    *piZero = iZero;
 +  }
-+  return rc;
-+}
  
 -    aTmp[iOut++] = logpage;
 -    if( iLeft<nLeft && aContent[aLeft[iLeft]]==dbpage ) iLeft++;
-+/*
-+** Return the number of the wal-index page that contains the hash-table
-+** and page-number array that contain entries corresponding to WAL frame
-+** iFrame. The wal-index is broken up into 32KB pages. Wal-index pages 
-+** are numbered starting from 0.
-+*/
-+static int walFramePage(u32 iFrame){
-+  int iHash = (iFrame+HASHTABLE_NPAGE-HASHTABLE_NPAGE_ONE-1) / HASHTABLE_NPAGE;
-+  assert( (iHash==0 || iFrame>HASHTABLE_NPAGE_ONE)
-+       && (iHash>=1 || iFrame<=HASHTABLE_NPAGE_ONE)
-+       && (iHash<=1 || iFrame>(HASHTABLE_NPAGE_ONE+HASHTABLE_NPAGE))
-+       && (iHash>=2 || iFrame<=HASHTABLE_NPAGE_ONE+HASHTABLE_NPAGE)
-+       && (iHash<=2 || iFrame>(HASHTABLE_NPAGE_ONE+2*HASHTABLE_NPAGE))
-+  );
-+  return iHash;
++  *ppPage = pWal->apWiData[iPage];
++  assert( iPage==0 || *ppPage || rc!=SQLITE_OK );
++  return rc;
 +}
  
 -    assert( iLeft>=nLeft || aContent[aLeft[iLeft]]>dbpage );
 -    assert( iRight>=nRight || aContent[aRight[iRight]]>dbpage );
+-  }
 +/*
-+** Return the page number associated with frame iFrame in this WAL.
++** Return a pointer to the WalCkptInfo structure in the wal-index.
 +*/
-+static u32 walFramePgno(Wal *pWal, u32 iFrame){
-+  int iHash = walFramePage(iFrame);
-+  if( iHash==0 ){
-+    return pWal->apWiData[0][WALINDEX_HDR_SIZE/sizeof(u32) + iFrame - 1];
-   }
--
++static volatile WalCkptInfo *walCkptInfo(Wal *pWal){
++  assert( pWal->nWiData>0 && pWal->apWiData[0] );
++  return (volatile WalCkptInfo*)&(pWal->apWiData[0][sizeof(WalIndexHdr)/2]);
++}
+ 
 -  *paRight = aLeft;
 -  *pnRight = iOut;
 -  memcpy(aLeft, aTmp, sizeof(aTmp[0])*iOut);
-+  return pWal->apWiData[iHash][(iFrame-1-HASHTABLE_NPAGE_ONE)%HASHTABLE_NPAGE];
++/*
++** Return a pointer to the WalIndexHdr structure in the wal-index.
++*/
++static volatile WalIndexHdr *walIndexHdr(Wal *pWal){
++  assert( pWal->nWiData>0 && pWal->apWiData[0] );
++  return (volatile WalIndexHdr*)pWal->apWiData[0];
  }
  
  /*
@@ -5878,37 +39193,48 @@
 -**      aContent[aList[J]] < aContent[aList[K]]
 -**
 -** For any X and Y such that
-+** Remove entries from the hash table that point to WAL slots greater
-+** than pWal->hdr.mxFrame.
++** The argument to this macro must be of type u32. On a little-endian
++** architecture, it returns the u32 value that results from interpreting
++** the 4 bytes as a big-endian value. On a big-endian architecture, it
++** returns the value that would be produced by interpreting the 4 bytes
++** of the input value as a little-endian integer.
++*/
++#define BYTESWAP32(x) ( \
++    (((x)&0x000000FF)<<24) + (((x)&0x0000FF00)<<8)  \
++  + (((x)&0x00FF0000)>>8)  + (((x)&0xFF000000)>>24) \
++)
++
++/*
++** Generate or extend an 8 byte checksum based on the data in 
++** array aByte[] and the initial values of aIn[0] and aIn[1] (or
++** initial values of 0 and 0 if aIn==NULL).
  **
 -**      aContent[aList[X]] == aContent[aList[Y]]
-+** This function is called whenever pWal->hdr.mxFrame is decreased due
-+** to a rollback or savepoint.
++** The checksum is written back into aOut[] before returning.
  **
 -** Keep the larger of the two values aList[X] and aList[Y] and discard
 -** the smaller.
-+** At most only the hash table containing pWal->hdr.mxFrame needs to be
-+** updated.  Any later hash tables will be automatically cleared when
-+** pWal->hdr.mxFrame advances to the point where those hash tables are
-+** actually needed.
++** nByte must be a positive multiple of 8.
  */
 -static void walMergesort(
 -  const u32 *aContent,            /* Pages in wal */
 -  ht_slot *aBuffer,               /* Buffer of at least *pnList items to use */
 -  ht_slot *aList,                 /* IN/OUT: List to sort */
 -  int *pnList                     /* IN/OUT: Number of elements in aList[] */
--){
++static void walChecksumBytes(
++  int nativeCksum, /* True for native byte-order, false for non-native */
++  u8 *a,           /* Content to be checksummed */
++  int nByte,       /* Bytes of content in a[].  Must be a multiple of 8. */
++  const u32 *aIn,  /* Initial checksum value input */
++  u32 *aOut        /* OUT: Final checksum value output */
+ ){
 -  struct Sublist {
 -    int nList;                    /* Number of elements in aList */
 -    ht_slot *aList;               /* Pointer to sub-list content */
 -  };
-+static void walCleanupHash(Wal *pWal){
-+  volatile ht_slot *aHash = 0;    /* Pointer to hash table to clear */
-+  volatile u32 *aPgno = 0;        /* Page number array for hash table */
-+  u32 iZero = 0;                  /* frame == (aHash[x]+iZero) */
-+  int iLimit = 0;                 /* Zero values greater than this */
-+  int nByte;                      /* Number of bytes to zero in aPgno[] */
-+  int i;                          /* Used to iterate through aHash[] */
++  u32 s1, s2;
++  u32 *aData = (u32 *)a;
++  u32 *aEnd = (u32 *)&a[nByte];
  
 -  const int nList = *pnList;      /* Size of input list */
 -  int nMerge = 0;                 /* Number of elements in list aMerge */
@@ -5916,15 +39242,18 @@
 -  int iList;                      /* Index into input list */
 -  int iSub = 0;                   /* Index into aSub array */
 -  struct Sublist aSub[13];        /* Array of sub-lists */
-+  assert( pWal->writeLock );
-+  testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE-1 );
-+  testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE );
-+  testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE+1 );
++  if( aIn ){
++    s1 = aIn[0];
++    s2 = aIn[1];
++  }else{
++    s1 = s2 = 0;
++  }
  
 -  memset(aSub, 0, sizeof(aSub));
 -  assert( nList<=HASHTABLE_NPAGE && nList>0 );
 -  assert( HASHTABLE_NPAGE==(1<<(ArraySize(aSub)-1)) );
-+  if( pWal->hdr.mxFrame==0 ) return;
++  assert( nByte>=8 );
++  assert( (nByte&0x00000007)==0 );
  
 -  for(iList=0; iList<nList; iList++){
 -    nMerge = 1;
@@ -5937,14 +39266,18 @@
 -    }
 -    aSub[iSub].aList = aMerge;
 -    aSub[iSub].nList = nMerge;
--  }
-+  /* Obtain pointers to the hash-table and page-number array containing 
-+  ** the entry that corresponds to frame pWal->hdr.mxFrame. It is guaranteed
-+  ** that the page said hash-table and array reside on is already mapped.
-+  */
-+  assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) );
-+  assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] );
-+  walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &aHash, &aPgno, &iZero);
++  if( nativeCksum ){
++    do {
++      s1 += *aData++ + s2;
++      s2 += *aData++ + s1;
++    }while( aData<aEnd );
++  }else{
++    do {
++      s1 += BYTESWAP32(aData[0]) + s2;
++      s2 += BYTESWAP32(aData[1]) + s1;
++      aData += 2;
++    }while( aData<aEnd );
+   }
  
 -  for(iSub++; iSub<ArraySize(aSub); iSub++){
 -    if( nList & (1<<iSub) ){
@@ -5952,54 +39285,48 @@
 -      assert( p->nList<=(1<<iSub) );
 -      assert( p->aList==&aList[nList&~((2<<iSub)-1)] );
 -      walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer);
-+  /* Zero all hash-table entries that correspond to frame numbers greater
-+  ** than pWal->hdr.mxFrame.
-+  */
-+  iLimit = pWal->hdr.mxFrame - iZero;
-+  assert( iLimit>0 );
-+  for(i=0; i<HASHTABLE_NSLOT; i++){
-+    if( aHash[i]>iLimit ){
-+      aHash[i] = 0;
-     }
-   }
+-    }
+-  }
 -  assert( aMerge==aList );
 -  *pnList = nMerge;
-+  
-+  /* Zero the entries in the aPgno array that correspond to frames with
-+  ** frame numbers greater than pWal->hdr.mxFrame. 
-+  */
-+  nByte = (int)((char *)aHash - (char *)&aPgno[iLimit+1]);
-+  memset((void *)&aPgno[iLimit+1], 0, nByte);
++  aOut[0] = s1;
++  aOut[1] = s2;
++}
  
 -#ifdef SQLITE_DEBUG
 -  {
 -    int i;
 -    for(i=1; i<*pnList; i++){
 -      assert( aContent[aList[i]] > aContent[aList[i-1]] );
-+#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
-+  /* Verify that the every entry in the mapping region is still reachable
-+  ** via the hash table even after the cleanup.
-+  */
-+  if( iLimit ){
-+    int i;           /* Loop counter */
-+    int iKey;        /* Hash key */
-+    for(i=1; i<=iLimit; i++){
-+      for(iKey=walHash(aPgno[i]); aHash[iKey]; iKey=walNextHash(iKey)){
-+        if( aHash[iKey]==i ) break;
-+      }
-+      assert( aHash[iKey]==i );
-     }
+-    }
++static void walShmBarrier(Wal *pWal){
++  if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){
++    sqlite3OsShmBarrier(pWal->pDbFd);
    }
 -#endif
-+#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
  }
  
 -/* 
 -** Free an iterator allocated by walIteratorInit().
--*/
++/*
++** Write the header information in pWal->hdr into the wal-index.
++**
++** The checksum on pWal->hdr is updated before it is written.
+ */
 -static void walIteratorFree(WalIterator *p){
--  sqlite3ScratchFree(p);
--}
+-  sqlite3_free(p);
++static void walIndexWriteHdr(Wal *pWal){
++  volatile WalIndexHdr *aHdr = walIndexHdr(pWal);
++  const int nCksum = offsetof(WalIndexHdr, aCksum);
++
++  assert( pWal->writeLock );
++  pWal->hdr.isInit = 1;
++  pWal->hdr.iVersion = WALINDEX_MAX_VERSION;
++  walChecksumBytes(1, (u8*)&pWal->hdr, nCksum, 0, pWal->hdr.aCksum);
++  memcpy((void *)&aHdr[1], (void *)&pWal->hdr, sizeof(WalIndexHdr));
++  walShmBarrier(pWal);
++  memcpy((void *)&aHdr[0], (void *)&pWal->hdr, sizeof(WalIndexHdr));
+ }
  
  /*
 -** Construct a WalInterator object that can be used to loop over all 
@@ -6009,11 +39336,19 @@
 -** On success, make *pp point to the newly allocated WalInterator object
 -** return SQLITE_OK. Otherwise, return an error code. If this routine
 -** returns an error, the value of *pp is undefined.
--**
++** This function encodes a single frame header and writes it to a buffer
++** supplied by the caller. A frame-header is made up of a series of 
++** 4-byte big-endian integers, as follows:
+ **
 -** The calling routine should invoke walIteratorFree() to destroy the
 -** WalIterator object when it has finished with it.
-+** Set an entry in the wal-index that will map database page number
-+** pPage into WAL frame iFrame.
++**     0: Page number.
++**     4: For commit records, the size of the database image in pages 
++**        after the commit. For all other records, zero.
++**     8: Salt-1 (copied from the wal-header)
++**    12: Salt-2 (copied from the wal-header)
++**    16: Checksum-1.
++**    20: Checksum-2.
  */
 -static int walIteratorInit(Wal *pWal, WalIterator **pp){
 -  WalIterator *p;                 /* Return value */
@@ -6023,95 +39358,112 @@
 -  int i;                          /* Iterator variable */
 -  ht_slot *aTmp;                  /* Temp space used by merge-sort */
 -  int rc = SQLITE_OK;             /* Return Code */
-+static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
-+  int rc;                         /* Return code */
-+  u32 iZero = 0;                  /* One less than frame number of aPgno[1] */
-+  volatile u32 *aPgno = 0;        /* Page number array */
-+  volatile ht_slot *aHash = 0;    /* Hash table */
++static void walEncodeFrame(
++  Wal *pWal,                      /* The write-ahead log */
++  u32 iPage,                      /* Database page number for frame */
++  u32 nTruncate,                  /* New db size (or 0 for non-commit frames) */
++  u8 *aData,                      /* Pointer to page data */
++  u8 *aFrame                      /* OUT: Write encoded frame here */
++){
++  int nativeCksum;                /* True for native byte-order checksums */
++  u32 *aCksum = pWal->hdr.aFrameCksum;
++  assert( WAL_FRAME_HDRSIZE==24 );
++  sqlite3Put4byte(&aFrame[0], iPage);
++  sqlite3Put4byte(&aFrame[4], nTruncate);
++  memcpy(&aFrame[8], pWal->hdr.aSalt, 8);
  
 -  /* This routine only runs while holding the checkpoint lock. And
 -  ** it only runs if there is actually content in the log (mxFrame>0).
-+  rc = walHashGet(pWal, walFramePage(iFrame), &aHash, &aPgno, &iZero);
-+
-+  /* Assuming the wal-index file was successfully mapped, populate the
-+  ** page number array and hash table entry.
-   */
+-  */
 -  assert( pWal->ckptLock && pWal->hdr.mxFrame>0 );
 -  iLast = pWal->hdr.mxFrame;
-+  if( rc==SQLITE_OK ){
-+    int iKey;                     /* Hash table key */
-+    int idx;                      /* Value to write to hash-table slot */
-+    int nCollide;                 /* Number of hash collisions */
++  nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
++  walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
++  walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
  
 -  /* Allocate space for the WalIterator object. */
 -  nSegment = walFramePage(iLast) + 1;
 -  nByte = sizeof(WalIterator) 
 -        + (nSegment-1)*sizeof(struct WalSegment)
 -        + iLast*sizeof(ht_slot);
--  p = (WalIterator *)sqlite3ScratchMalloc(nByte);
+-  p = (WalIterator *)sqlite3_malloc64(nByte);
 -  if( !p ){
 -    return SQLITE_NOMEM;
--  }
++  sqlite3Put4byte(&aFrame[16], aCksum[0]);
++  sqlite3Put4byte(&aFrame[20], aCksum[1]);
++}
++
++/*
++** Check to see if the frame with header in aFrame[] and content
++** in aData[] is valid.  If it is a valid frame, fill *piPage and
++** *pnTruncate and return true.  Return if the frame is not valid.
++*/
++static int walDecodeFrame(
++  Wal *pWal,                      /* The write-ahead log */
++  u32 *piPage,                    /* OUT: Database page number for frame */
++  u32 *pnTruncate,                /* OUT: New db size (or 0 if not commit) */
++  u8 *aData,                      /* Pointer to page data (for checksum) */
++  u8 *aFrame                      /* Frame data */
++){
++  int nativeCksum;                /* True for native byte-order checksums */
++  u32 *aCksum = pWal->hdr.aFrameCksum;
++  u32 pgno;                       /* Page number of the frame */
++  assert( WAL_FRAME_HDRSIZE==24 );
++
++  /* A frame is only valid if the salt values in the frame-header
++  ** match the salt values in the wal-header. 
++  */
++  if( memcmp(&pWal->hdr.aSalt, &aFrame[8], 8)!=0 ){
++    return 0;
+   }
 -  memset(p, 0, nByte);
 -  p->nSegment = nSegment;
-+    idx = iFrame - iZero;
-+    assert( idx <= HASHTABLE_NSLOT/2 + 1 );
-+    
-+    /* If this is the first entry to be added to this hash-table, zero the
-+    ** entire hash table and aPgno[] array before proceding. 
-+    */
-+    if( idx==1 ){
-+      int nByte = (int)((u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]);
-+      memset((void*)&aPgno[1], 0, nByte);
-+    }
  
 -  /* Allocate temporary space used by the merge-sort routine. This block
 -  ** of memory will be freed before this function returns.
--  */
--  aTmp = (ht_slot *)sqlite3ScratchMalloc(
++  /* A frame is only valid if the page number is creater than zero.
+   */
+-  aTmp = (ht_slot *)sqlite3_malloc64(
 -      sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
 -  );
 -  if( !aTmp ){
 -    rc = SQLITE_NOMEM;
--  }
-+    /* If the entry in aPgno[] is already set, then the previous writer
-+    ** must have exited unexpectedly in the middle of a transaction (after
-+    ** writing one or more dirty pages to the WAL to free up memory). 
-+    ** Remove the remnants of that writers uncommitted transaction from 
-+    ** the hash-table before writing any new entries.
-+    */
-+    if( aPgno[idx] ){
-+      walCleanupHash(pWal);
-+      assert( !aPgno[idx] );
-+    }
++  pgno = sqlite3Get4byte(&aFrame[0]);
++  if( pgno==0 ){
++    return 0;
+   }
  
 -  for(i=0; rc==SQLITE_OK && i<nSegment; i++){
 -    volatile ht_slot *aHash;
 -    u32 iZero;
 -    volatile u32 *aPgno;
-+    /* Write the aPgno[] array entry and the hash-table slot. */
-+    nCollide = idx;
-+    for(iKey=walHash(iPage); aHash[iKey]; iKey=walNextHash(iKey)){
-+      if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT;
-+    }
-+    aPgno[idx] = iPage;
-+    aHash[iKey] = (ht_slot)idx;
++  /* A frame is only valid if a checksum of the WAL header,
++  ** all prior frams, the first 16 bytes of this frame-header, 
++  ** and the frame-data matches the checksum in the last 8 
++  ** bytes of this frame-header.
++  */
++  nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN);
++  walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum);
++  walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum);
++  if( aCksum[0]!=sqlite3Get4byte(&aFrame[16]) 
++   || aCksum[1]!=sqlite3Get4byte(&aFrame[20]) 
++  ){
++    /* Checksum failed. */
++    return 0;
++  }
  
 -    rc = walHashGet(pWal, i, &aHash, &aPgno, &iZero);
 -    if( rc==SQLITE_OK ){
 -      int j;                      /* Counter variable */
 -      int nEntry;                 /* Number of entries in this segment */
 -      ht_slot *aIndex;            /* Sorted index for this segment */
-+#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
-+    /* Verify that the number of entries in the hash table exactly equals
-+    ** the number of entries in the mapping region.
-+    */
-+    {
-+      int i;           /* Loop counter */
-+      int nEntry = 0;  /* Number of entries in the hash table */
-+      for(i=0; i<HASHTABLE_NSLOT; i++){ if( aHash[i] ) nEntry++; }
-+      assert( nEntry==idx );
-+    }
++  /* If we reach this point, the frame is valid.  Return the page number
++  ** and the new database size.
++  */
++  *piPage = pgno;
++  *pnTruncate = sqlite3Get4byte(&aFrame[4]);
++  return 1;
++}
  
 -      aPgno++;
 -      if( (i+1)==nSegment ){
@@ -6124,42 +39476,53 @@
 -  
 -      for(j=0; j<nEntry; j++){
 -        aIndex[j] = (ht_slot)j;
-+    /* Verify that the every entry in the mapping region is reachable
-+    ** via the hash table.  This turns out to be a really, really expensive
-+    ** thing to check, so only do this occasionally - not on every
-+    ** iteration.
-+    */
-+    if( (idx&0x3ff)==0 ){
-+      int i;           /* Loop counter */
-+      for(i=1; i<=idx; i++){
-+        for(iKey=walHash(aPgno[i]); aHash[iKey]; iKey=walNextHash(iKey)){
-+          if( aHash[iKey]==i ) break;
-+        }
-+        assert( aHash[iKey]==i );
-       }
+-      }
 -      walMergesort((u32 *)aPgno, aTmp, aIndex, &nEntry);
 -      p->aSegment[i].iZero = iZero;
 -      p->aSegment[i].nEntry = nEntry;
 -      p->aSegment[i].aIndex = aIndex;
 -      p->aSegment[i].aPgno = (u32 *)aPgno;
-     }
-+#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
-   }
--  sqlite3ScratchFree(aTmp);
+-    }
+-  }
+-  sqlite3_free(aTmp);
  
 -  if( rc!=SQLITE_OK ){
 -    walIteratorFree(p);
--  }
++#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
++/*
++** Names of locks.  This routine is used to provide debugging output and is not
++** a part of an ordinary build.
++*/
++static const char *walLockName(int lockIdx){
++  if( lockIdx==WAL_WRITE_LOCK ){
++    return "WRITE-LOCK";
++  }else if( lockIdx==WAL_CKPT_LOCK ){
++    return "CKPT-LOCK";
++  }else if( lockIdx==WAL_RECOVER_LOCK ){
++    return "RECOVER-LOCK";
++  }else{
++    static char zName[15];
++    sqlite3_snprintf(sizeof(zName), zName, "READ-LOCK[%d]",
++                     lockIdx-WAL_READ_LOCK(0));
++    return zName;
+   }
 -  *pp = p;
 -  return rc;
--}
+ }
++#endif /*defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */
++    
  
--/*
+ /*
 -** Attempt to obtain the exclusive WAL lock defined by parameters lockIdx and
 -** n. If the attempt fails and parameter xBusy is not NULL, then it is a
 -** busy-handler function. Invoke it and retry the lock until either the
 -** lock is successfully obtained or the busy-handler returns 0.
--*/
++** Set or release locks on the WAL.  Locks are either shared or exclusive.
++** A lock cannot be moved directly between shared and exclusive - it must go
++** through the unlocked state first.
++**
++** In locking_mode=EXCLUSIVE, all of these routines become no-ops.
+ */
 -static int walBusyLock(
 -  Wal *pWal,                      /* WAL connection */
 -  int (*xBusy)(void*),            /* Function to call when busy */
@@ -6167,22 +39530,94 @@
 -  int lockIdx,                    /* Offset of first byte to lock */
 -  int n                           /* Number of bytes to lock */
 -){
--  int rc;
++static int walLockShared(Wal *pWal, int lockIdx){
+   int rc;
 -  do {
--    rc = walLockExclusive(pWal, lockIdx, n);
+-    rc = walLockExclusive(pWal, lockIdx, n, 0);
 -  }while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) );
++  if( pWal->exclusiveMode ) return SQLITE_OK;
++  rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
++                        SQLITE_SHM_LOCK | SQLITE_SHM_SHARED);
++  WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal,
++            walLockName(lockIdx), rc ? "failed" : "ok"));
++  VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
    return rc;
  }
- 
+-
 -/*
 -** The cache of the wal-index header must be valid to call this function.
 -** Return the page-size in bytes used by the database.
 -*/
 -static int walPagesize(Wal *pWal){
 -  return (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
--}
++static void walUnlockShared(Wal *pWal, int lockIdx){
++  if( pWal->exclusiveMode ) return;
++  (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
++                         SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED);
++  WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx)));
++}
++static int walLockExclusive(Wal *pWal, int lockIdx, int n, int fBlock){
++  int rc;
++  if( pWal->exclusiveMode ) return SQLITE_OK;
++  if( fBlock ) sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_WAL_BLOCK, 0);
++  rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
++                        SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE);
++  WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal,
++            walLockName(lockIdx), n, rc ? "failed" : "ok"));
++  VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
++  return rc;
++}
++static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){
++  if( pWal->exclusiveMode ) return;
++  (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
++                         SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE);
++  WALTRACE(("WAL%p: release EXCLUSIVE-%s cnt=%d\n", pWal,
++             walLockName(lockIdx), n));
+ }
  
  /*
+-** The following is guaranteed when this function is called:
+-**
+-**   a) the WRITER lock is held,
+-**   b) the entire log file has been checkpointed, and
+-**   c) any existing readers are reading exclusively from the database
+-**      file - there are no readers that may attempt to read a frame from
+-**      the log file.
+-**
+-** This function updates the shared-memory structures so that the next
+-** client to write to the database (which may be this one) does so by
+-** writing frames into the start of the log file.
+-**
+-** The value of parameter salt1 is used as the aSalt[1] value in the 
+-** new wal-index header. It should be passed a pseudo-random value (i.e. 
+-** one obtained from sqlite3_randomness()).
++** Compute a hash on a page number.  The resulting hash value must land
++** between 0 and (HASHTABLE_NSLOT-1).  The walHashNext() function advances
++** the hash to the next value in the event of a collision.
+ */
+-static void walRestartHdr(Wal *pWal, u32 salt1){
+-  volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
+-  int i;                          /* Loop counter */
+-  u32 *aSalt = pWal->hdr.aSalt;   /* Big-endian salt values */
+-  pWal->nCkpt++;
+-  pWal->hdr.mxFrame = 0;
+-  sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
+-  memcpy(&pWal->hdr.aSalt[1], &salt1, 4);
+-  walIndexWriteHdr(pWal);
+-  pInfo->nBackfill = 0;
+-  pInfo->aReadMark[1] = 0;
+-  for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
+-  assert( pInfo->aReadMark[0]==0 );
++static int walHash(u32 iPage){
++  assert( iPage>0 );
++  assert( (HASHTABLE_NSLOT & (HASHTABLE_NSLOT-1))==0 );
++  return (iPage*HASHTABLE_HASH_1) & (HASHTABLE_NSLOT-1);
++}
++static int walNextHash(int iPriorHash){
++  return (iPriorHash+1)&(HASHTABLE_NSLOT-1);
+ }
+ 
+-/*
 -** Copy as much content as we can from the WAL back into the database file
 -** in response to an sqlite3_wal_checkpoint() request or the equivalent.
 -**
@@ -6203,32 +39638,42 @@
 -** WAL content is copied into the database file.  This second fsync makes
 -** it safe to delete the WAL since the new content will persist in the
 -** database file.
--**
++/* 
++** Return pointers to the hash table and page number array stored on
++** page iHash of the wal-index. The wal-index is broken into 32KB pages
++** numbered starting from 0.
+ **
 -** This routine uses and updates the nBackfill field of the wal-index header.
--** This is the only routine tha will increase the value of nBackfill.  
+-** This is the only routine that will increase the value of nBackfill.  
 -** (A WAL reset or recovery will revert nBackfill to zero, but not increase
 -** its value.)
-+** Recover the wal-index by reading the write-ahead log file. 
++** Set output variable *paHash to point to the start of the hash table
++** in the wal-index file. Set *piZero to one less than the frame 
++** number of the first frame indexed by this hash table. If a
++** slot in the hash table is set to N, it refers to frame number 
++** (*piZero+N) in the log.
  **
 -** The caller must be holding sufficient locks to ensure that no other
 -** checkpoint is running (in any other thread or process) at the same
 -** time.
-+** This routine first tries to establish an exclusive lock on the
-+** wal-index to prevent other threads/processes from doing anything
-+** with the WAL or wal-index while recovery is running.  The
-+** WAL_RECOVER_LOCK is also held so that other threads will know
-+** that this thread is running recovery.  If unable to establish
-+** the necessary locks, this routine returns SQLITE_BUSY.
++** Finally, set *paPgno so that *paPgno[1] is the page number of the
++** first frame indexed by the hash table, frame (*piZero+1).
  */
 -static int walCheckpoint(
 -  Wal *pWal,                      /* Wal connection */
 -  int eMode,                      /* One of PASSIVE, FULL or RESTART */
--  int (*xBusyCall)(void*),        /* Function to call when busy */
+-  int (*xBusy)(void*),            /* Function to call when busy */
 -  void *pBusyArg,                 /* Context argument for xBusyHandler */
 -  int sync_flags,                 /* Flags for OsSync() (or 0) */
 -  u8 *zBuf                        /* Temporary buffer to use */
--){
--  int rc;                         /* Return code */
++static int walHashGet(
++  Wal *pWal,                      /* WAL handle */
++  int iHash,                      /* Find the iHash'th table */
++  volatile ht_slot **paHash,      /* OUT: Pointer to hash index */
++  volatile u32 **paPgno,          /* OUT: Pointer to page number array */
++  u32 *piZero                     /* OUT: Frame associated with *paPgno[0] */
+ ){
+-  int rc = SQLITE_OK;             /* Return code */
 -  int szPage;                     /* Database page-size */
 -  WalIterator *pIter = 0;         /* Wal iterator context */
 -  u32 iDbpage = 0;                /* Next database page to write */
@@ -6237,270 +39682,267 @@
 -  u32 mxPage;                     /* Max database page to write */
 -  int i;                          /* Loop counter */
 -  volatile WalCkptInfo *pInfo;    /* The checkpoint status information */
--  int (*xBusy)(void*) = 0;        /* Function to call when waiting for locks */
 -
 -  szPage = walPagesize(pWal);
 -  testcase( szPage<=32768 );
 -  testcase( szPage>=65536 );
 -  pInfo = walCkptInfo(pWal);
--  if( pInfo->nBackfill>=pWal->hdr.mxFrame ) return SQLITE_OK;
-+static int walIndexRecover(Wal *pWal){
-+  int rc;                         /* Return Code */
-+  i64 nSize;                      /* Size of log file */
-+  u32 aFrameCksum[2] = {0, 0};
-+  int iLock;                      /* Lock offset to lock for checkpoint */
-+  int nLock;                      /* Number of locks to hold */
+-  if( pInfo->nBackfill<pWal->hdr.mxFrame ){
++  int rc;                         /* Return code */
++  volatile u32 *aPgno;
  
--  /* Allocate the iterator */
--  rc = walIteratorInit(pWal, &pIter);
--  if( rc!=SQLITE_OK ){
-+  /* Obtain an exclusive lock on all byte in the locking range not already
-+  ** locked by the caller. The caller is guaranteed to have locked the
-+  ** WAL_WRITE_LOCK byte, and may have also locked the WAL_CKPT_LOCK byte.
-+  ** If successful, the same bytes that are locked here are unlocked before
-+  ** this function returns.
-+  */
-+  assert( pWal->ckptLock==1 || pWal->ckptLock==0 );
-+  assert( WAL_ALL_BUT_WRITE==WAL_WRITE_LOCK+1 );
-+  assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE );
-+  assert( pWal->writeLock );
-+  iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock;
-+  nLock = SQLITE_SHM_NLOCK - iLock;
-+  rc = walLockExclusive(pWal, iLock, nLock);
-+  if( rc ){
-     return rc;
-   }
--  assert( pIter );
--
--  if( eMode!=SQLITE_CHECKPOINT_PASSIVE ) xBusy = xBusyCall;
--
--  /* Compute in mxSafeFrame the index of the last frame of the WAL that is
--  ** safe to write into the database.  Frames beyond mxSafeFrame might
--  ** overwrite database pages that are in use by active readers and thus
--  ** cannot be backfilled from the WAL.
--  */
--  mxSafeFrame = pWal->hdr.mxFrame;
--  mxPage = pWal->hdr.nPage;
--  for(i=1; i<WAL_NREADER; i++){
--    u32 y = pInfo->aReadMark[i];
--    if( mxSafeFrame>y ){
--      assert( y<=pWal->hdr.mxFrame );
--      rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
--      if( rc==SQLITE_OK ){
--        pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
--        walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
--      }else if( rc==SQLITE_BUSY ){
--        mxSafeFrame = y;
--        xBusy = 0;
--      }else{
--        goto walcheckpoint_out;
--      }
+-    /* Allocate the iterator */
+-    rc = walIteratorInit(pWal, &pIter);
+-    if( rc!=SQLITE_OK ){
+-      return rc;
 -    }
-+  WALTRACE(("WAL%p: recovery begin...\n", pWal));
-+
-+  memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
-+
-+  rc = sqlite3OsFileSize(pWal->pWalFd, &nSize);
-+  if( rc!=SQLITE_OK ){
-+    goto recovery_error;
-   }
+-    assert( pIter );
++  rc = walIndexPage(pWal, iHash, &aPgno);
++  assert( rc==SQLITE_OK || iHash>0 );
  
--  if( pInfo->nBackfill<mxSafeFrame
--   && (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0), 1))==SQLITE_OK
--  ){
--    i64 nSize;                    /* Current size of database file */
--    u32 nBackfill = pInfo->nBackfill;
-+  if( nSize>WAL_HDRSIZE ){
-+    u8 aBuf[WAL_HDRSIZE];         /* Buffer to load WAL header into */
-+    u8 *aFrame = 0;               /* Malloc'd buffer to load entire frame */
-+    int szFrame;                  /* Number of bytes in buffer aFrame[] */
-+    u8 *aData;                    /* Pointer to data part of aFrame buffer */
-+    int iFrame;                   /* Index of last frame read */
-+    i64 iOffset;                  /* Next offset to read from log file */
-+    int szPage;                   /* Page size according to the log */
-+    u32 magic;                    /* Magic value read from WAL header */
-+    u32 version;                  /* Magic value read from WAL header */
-+    int isValid;                  /* True if this frame is valid */
+-    /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
+-    ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
+-    assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
++  if( rc==SQLITE_OK ){
++    u32 iZero;
++    volatile ht_slot *aHash;
  
--    /* Sync the WAL to disk */
--    if( sync_flags ){
--      rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
-+    /* Read in the WAL header. */
-+    rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0);
-+    if( rc!=SQLITE_OK ){
-+      goto recovery_error;
+-    /* Compute in mxSafeFrame the index of the last frame of the WAL that is
+-    ** safe to write into the database.  Frames beyond mxSafeFrame might
+-    ** overwrite database pages that are in use by active readers and thus
+-    ** cannot be backfilled from the WAL.
+-    */
+-    mxSafeFrame = pWal->hdr.mxFrame;
+-    mxPage = pWal->hdr.nPage;
+-    for(i=1; i<WAL_NREADER; i++){
+-      /* Thread-sanitizer reports that the following is an unsafe read,
+-      ** as some other thread may be in the process of updating the value
+-      ** of the aReadMark[] slot. The assumption here is that if that is
+-      ** happening, the other client may only be increasing the value,
+-      ** not decreasing it. So assuming either that either the "old" or
+-      ** "new" version of the value is read, and not some arbitrary value
+-      ** that would never be written by a real client, things are still 
+-      ** safe.  */
+-      u32 y = pInfo->aReadMark[i];
+-      if( mxSafeFrame>y ){
+-        assert( y<=pWal->hdr.mxFrame );
+-        rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
+-        if( rc==SQLITE_OK ){
+-          pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
+-          walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
+-        }else if( rc==SQLITE_BUSY ){
+-          mxSafeFrame = y;
+-          xBusy = 0;
+-        }else{
+-          goto walcheckpoint_out;
+-        }
+-      }
++    aHash = (volatile ht_slot *)&aPgno[HASHTABLE_NPAGE];
++    if( iHash==0 ){
++      aPgno = &aPgno[WALINDEX_HDR_SIZE/sizeof(u32)];
++      iZero = 0;
++    }else{
++      iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE;
      }
++  
++    *paPgno = &aPgno[-1];
++    *paHash = aHash;
++    *piZero = iZero;
++  }
++  return rc;
++}
  
--    /* If the database may grow as a result of this checkpoint, hint
--    ** about the eventual size of the db file to the VFS layer.
-+    /* If the database page size is not a power of two, or is greater than
-+    ** SQLITE_MAX_PAGE_SIZE, conclude that the WAL file contains no valid 
-+    ** data. Similarly, if the 'magic' value is invalid, ignore the whole
-+    ** WAL file.
-     */
--    if( rc==SQLITE_OK ){
--      i64 nReq = ((i64)mxPage * szPage);
--      rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
--      if( rc==SQLITE_OK && nSize<nReq ){
--        sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
+-    if( pInfo->nBackfill<mxSafeFrame
+-     && (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0),1))==SQLITE_OK
+-    ){
+-      i64 nSize;                    /* Current size of database file */
+-      u32 nBackfill = pInfo->nBackfill;
+-
+-      /* Sync the WAL to disk */
+-      if( sync_flags ){
+-        rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
 -      }
-+    magic = sqlite3Get4byte(&aBuf[0]);
-+    szPage = sqlite3Get4byte(&aBuf[8]);
-+    if( (magic&0xFFFFFFFE)!=WAL_MAGIC 
-+     || szPage&(szPage-1) 
-+     || szPage>SQLITE_MAX_PAGE_SIZE 
-+     || szPage<512 
-+    ){
-+      goto finished;
-     }
-+    pWal->hdr.bigEndCksum = (u8)(magic&0x00000001);
-+    pWal->szPage = szPage;
-+    pWal->nCkpt = sqlite3Get4byte(&aBuf[12]);
-+    memcpy(&pWal->hdr.aSalt, &aBuf[16], 8);
++/*
++** Return the number of the wal-index page that contains the hash-table
++** and page-number array that contain entries corresponding to WAL frame
++** iFrame. The wal-index is broken up into 32KB pages. Wal-index pages 
++** are numbered starting from 0.
++*/
++static int walFramePage(u32 iFrame){
++  int iHash = (iFrame+HASHTABLE_NPAGE-HASHTABLE_NPAGE_ONE-1) / HASHTABLE_NPAGE;
++  assert( (iHash==0 || iFrame>HASHTABLE_NPAGE_ONE)
++       && (iHash>=1 || iFrame<=HASHTABLE_NPAGE_ONE)
++       && (iHash<=1 || iFrame>(HASHTABLE_NPAGE_ONE+HASHTABLE_NPAGE))
++       && (iHash>=2 || iFrame<=HASHTABLE_NPAGE_ONE+HASHTABLE_NPAGE)
++       && (iHash<=2 || iFrame>(HASHTABLE_NPAGE_ONE+2*HASHTABLE_NPAGE))
++  );
++  return iHash;
++}
  
-+    /* Verify that the WAL header checksum is correct */
-+    walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, 
-+        aBuf, WAL_HDRSIZE-2*4, 0, pWal->hdr.aFrameCksum
-+    );
-+    if( pWal->hdr.aFrameCksum[0]!=sqlite3Get4byte(&aBuf[24])
-+     || pWal->hdr.aFrameCksum[1]!=sqlite3Get4byte(&aBuf[28])
-+    ){
-+      goto finished;
-+    }
+-      /* If the database may grow as a result of this checkpoint, hint
+-      ** about the eventual size of the db file to the VFS layer.
+-      */
+-      if( rc==SQLITE_OK ){
+-        i64 nReq = ((i64)mxPage * szPage);
+-        rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
+-        if( rc==SQLITE_OK && nSize<nReq ){
+-          sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
+-        }
+-      }
++/*
++** Return the page number associated with frame iFrame in this WAL.
++*/
++static u32 walFramePgno(Wal *pWal, u32 iFrame){
++  int iHash = walFramePage(iFrame);
++  if( iHash==0 ){
++    return pWal->apWiData[0][WALINDEX_HDR_SIZE/sizeof(u32) + iFrame - 1];
++  }
++  return pWal->apWiData[iHash][(iFrame-1-HASHTABLE_NPAGE_ONE)%HASHTABLE_NPAGE];
++}
  
--    /* Iterate through the contents of the WAL, copying data to the db file. */
--    while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
--      i64 iOffset;
--      assert( walFramePgno(pWal, iFrame)==iDbpage );
--      if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ) continue;
--      iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
--      /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
--      rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset);
-+    /* Verify that the version number on the WAL format is one that
-+    ** are able to understand */
-+    version = sqlite3Get4byte(&aBuf[4]);
-+    if( version!=WAL_MAX_VERSION ){
-+      rc = SQLITE_CANTOPEN_BKPT;
-+      goto finished;
-+    }
-+
-+    /* Malloc a buffer to read frames into. */
-+    szFrame = szPage + WAL_FRAME_HDRSIZE;
-+    aFrame = (u8 *)sqlite3_malloc(szFrame);
-+    if( !aFrame ){
-+      rc = SQLITE_NOMEM;
-+      goto recovery_error;
-+    }
-+    aData = &aFrame[WAL_FRAME_HDRSIZE];
-+
-+    /* Read all frames from the log file. */
-+    iFrame = 0;
-+    for(iOffset=WAL_HDRSIZE; (iOffset+szFrame)<=nSize; iOffset+=szFrame){
-+      u32 pgno;                   /* Database page number for frame */
-+      u32 nTruncate;              /* dbsize field from frame header */
-+
-+      /* Read and decode the next log frame. */
-+      iFrame++;
-+      rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset);
-       if( rc!=SQLITE_OK ) break;
--      iOffset = (iDbpage-1)*(i64)szPage;
--      testcase( IS_BIG_INT(iOffset) );
--      rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
-+      isValid = walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame);
-+      if( !isValid ) break;
-+      rc = walIndexAppend(pWal, iFrame, pgno);
-       if( rc!=SQLITE_OK ) break;
--    }
++/*
++** Remove entries from the hash table that point to WAL slots greater
++** than pWal->hdr.mxFrame.
++**
++** This function is called whenever pWal->hdr.mxFrame is decreased due
++** to a rollback or savepoint.
++**
++** At most only the hash table containing pWal->hdr.mxFrame needs to be
++** updated.  Any later hash tables will be automatically cleared when
++** pWal->hdr.mxFrame advances to the point where those hash tables are
++** actually needed.
++*/
++static void walCleanupHash(Wal *pWal){
++  volatile ht_slot *aHash = 0;    /* Pointer to hash table to clear */
++  volatile u32 *aPgno = 0;        /* Page number array for hash table */
++  u32 iZero = 0;                  /* frame == (aHash[x]+iZero) */
++  int iLimit = 0;                 /* Zero values greater than this */
++  int nByte;                      /* Number of bytes to zero in aPgno[] */
++  int i;                          /* Used to iterate through aHash[] */
  
--    /* If work was actually accomplished... */
--    if( rc==SQLITE_OK ){
--      if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
--        i64 szDb = pWal->hdr.nPage*(i64)szPage;
--        testcase( IS_BIG_INT(szDb) );
--        rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
--        if( rc==SQLITE_OK && sync_flags ){
--          rc = sqlite3OsSync(pWal->pDbFd, sync_flags);
+-      /* Iterate through the contents of the WAL, copying data to the db file */
+-      while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
+-        i64 iOffset;
+-        assert( walFramePgno(pWal, iFrame)==iDbpage );
+-        if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){
+-          continue;
 -        }
+-        iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
+-        /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
+-        rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset);
+-        if( rc!=SQLITE_OK ) break;
+-        iOffset = (iDbpage-1)*(i64)szPage;
+-        testcase( IS_BIG_INT(iOffset) );
+-        rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
+-        if( rc!=SQLITE_OK ) break;
 -      }
++  assert( pWal->writeLock );
++  testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE-1 );
++  testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE );
++  testcase( pWal->hdr.mxFrame==HASHTABLE_NPAGE_ONE+1 );
+ 
+-      /* If work was actually accomplished... */
 -      if( rc==SQLITE_OK ){
--        pInfo->nBackfill = mxSafeFrame;
-+      /* If nTruncate is non-zero, this is a commit record. */
-+      if( nTruncate ){
-+        pWal->hdr.mxFrame = iFrame;
-+        pWal->hdr.nPage = nTruncate;
-+        pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16));
-+        testcase( szPage<=32768 );
-+        testcase( szPage>=65536 );
-+        aFrameCksum[0] = pWal->hdr.aFrameCksum[0];
-+        aFrameCksum[1] = pWal->hdr.aFrameCksum[1];
-       }
-     }
+-        if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
+-          i64 szDb = pWal->hdr.nPage*(i64)szPage;
+-          testcase( IS_BIG_INT(szDb) );
+-          rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
+-          if( rc==SQLITE_OK && sync_flags ){
+-            rc = sqlite3OsSync(pWal->pDbFd, sync_flags);
+-          }
+-        }
+-        if( rc==SQLITE_OK ){
+-          pInfo->nBackfill = mxSafeFrame;
+-        }
+-      }
++  if( pWal->hdr.mxFrame==0 ) return;
  
--    /* Release the reader lock held while backfilling */
--    walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
-+    sqlite3_free(aFrame);
-   }
+-      /* Release the reader lock held while backfilling */
+-      walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
+-    }
++  /* Obtain pointers to the hash-table and page-number array containing 
++  ** the entry that corresponds to frame pWal->hdr.mxFrame. It is guaranteed
++  ** that the page said hash-table and array reside on is already mapped.
++  */
++  assert( pWal->nWiData>walFramePage(pWal->hdr.mxFrame) );
++  assert( pWal->apWiData[walFramePage(pWal->hdr.mxFrame)] );
++  walHashGet(pWal, walFramePage(pWal->hdr.mxFrame), &aHash, &aPgno, &iZero);
  
--  if( rc==SQLITE_BUSY ){
--    /* Reset the return code so as not to report a checkpoint failure
--    ** just because there are active readers.  */
--    rc = SQLITE_OK;
--  }
-+finished:
-+  if( rc==SQLITE_OK ){
-+    volatile WalCkptInfo *pInfo;
-+    int i;
-+    pWal->hdr.aFrameCksum[0] = aFrameCksum[0];
-+    pWal->hdr.aFrameCksum[1] = aFrameCksum[1];
-+    walIndexWriteHdr(pWal);
+-    if( rc==SQLITE_BUSY ){
+-      /* Reset the return code so as not to report a checkpoint failure
+-      ** just because there are active readers.  */
+-      rc = SQLITE_OK;
++  /* Zero all hash-table entries that correspond to frame numbers greater
++  ** than pWal->hdr.mxFrame.
++  */
++  iLimit = pWal->hdr.mxFrame - iZero;
++  assert( iLimit>0 );
++  for(i=0; i<HASHTABLE_NSLOT; i++){
++    if( aHash[i]>iLimit ){
++      aHash[i] = 0;
+     }
+   }
++  
++  /* Zero the entries in the aPgno array that correspond to frames with
++  ** frame numbers greater than pWal->hdr.mxFrame. 
++  */
++  nByte = (int)((char *)aHash - (char *)&aPgno[iLimit+1]);
++  memset((void *)&aPgno[iLimit+1], 0, nByte);
  
--  /* If this is an SQLITE_CHECKPOINT_RESTART operation, and the entire wal
--  ** file has been copied into the database file, then block until all
--  ** readers have finished using the wal file. This ensures that the next
--  ** process to write to the database restarts the wal file.
--  */
+-  /* If this is an SQLITE_CHECKPOINT_RESTART or TRUNCATE operation, and the
+-  ** entire wal file has been copied into the database file, then block 
+-  ** until all readers have finished using the wal file. This ensures that 
+-  ** the next process to write to the database restarts the wal file.
++#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
++  /* Verify that the every entry in the mapping region is still reachable
++  ** via the hash table even after the cleanup.
+   */
 -  if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){
 -    assert( pWal->writeLock );
 -    if( pInfo->nBackfill<pWal->hdr.mxFrame ){
 -      rc = SQLITE_BUSY;
--    }else if( eMode==SQLITE_CHECKPOINT_RESTART ){
--      assert( mxSafeFrame==pWal->hdr.mxFrame );
+-    }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){
+-      u32 salt1;
+-      sqlite3_randomness(4, &salt1);
+-      assert( pInfo->nBackfill==pWal->hdr.mxFrame );
 -      rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1);
 -      if( rc==SQLITE_OK ){
+-        if( eMode==SQLITE_CHECKPOINT_TRUNCATE ){
+-          /* IMPLEMENTATION-OF: R-44699-57140 This mode works the same way as
+-          ** SQLITE_CHECKPOINT_RESTART with the addition that it also
+-          ** truncates the log file to zero bytes just prior to a
+-          ** successful return.
+-          **
+-          ** In theory, it might be safe to do this without updating the
+-          ** wal-index header in shared memory, as all subsequent reader or
+-          ** writer clients should see that the entire log file has been
+-          ** checkpointed and behave accordingly. This seems unsafe though,
+-          ** as it would leave the system in a state where the contents of
+-          ** the wal-index header do not match the contents of the 
+-          ** file-system. To avoid this, update the wal-index header to
+-          ** indicate that the log file contains zero valid frames.  */
+-          walRestartHdr(pWal, salt1);
+-          rc = sqlite3OsTruncate(pWal->pWalFd, 0);
+-        }
 -        walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
--      }
-+    /* Reset the checkpoint-header. This is safe because this thread is 
-+    ** currently holding locks that exclude all other readers, writers and
-+    ** checkpointers.
-+    */
-+    pInfo = walCkptInfo(pWal);
-+    pInfo->nBackfill = 0;
-+    pInfo->aReadMark[0] = 0;
-+    for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
-+    if( pWal->hdr.mxFrame ) pInfo->aReadMark[1] = pWal->hdr.mxFrame;
-+
-+    /* If more than one frame was recovered from the log file, report an
-+    ** event via sqlite3_log(). This is to help with identifying performance
-+    ** problems caused by applications routinely shutting down without
-+    ** checkpointing the log file.
-+    */
-+    if( pWal->hdr.nPage ){
-+      sqlite3_log(SQLITE_NOTICE_RECOVER_WAL,
-+          "recovered %d frames from WAL file %s",
-+          pWal->hdr.mxFrame, pWal->zWalName
-+      );
++  if( iLimit ){
++    int i;           /* Loop counter */
++    int iKey;        /* Hash key */
++    for(i=1; i<=iLimit; i++){
++      for(iKey=walHash(aPgno[i]); aHash[iKey]; iKey=walNextHash(iKey)){
++        if( aHash[iKey]==i ) break;
+       }
++      assert( aHash[iKey]==i );
      }
    }
- 
+-
 - walcheckpoint_out:
 -  walIteratorFree(pIter);
-+recovery_error:
-+  WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok"));
-+  walUnlockExclusive(pWal, iLock, nLock);
-   return rc;
+-  return rc;
++#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
  }
  
- /*
+-/*
 -** If the WAL file is currently larger than nMax bytes in size, truncate
 -** it to exactly nMax bytes. If an error occurs while doing so, ignore it.
 -*/
@@ -6517,10 +39959,11 @@
 -    sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName);
 -  }
 -}
--
--/*
+ 
+ /*
 -** Close a connection to a log file.
-+** Close an open wal-index.
++** Set an entry in the wal-index that will map database page number
++** pPage into WAL frame iFrame.
  */
 -SQLITE_PRIVATE int sqlite3WalClose(
 -  Wal *pWal,                      /* Wal to close */
@@ -6531,7 +39974,12 @@
 -  int rc = SQLITE_OK;
 -  if( pWal ){
 -    int isDelete = 0;             /* True to unlink wal and wal-index files */
--
++static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
++  int rc;                         /* Return code */
++  u32 iZero = 0;                  /* One less than frame number of aPgno[1] */
++  volatile u32 *aPgno = 0;        /* Page number array */
++  volatile ht_slot *aHash = 0;    /* Hash table */
+ 
 -    /* If an EXCLUSIVE lock can be obtained on the database file (using the
 -    ** ordinary, rollback-mode locking methods, this guarantees that the
 -    ** connection associated with this log file is the only connection to
@@ -6539,7 +39987,22 @@
 -    ** the wal and wal-index files.
 -    **
 -    ** The EXCLUSIVE lock is not released before returning.
--    */
++  rc = walHashGet(pWal, walFramePage(iFrame), &aHash, &aPgno, &iZero);
++
++  /* Assuming the wal-index file was successfully mapped, populate the
++  ** page number array and hash table entry.
++  */
++  if( rc==SQLITE_OK ){
++    int iKey;                     /* Hash table key */
++    int idx;                      /* Value to write to hash-table slot */
++    int nCollide;                 /* Number of hash collisions */
++
++    idx = iFrame - iZero;
++    assert( idx <= HASHTABLE_NSLOT/2 + 1 );
++    
++    /* If this is the first entry to be added to this hash-table, zero the
++    ** entire hash table and aPgno[] array before proceeding. 
+     */
 -    rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE);
 -    if( rc==SQLITE_OK ){
 -      if( pWal->exclusiveMode==WAL_NORMAL_MODE ){
@@ -6568,31 +40031,73 @@
 -          walLimitSize(pWal, 0);
 -        }
 -      }
--    }
--
++    if( idx==1 ){
++      int nByte = (int)((u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]);
++      memset((void*)&aPgno[1], 0, nByte);
++    }
++
++    /* If the entry in aPgno[] is already set, then the previous writer
++    ** must have exited unexpectedly in the middle of a transaction (after
++    ** writing one or more dirty pages to the WAL to free up memory). 
++    ** Remove the remnants of that writers uncommitted transaction from 
++    ** the hash-table before writing any new entries.
++    */
++    if( aPgno[idx] ){
++      walCleanupHash(pWal);
++      assert( !aPgno[idx] );
++    }
++
++    /* Write the aPgno[] array entry and the hash-table slot. */
++    nCollide = idx;
++    for(iKey=walHash(iPage); aHash[iKey]; iKey=walNextHash(iKey)){
++      if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT;
+     }
++    aPgno[idx] = iPage;
++    aHash[iKey] = (ht_slot)idx;
+ 
 -    walIndexClose(pWal, isDelete);
 -    sqlite3OsClose(pWal->pWalFd);
 -    if( isDelete ){
 -      sqlite3BeginBenignMalloc();
 -      sqlite3OsDelete(pWal->pVfs, pWal->zWalName, 0);
 -      sqlite3EndBenignMalloc();
-+static void walIndexClose(Wal *pWal, int isDelete){
-+  if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
-+    int i;
-+    for(i=0; i<pWal->nWiData; i++){
-+      sqlite3_free((void *)pWal->apWiData[i]);
-+      pWal->apWiData[i] = 0;
++#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
++    /* Verify that the number of entries in the hash table exactly equals
++    ** the number of entries in the mapping region.
++    */
++    {
++      int i;           /* Loop counter */
++      int nEntry = 0;  /* Number of entries in the hash table */
++      for(i=0; i<HASHTABLE_NSLOT; i++){ if( aHash[i] ) nEntry++; }
++      assert( nEntry==idx );
      }
 -    WALTRACE(("WAL%p: closed\n", pWal));
 -    sqlite3_free((void *)pWal->apWiData);
 -    sqlite3_free(pWal);
-+  }else{
-+    sqlite3OsShmUnmap(pWal->pDbFd, isDelete);
++
++    /* Verify that the every entry in the mapping region is reachable
++    ** via the hash table.  This turns out to be a really, really expensive
++    ** thing to check, so only do this occasionally - not on every
++    ** iteration.
++    */
++    if( (idx&0x3ff)==0 ){
++      int i;           /* Loop counter */
++      for(i=1; i<=idx; i++){
++        for(iKey=walHash(aPgno[i]); aHash[iKey]; iKey=walNextHash(iKey)){
++          if( aHash[iKey]==i ) break;
++        }
++        assert( aHash[iKey]==i );
++      }
++    }
++#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
    }
--  return rc;
++
++
+   return rc;
  }
  
--/*
++
+ /*
 -** Try to read the wal-index header.  Return 0 on success and 1 if
 -** there is a problem.
 -**
@@ -6601,46 +40106,34 @@
 -** read it, which might result in inconsistency.  A dirty read is detected
 -** by verifying that both copies of the header are the same and also by
 -** a checksum on the header.
-+/* 
-+** Open a connection to the WAL file zWalName. The database file must 
-+** already be opened on connection pDbFd. The buffer that zWalName points
-+** to must remain valid for the lifetime of the returned Wal* handle.
- **
+-**
 -** If and only if the read is consistent and the header is different from
 -** pWal->hdr, then pWal->hdr is updated to the content of the new header
 -** and *pChanged is set to 1.
-+** A SHARED lock should be held on the database file when this function
-+** is called. The purpose of this SHARED lock is to prevent any other
-+** client from unlinking the WAL or wal-index file. If another process
-+** were to do this just after this client opened one of these files, the
-+** system would be badly broken.
++** Recover the wal-index by reading the write-ahead log file. 
  **
 -** If the checksum cannot be verified return non-zero. If the header
 -** is read successfully and the checksum verified, return zero.
-+** If the log file is successfully opened, SQLITE_OK is returned and 
-+** *ppWal is set to point to a new WAL handle. If an error occurs,
-+** an SQLite error code is returned and *ppWal is left unmodified.
++** This routine first tries to establish an exclusive lock on the
++** wal-index to prevent other threads/processes from doing anything
++** with the WAL or wal-index while recovery is running.  The
++** WAL_RECOVER_LOCK is also held so that other threads will know
++** that this thread is running recovery.  If unable to establish
++** the necessary locks, this routine returns SQLITE_BUSY.
  */
 -static int walIndexTryHdr(Wal *pWal, int *pChanged){
 -  u32 aCksum[2];                  /* Checksum on the header content */
 -  WalIndexHdr h1, h2;             /* Two copies of the header content */
 -  WalIndexHdr volatile *aHdr;     /* Header in shared memory */
-+SQLITE_PRIVATE int sqlite3WalOpen(
-+  sqlite3_vfs *pVfs,              /* vfs module to open wal and wal-index */
-+  sqlite3_file *pDbFd,            /* The open database file */
-+  const char *zWalName,           /* Name of the WAL file */
-+  int bNoShm,                     /* True to run in heap-memory mode */
-+  i64 mxWalSize,                  /* Truncate WAL to this size on reset */
-+  Wal **ppWal                     /* OUT: Allocated Wal handle */
-+){
-+  int rc;                         /* Return Code */
-+  Wal *pRet;                      /* Object to allocate and return */
-+  int flags;                      /* Flags passed to OsOpen() */
- 
+-
 -  /* The first page of the wal-index must be mapped at this point. */
 -  assert( pWal->nWiData>0 && pWal->apWiData[0] );
-+  assert( zWalName && zWalName[0] );
-+  assert( pDbFd );
++static int walIndexRecover(Wal *pWal){
++  int rc;                         /* Return Code */
++  i64 nSize;                      /* Size of log file */
++  u32 aFrameCksum[2] = {0, 0};
++  int iLock;                      /* Lock offset to lock for checkpoint */
++  int nLock;                      /* Number of locks to hold */
  
 -  /* Read the header. This might happen concurrently with a write to the
 -  ** same area of shared memory on a different CPU in a SMP,
@@ -6651,53 +40144,37 @@
 -  ** When reading, read [0] first then [1].  Writes are in the reverse order.
 -  ** Memory barriers are used to prevent the compiler or the hardware from
 -  ** reordering the reads and writes.
-+  /* In the amalgamation, the os_unix.c and os_win.c source files come before
-+  ** this source file.  Verify that the #defines of the locking byte offsets
-+  ** in os_unix.c and os_win.c agree with the WALINDEX_LOCK_OFFSET value.
++  /* Obtain an exclusive lock on all byte in the locking range not already
++  ** locked by the caller. The caller is guaranteed to have locked the
++  ** WAL_WRITE_LOCK byte, and may have also locked the WAL_CKPT_LOCK byte.
++  ** If successful, the same bytes that are locked here are unlocked before
++  ** this function returns.
    */
 -  aHdr = walIndexHdr(pWal);
 -  memcpy(&h1, (void *)&aHdr[0], sizeof(h1));
 -  walShmBarrier(pWal);
 -  memcpy(&h2, (void *)&aHdr[1], sizeof(h2));
-+#ifdef WIN_SHM_BASE
-+  assert( WIN_SHM_BASE==WALINDEX_LOCK_OFFSET );
-+#endif
-+#ifdef UNIX_SHM_BASE
-+  assert( UNIX_SHM_BASE==WALINDEX_LOCK_OFFSET );
-+#endif
- 
+-
 -  if( memcmp(&h1, &h2, sizeof(h1))!=0 ){
 -    return 1;   /* Dirty read */
 -  }  
 -  if( h1.isInit==0 ){
 -    return 1;   /* Malformed header - probably all zeros */
-+
-+  /* Allocate an instance of struct Wal to return. */
-+  *ppWal = 0;
-+  pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile);
-+  if( !pRet ){
-+    return SQLITE_NOMEM;
-   }
+-  }
 -  walChecksumBytes(1, (u8*)&h1, sizeof(h1)-sizeof(h1.aCksum), 0, aCksum);
 -  if( aCksum[0]!=h1.aCksum[0] || aCksum[1]!=h1.aCksum[1] ){
 -    return 1;   /* Checksum does not match */
-+
-+  pRet->pVfs = pVfs;
-+  pRet->pWalFd = (sqlite3_file *)&pRet[1];
-+  pRet->pDbFd = pDbFd;
-+  pRet->readLock = -1;
-+  pRet->mxWalSize = mxWalSize;
-+  pRet->zWalName = zWalName;
-+  pRet->syncHeader = 1;
-+  pRet->padToSectorBoundary = 1;
-+  pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE);
-+
-+  /* Open file handle on the write-ahead log file. */
-+  flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL);
-+  rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags);
-+  if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){
-+    pRet->readOnly = WAL_RDONLY;
++  assert( pWal->ckptLock==1 || pWal->ckptLock==0 );
++  assert( WAL_ALL_BUT_WRITE==WAL_WRITE_LOCK+1 );
++  assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE );
++  assert( pWal->writeLock );
++  iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock;
++  nLock = SQLITE_SHM_NLOCK - iLock;
++  rc = walLockExclusive(pWal, iLock, nLock, 0);
++  if( rc ){
++    return rc;
    }
++  WALTRACE(("WAL%p: recovery begin...\n", pWal));
  
 -  if( memcmp(&pWal->hdr, &h1, sizeof(WalIndexHdr)) ){
 -    *pChanged = 1;
@@ -6705,55 +40182,50 @@
 -    pWal->szPage = (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
 -    testcase( pWal->szPage<=32768 );
 -    testcase( pWal->szPage>=65536 );
++  memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
++
++  rc = sqlite3OsFileSize(pWal->pWalFd, &nSize);
 +  if( rc!=SQLITE_OK ){
-+    walIndexClose(pRet, 0);
-+    sqlite3OsClose(pRet->pWalFd);
-+    sqlite3_free(pRet);
-+  }else{
-+    int iDC = sqlite3OsDeviceCharacteristics(pDbFd);
-+    if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->syncHeader = 0; }
-+    if( iDC & SQLITE_IOCAP_POWERSAFE_OVERWRITE ){
-+      pRet->padToSectorBoundary = 0;
-+    }
-+    *ppWal = pRet;
-+    WALTRACE(("WAL%d: opened\n", pRet));
++    goto recovery_error;
    }
-+  return rc;
-+}
  
 -  /* The header was successfully read. Return zero. */
 -  return 0;
-+/*
-+** Change the size to which the WAL file is trucated on each reset.
-+*/
-+SQLITE_PRIVATE void sqlite3WalLimit(Wal *pWal, i64 iLimit){
-+  if( pWal ) pWal->mxWalSize = iLimit;
- }
+-}
++  if( nSize>WAL_HDRSIZE ){
++    u8 aBuf[WAL_HDRSIZE];         /* Buffer to load WAL header into */
++    u8 *aFrame = 0;               /* Malloc'd buffer to load entire frame */
++    int szFrame;                  /* Number of bytes in buffer aFrame[] */
++    u8 *aData;                    /* Pointer to data part of aFrame buffer */
++    int iFrame;                   /* Index of last frame read */
++    i64 iOffset;                  /* Next offset to read from log file */
++    int szPage;                   /* Page size according to the log */
++    u32 magic;                    /* Magic value read from WAL header */
++    u32 version;                  /* Magic value read from WAL header */
++    int isValid;                  /* True if this frame is valid */
  
- /*
+-/*
 -** Read the wal-index header from the wal-index and into pWal->hdr.
 -** If the wal-header appears to be corrupt, try to reconstruct the
 -** wal-index from the WAL before returning.
 -**
 -** Set *pChanged to 1 if the wal-index header value in pWal->hdr is
--** changed by this opertion.  If pWal->hdr is unchanged, set *pChanged
+-** changed by this operation.  If pWal->hdr is unchanged, set *pChanged
 -** to 0.
-+** Find the smallest page number out of all pages held in the WAL that
-+** has not been returned by any prior invocation of this method on the
-+** same WalIterator object.   Write into *piFrame the frame index where
-+** that page was last written into the WAL.  Write into *piPage the page
-+** number.
- **
+-**
 -** If the wal-index header is successfully read, return SQLITE_OK. 
 -** Otherwise an SQLite error code.
-+** Return 0 on success.  If there are no pages in the WAL with a page
-+** number larger than *piPage, then return 1.
- */
+-*/
 -static int walIndexReadHdr(Wal *pWal, int *pChanged){
 -  int rc;                         /* Return code */
 -  int badHdr;                     /* True if a header read failed */
 -  volatile u32 *page0;            /* Chunk of wal-index containing header */
--
++    /* Read in the WAL header. */
++    rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0);
++    if( rc!=SQLITE_OK ){
++      goto recovery_error;
++    }
+ 
 -  /* Ensure that page 0 of the wal-index (the page that contains the 
 -  ** wal-index header) is mapped. Return early if an error occurs here.
 -  */
@@ -6763,21 +40235,40 @@
 -    return rc;
 -  };
 -  assert( page0 || pWal->writeLock==0 );
--
++    /* If the database page size is not a power of two, or is greater than
++    ** SQLITE_MAX_PAGE_SIZE, conclude that the WAL file contains no valid 
++    ** data. Similarly, if the 'magic' value is invalid, ignore the whole
++    ** WAL file.
++    */
++    magic = sqlite3Get4byte(&aBuf[0]);
++    szPage = sqlite3Get4byte(&aBuf[8]);
++    if( (magic&0xFFFFFFFE)!=WAL_MAGIC 
++     || szPage&(szPage-1) 
++     || szPage>SQLITE_MAX_PAGE_SIZE 
++     || szPage<512 
++    ){
++      goto finished;
++    }
++    pWal->hdr.bigEndCksum = (u8)(magic&0x00000001);
++    pWal->szPage = szPage;
++    pWal->nCkpt = sqlite3Get4byte(&aBuf[12]);
++    memcpy(&pWal->hdr.aSalt, &aBuf[16], 8);
+ 
 -  /* If the first page of the wal-index has been mapped, try to read the
 -  ** wal-index header immediately, without holding any lock. This usually
 -  ** works, but may fail if the wal-index header is corrupt or currently 
 -  ** being modified by another thread or process.
 -  */
 -  badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1);
-+static int walIteratorNext(
-+  WalIterator *p,               /* Iterator */
-+  u32 *piPage,                  /* OUT: The page number of the next page */
-+  u32 *piFrame                  /* OUT: Wal frame index of next page */
-+){
-+  u32 iMin;                     /* Result pgno must be greater than iMin */
-+  u32 iRet = 0xFFFFFFFF;        /* 0xffffffff is never a valid page number */
-+  int i;                        /* For looping through segments */
++    /* Verify that the WAL header checksum is correct */
++    walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, 
++        aBuf, WAL_HDRSIZE-2*4, 0, pWal->hdr.aFrameCksum
++    );
++    if( pWal->hdr.aFrameCksum[0]!=sqlite3Get4byte(&aBuf[24])
++     || pWal->hdr.aFrameCksum[1]!=sqlite3Get4byte(&aBuf[28])
++    ){
++      goto finished;
++    }
  
 -  /* If the first attempt failed, it might have been due to a race
 -  ** with a writer.  So get a WRITE lock and try again.
@@ -6789,7 +40280,7 @@
 -        walUnlockShared(pWal, WAL_WRITE_LOCK);
 -        rc = SQLITE_READONLY_RECOVERY;
 -      }
--    }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){
+-    }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 1)) ){
 -      pWal->writeLock = 1;
 -      if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
 -        badHdr = walIndexTryHdr(pWal, pChanged);
@@ -6800,80 +40291,55 @@
 -          */
 -          rc = walIndexRecover(pWal);
 -          *pChanged = 1;
-+  iMin = p->iPrior;
-+  assert( iMin<0xffffffff );
-+  for(i=p->nSegment-1; i>=0; i--){
-+    struct WalSegment *pSegment = &p->aSegment[i];
-+    while( pSegment->iNext<pSegment->nEntry ){
-+      u32 iPg = pSegment->aPgno[pSegment->aIndex[pSegment->iNext]];
-+      if( iPg>iMin ){
-+        if( iPg<iRet ){
-+          iRet = iPg;
-+          *piFrame = pSegment->iZero + pSegment->aIndex[pSegment->iNext];
-         }
-+        break;
-       }
--      pWal->writeLock = 0;
--      walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
-+      pSegment->iNext++;
+-        }
++    /* Verify that the version number on the WAL format is one that
++    ** are able to understand */
++    version = sqlite3Get4byte(&aBuf[4]);
++    if( version!=WAL_MAX_VERSION ){
++      rc = SQLITE_CANTOPEN_BKPT;
++      goto finished;
 +    }
-+  }
 +
-+  *piPage = p->iPrior = iRet;
-+  return (iRet==0xFFFFFFFF);
-+}
++    /* Malloc a buffer to read frames into. */
++    szFrame = szPage + WAL_FRAME_HDRSIZE;
++    aFrame = (u8 *)sqlite3_malloc64(szFrame);
++    if( !aFrame ){
++      rc = SQLITE_NOMEM;
++      goto recovery_error;
++    }
++    aData = &aFrame[WAL_FRAME_HDRSIZE];
 +
-+/*
-+** This function merges two sorted lists into a single sorted list.
-+**
-+** aLeft[] and aRight[] are arrays of indices.  The sort key is
-+** aContent[aLeft[]] and aContent[aRight[]].  Upon entry, the following
-+** is guaranteed for all J<K:
-+**
-+**        aContent[aLeft[J]] < aContent[aLeft[K]]
-+**        aContent[aRight[J]] < aContent[aRight[K]]
-+**
-+** This routine overwrites aRight[] with a new (probably longer) sequence
-+** of indices such that the aRight[] contains every index that appears in
-+** either aLeft[] or the old aRight[] and such that the second condition
-+** above is still met.
-+**
-+** The aContent[aLeft[X]] values will be unique for all X.  And the
-+** aContent[aRight[X]] values will be unique too.  But there might be
-+** one or more combinations of X and Y such that
-+**
-+**      aLeft[X]!=aRight[Y]  &&  aContent[aLeft[X]] == aContent[aRight[Y]]
-+**
-+** When that happens, omit the aLeft[X] and use the aRight[Y] index.
-+*/
-+static void walMerge(
-+  const u32 *aContent,            /* Pages in wal - keys for the sort */
-+  ht_slot *aLeft,                 /* IN: Left hand input list */
-+  int nLeft,                      /* IN: Elements in array *paLeft */
-+  ht_slot **paRight,              /* IN/OUT: Right hand input list */
-+  int *pnRight,                   /* IN/OUT: Elements in *paRight */
-+  ht_slot *aTmp                   /* Temporary buffer */
-+){
-+  int iLeft = 0;                  /* Current index in aLeft */
-+  int iRight = 0;                 /* Current index in aRight */
-+  int iOut = 0;                   /* Current index in output buffer */
-+  int nRight = *pnRight;
-+  ht_slot *aRight = *paRight;
++    /* Read all frames from the log file. */
++    iFrame = 0;
++    for(iOffset=WAL_HDRSIZE; (iOffset+szFrame)<=nSize; iOffset+=szFrame){
++      u32 pgno;                   /* Database page number for frame */
++      u32 nTruncate;              /* dbsize field from frame header */
 +
-+  assert( nLeft>0 && nRight>0 );
-+  while( iRight<nRight || iLeft<nLeft ){
-+    ht_slot logpage;
-+    Pgno dbpage;
++      /* Read and decode the next log frame. */
++      iFrame++;
++      rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset);
++      if( rc!=SQLITE_OK ) break;
++      isValid = walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame);
++      if( !isValid ) break;
++      rc = walIndexAppend(pWal, iFrame, pgno);
++      if( rc!=SQLITE_OK ) break;
 +
-+    if( (iLeft<nLeft) 
-+     && (iRight>=nRight || aContent[aLeft[iLeft]]<aContent[aRight[iRight]])
-+    ){
-+      logpage = aLeft[iLeft++];
-+    }else{
-+      logpage = aRight[iRight++];
++      /* If nTruncate is non-zero, this is a commit record. */
++      if( nTruncate ){
++        pWal->hdr.mxFrame = iFrame;
++        pWal->hdr.nPage = nTruncate;
++        pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16));
++        testcase( szPage<=32768 );
++        testcase( szPage>=65536 );
++        aFrameCksum[0] = pWal->hdr.aFrameCksum[0];
++        aFrameCksum[1] = pWal->hdr.aFrameCksum[1];
+       }
+-      pWal->writeLock = 0;
+-      walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
      }
--  }
-+    dbpage = aContent[logpage];
++
++    sqlite3_free(aFrame);
+   }
  
 -  /* If the header is read successfully, check the version number to make
 -  ** sure the wal-index was not constructed with some future format that
@@ -6881,39 +40347,70 @@
 -  */
 -  if( badHdr==0 && pWal->hdr.iVersion!=WALINDEX_MAX_VERSION ){
 -    rc = SQLITE_CANTOPEN_BKPT;
-+    aTmp[iOut++] = logpage;
-+    if( iLeft<nLeft && aContent[aLeft[iLeft]]==dbpage ) iLeft++;
++finished:
++  if( rc==SQLITE_OK ){
++    volatile WalCkptInfo *pInfo;
++    int i;
++    pWal->hdr.aFrameCksum[0] = aFrameCksum[0];
++    pWal->hdr.aFrameCksum[1] = aFrameCksum[1];
++    walIndexWriteHdr(pWal);
 +
-+    assert( iLeft>=nLeft || aContent[aLeft[iLeft]]>dbpage );
-+    assert( iRight>=nRight || aContent[aRight[iRight]]>dbpage );
++    /* Reset the checkpoint-header. This is safe because this thread is 
++    ** currently holding locks that exclude all other readers, writers and
++    ** checkpointers.
++    */
++    pInfo = walCkptInfo(pWal);
++    pInfo->nBackfill = 0;
++    pInfo->aReadMark[0] = 0;
++    for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
++    if( pWal->hdr.mxFrame ) pInfo->aReadMark[1] = pWal->hdr.mxFrame;
++
++    /* If more than one frame was recovered from the log file, report an
++    ** event via sqlite3_log(). This is to help with identifying performance
++    ** problems caused by applications routinely shutting down without
++    ** checkpointing the log file.
++    */
++    if( pWal->hdr.nPage ){
++      sqlite3_log(SQLITE_NOTICE_RECOVER_WAL,
++          "recovered %d frames from WAL file %s",
++          pWal->hdr.mxFrame, pWal->zWalName
++      );
++    }
    }
  
--  return rc;
-+  *paRight = aLeft;
-+  *pnRight = iOut;
-+  memcpy(aLeft, aTmp, sizeof(aTmp[0])*iOut);
++recovery_error:
++  WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok"));
++  walUnlockExclusive(pWal, iLock, nLock);
+   return rc;
  }
  
  /*
 -** This is the value that walTryBeginRead returns when it needs to
 -** be retried.
--*/
++** Close an open wal-index.
+ */
 -#define WAL_RETRY  (-1)
--
++static void walIndexClose(Wal *pWal, int isDelete){
++  if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
++    int i;
++    for(i=0; i<pWal->nWiData; i++){
++      sqlite3_free((void *)pWal->apWiData[i]);
++      pWal->apWiData[i] = 0;
++    }
++  }else{
++    sqlite3OsShmUnmap(pWal->pDbFd, isDelete);
++  }
++}
+ 
 -/*
 -** Attempt to start a read transaction.  This might fail due to a race or
 -** other transient condition.  When that happens, it returns WAL_RETRY to
 -** indicate to the caller that it is safe to retry immediately.
-+** Sort the elements in list aList using aContent[] as the sort key.
-+** Remove elements with duplicate keys, preferring to keep the
-+** larger aList[] values.
- **
+-**
 -** On success return SQLITE_OK.  On a permanent failure (such an
 -** I/O error or an SQLITE_BUSY because another process is running
 -** recovery) return a positive error code.
-+** The aList[] entries are indices into aContent[].  The values in
-+** aList[] are to be sorted so that for all J<K:
- **
+-**
 -** The useWal parameter is true to force the use of the WAL and disable
 -** the case where the WAL is bypassed because it has been completely
 -** checkpointed.  If useWal==0 then this routine calls walIndexReadHdr() 
@@ -6922,8 +40419,7 @@
 -** to the caller that the local paget cache is obsolete and needs to be 
 -** flushed.)  When useWal==1, the wal-index header is assumed to already
 -** be loaded and the pChanged parameter is unused.
-+**      aContent[aList[J]] < aContent[aList[K]]
- **
+-**
 -** The caller must set the cnt parameter to the number of prior calls to
 -** this routine during the current read attempt that returned WAL_RETRY.
 -** This routine will start taking more aggressive measures to clear the
@@ -6934,7 +40430,10 @@
 -** chance that SQLITE_PROTOCOL could be returned because of a run of really
 -** bad luck when there is lots of contention for the wal-index, but that
 -** possibility is so small that it can be safely neglected, we believe.
-+** For any X and Y such that
++/* 
++** Open a connection to the WAL file zWalName. The database file must 
++** already be opened on connection pDbFd. The buffer that zWalName points
++** to must remain valid for the lifetime of the returned Wal* handle.
  **
 -** On success, this routine obtains a read lock on 
 -** WAL_READ_LOCK(pWal->readLock).  The pWal->readLock integer is
@@ -6949,7 +40448,11 @@
 -** this routine will always set pWal->readLock>0 on success.
 -** When the read transaction is completed, the caller must release the
 -** lock on WAL_READ_LOCK(pWal->readLock) and set pWal->readLock to -1.
-+**      aContent[aList[X]] == aContent[aList[Y]]
++** A SHARED lock should be held on the database file when this function
++** is called. The purpose of this SHARED lock is to prevent any other
++** client from unlinking the WAL or wal-index file. If another process
++** were to do this just after this client opened one of these files, the
++** system would be badly broken.
  **
 -** This routine uses the nBackfill and aReadMark[] fields of the header
 -** to select a particular WAL_READ_LOCK() that strives to let the
@@ -6957,8 +40460,9 @@
 -** update values of the aReadMark[] array in the header, but if it does
 -** so it takes care to hold an exclusive lock on the corresponding
 -** WAL_READ_LOCK() while changing values.
-+** Keep the larger of the two values aList[X] and aList[Y] and discard
-+** the smaller.
++** If the log file is successfully opened, SQLITE_OK is returned and 
++** *ppWal is set to point to a new WAL handle. If an error occurs,
++** an SQLite error code is returned and *ppWal is left unmodified.
  */
 -static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
 -  volatile WalCkptInfo *pInfo;    /* Checkpoint information in wal-index */
@@ -6966,24 +40470,21 @@
 -  int mxI;                        /* Index of largest aReadMark[] value */
 -  int i;                          /* Loop counter */
 -  int rc = SQLITE_OK;             /* Return code  */
-+static void walMergesort(
-+  const u32 *aContent,            /* Pages in wal */
-+  ht_slot *aBuffer,               /* Buffer of at least *pnList items to use */
-+  ht_slot *aList,                 /* IN/OUT: List to sort */
-+  int *pnList                     /* IN/OUT: Number of elements in aList[] */
++SQLITE_PRIVATE int sqlite3WalOpen(
++  sqlite3_vfs *pVfs,              /* vfs module to open wal and wal-index */
++  sqlite3_file *pDbFd,            /* The open database file */
++  const char *zWalName,           /* Name of the WAL file */
++  int bNoShm,                     /* True to run in heap-memory mode */
++  i64 mxWalSize,                  /* Truncate WAL to this size on reset */
++  Wal **ppWal                     /* OUT: Allocated Wal handle */
 +){
-+  struct Sublist {
-+    int nList;                    /* Number of elements in aList */
-+    ht_slot *aList;               /* Pointer to sub-list content */
-+  };
++  int rc;                         /* Return Code */
++  Wal *pRet;                      /* Object to allocate and return */
++  int flags;                      /* Flags passed to OsOpen() */
  
 -  assert( pWal->readLock<0 );     /* Not currently locked */
-+  const int nList = *pnList;      /* Size of input list */
-+  int nMerge = 0;                 /* Number of elements in list aMerge */
-+  ht_slot *aMerge = 0;            /* List to be merged */
-+  int iList;                      /* Index into input list */
-+  int iSub = 0;                   /* Index into aSub array */
-+  struct Sublist aSub[13];        /* Array of sub-lists */
++  assert( zWalName && zWalName[0] );
++  assert( pDbFd );
  
 -  /* Take steps to avoid spinning forever if there is a protocol error.
 -  **
@@ -7001,7 +40502,10 @@
 -  ** an subsequent retries, the delays start becoming longer and longer, 
 -  ** so that on the 100th (and last) RETRY we delay for 323 milliseconds.
 -  ** The total delay time before giving up is less than 10 seconds.
--  */
++  /* In the amalgamation, the os_unix.c and os_win.c source files come before
++  ** this source file.  Verify that the #defines of the locking byte offsets
++  ** in os_unix.c and os_win.c agree with the WALINDEX_LOCK_OFFSET value.
+   */
 -  if( cnt>5 ){
 -    int nDelay = 1;                      /* Pause time in microseconds */
 -    if( cnt>100 ){
@@ -7011,9 +40515,12 @@
 -    if( cnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39;
 -    sqlite3OsSleep(pWal->pVfs, nDelay);
 -  }
-+  memset(aSub, 0, sizeof(aSub));
-+  assert( nList<=HASHTABLE_NPAGE && nList>0 );
-+  assert( HASHTABLE_NPAGE==(1<<(ArraySize(aSub)-1)) );
++#ifdef WIN_SHM_BASE
++  assert( WIN_SHM_BASE==WALINDEX_LOCK_OFFSET );
++#endif
++#ifdef UNIX_SHM_BASE
++  assert( UNIX_SHM_BASE==WALINDEX_LOCK_OFFSET );
++#endif
  
 -  if( !useWal ){
 -    rc = walIndexReadHdr(pWal, pChanged);
@@ -7044,18 +40551,8 @@
 -    }
 -    if( rc!=SQLITE_OK ){
 -      return rc;
-+  for(iList=0; iList<nList; iList++){
-+    nMerge = 1;
-+    aMerge = &aList[iList];
-+    for(iSub=0; iList & (1<<iSub); iSub++){
-+      struct Sublist *p = &aSub[iSub];
-+      assert( p->aList && p->nList<=(1<<iSub) );
-+      assert( p->aList==&aList[iList&~((2<<iSub)-1)] );
-+      walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer);
-     }
-+    aSub[iSub].aList = aMerge;
-+    aSub[iSub].nList = nMerge;
-   }
+-    }
+-  }
  
 -  pInfo = walCkptInfo(pWal);
 -  if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame ){
@@ -7070,7 +40567,7 @@
 -        ** may have been appended to the log before READ_LOCK(0) was obtained.
 -        ** When holding READ_LOCK(0), the reader ignores the entire log file,
 -        ** which implies that the database file contains a trustworthy
--        ** snapshoT. Since holding READ_LOCK(0) prevents a checkpoint from
+-        ** snapshot. Since holding READ_LOCK(0) prevents a checkpoint from
 -        ** happening, this is usually correct.
 -        **
 -        ** However, if frames have been appended to the log (or if the log 
@@ -7086,16 +40583,13 @@
 -      return SQLITE_OK;
 -    }else if( rc!=SQLITE_BUSY ){
 -      return rc;
-+  for(iSub++; iSub<ArraySize(aSub); iSub++){
-+    if( nList & (1<<iSub) ){
-+      struct Sublist *p = &aSub[iSub];
-+      assert( p->nList<=(1<<iSub) );
-+      assert( p->aList==&aList[nList&~((2<<iSub)-1)] );
-+      walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer);
-     }
+-    }
++  /* Allocate an instance of struct Wal to return. */
++  *ppWal = 0;
++  pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile);
++  if( !pRet ){
++    return SQLITE_NOMEM;
    }
-+  assert( aMerge==aList );
-+  *pnList = nMerge;
  
 -  /* If we get this far, it means that the reader will want to use
 -  ** the WAL to get at content from recent commits.  The job now is
@@ -7111,15 +40605,29 @@
 -      mxReadMark = thisMark;
 -      mxI = i;
 -    }
--  }
++  pRet->pVfs = pVfs;
++  pRet->pWalFd = (sqlite3_file *)&pRet[1];
++  pRet->pDbFd = pDbFd;
++  pRet->readLock = -1;
++  pRet->mxWalSize = mxWalSize;
++  pRet->zWalName = zWalName;
++  pRet->syncHeader = 1;
++  pRet->padToSectorBoundary = 1;
++  pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE);
++
++  /* Open file handle on the write-ahead log file. */
++  flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL);
++  rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags);
++  if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){
++    pRet->readOnly = WAL_RDONLY;
+   }
 -  /* There was once an "if" here. The extra "{" is to preserve indentation. */
-+#ifdef SQLITE_DEBUG
-   {
+-  {
 -    if( (pWal->readOnly & WAL_SHM_RDONLY)==0
 -     && (mxReadMark<pWal->hdr.mxFrame || mxI==0)
 -    ){
 -      for(i=1; i<WAL_NREADER; i++){
--        rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
+-        rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1, 0);
 -        if( rc==SQLITE_OK ){
 -          mxReadMark = pInfo->aReadMark[i] = pWal->hdr.mxFrame;
 -          mxI = i;
@@ -7134,7 +40642,7 @@
 -      assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 );
 -      return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK;
 -    }
--
+ 
 -    rc = walLockShared(pWal, WAL_READ_LOCK(mxI));
 -    if( rc ){
 -      return rc==SQLITE_BUSY ? WAL_RETRY : rc;
@@ -7168,15 +40676,23 @@
 -    }else{
 -      assert( mxReadMark<=pWal->hdr.mxFrame );
 -      pWal->readLock = (i16)mxI;
-+    int i;
-+    for(i=1; i<*pnList; i++){
-+      assert( aContent[aList[i]] > aContent[aList[i-1]] );
++  if( rc!=SQLITE_OK ){
++    walIndexClose(pRet, 0);
++    sqlite3OsClose(pRet->pWalFd);
++    sqlite3_free(pRet);
++  }else{
++    int iDC = sqlite3OsDeviceCharacteristics(pDbFd);
++    if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->syncHeader = 0; }
++    if( iDC & SQLITE_IOCAP_POWERSAFE_OVERWRITE ){
++      pRet->padToSectorBoundary = 0;
      }
++    *ppWal = pRet;
++    WALTRACE(("WAL%d: opened\n", pRet));
    }
--  return rc;
--}
--
--/*
+   return rc;
+ }
+ 
+ /*
 -** Begin a read transaction on the database.
 -**
 -** This routine used to be called sqlite3OpenSnapshot() and with good reason:
@@ -7189,7 +40705,8 @@
 -** transaction, then *pChanged is set to 1 before returning.  The
 -** Pager layer will use this to know that is cache is stale and
 -** needs to be flushed.
--*/
++** Change the size to which the WAL file is trucated on each reset.
+ */
 -SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
 -  int rc;                         /* Return code */
 -  int cnt = 0;                    /* Number of TryBeginRead attempts */
@@ -7202,87 +40719,137 @@
 -  testcase( rc==SQLITE_PROTOCOL );
 -  testcase( rc==SQLITE_OK );
 -  return rc;
-+#endif
++SQLITE_PRIVATE void sqlite3WalLimit(Wal *pWal, i64 iLimit){
++  if( pWal ) pWal->mxWalSize = iLimit;
  }
  
--/*
+ /*
 -** Finish with a read transaction.  All this does is release the
 -** read-lock.
-+/* 
-+** Free an iterator allocated by walIteratorInit().
++** Find the smallest page number out of all pages held in the WAL that
++** has not been returned by any prior invocation of this method on the
++** same WalIterator object.   Write into *piFrame the frame index where
++** that page was last written into the WAL.  Write into *piPage the page
++** number.
++**
++** Return 0 on success.  If there are no pages in the WAL with a page
++** number larger than *piPage, then return 1.
  */
 -SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){
 -  sqlite3WalEndWriteTransaction(pWal);
 -  if( pWal->readLock>=0 ){
 -    walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
 -    pWal->readLock = -1;
--  }
-+static void walIteratorFree(WalIterator *p){
-+  sqlite3ScratchFree(p);
++static int walIteratorNext(
++  WalIterator *p,               /* Iterator */
++  u32 *piPage,                  /* OUT: The page number of the next page */
++  u32 *piFrame                  /* OUT: Wal frame index of next page */
++){
++  u32 iMin;                     /* Result pgno must be greater than iMin */
++  u32 iRet = 0xFFFFFFFF;        /* 0xffffffff is never a valid page number */
++  int i;                        /* For looping through segments */
++
++  iMin = p->iPrior;
++  assert( iMin<0xffffffff );
++  for(i=p->nSegment-1; i>=0; i--){
++    struct WalSegment *pSegment = &p->aSegment[i];
++    while( pSegment->iNext<pSegment->nEntry ){
++      u32 iPg = pSegment->aPgno[pSegment->aIndex[pSegment->iNext]];
++      if( iPg>iMin ){
++        if( iPg<iRet ){
++          iRet = iPg;
++          *piFrame = pSegment->iZero + pSegment->aIndex[pSegment->iNext];
++        }
++        break;
++      }
++      pSegment->iNext++;
++    }
+   }
++
++  *piPage = p->iPrior = iRet;
++  return (iRet==0xFFFFFFFF);
  }
  
  /*
 -** Search the wal file for page pgno. If found, set *piRead to the frame that
 -** contains the page. Otherwise, if pgno is not in the wal file, set *piRead
 -** to zero.
-+** Construct a WalInterator object that can be used to loop over all 
-+** pages in the WAL in ascending order. The caller must hold the checkpoint
-+** lock.
++** This function merges two sorted lists into a single sorted list.
  **
 -** Return SQLITE_OK if successful, or an error code if an error occurs. If an
 -** error does occur, the final value of *piRead is undefined.
-+** On success, make *pp point to the newly allocated WalInterator object
-+** return SQLITE_OK. Otherwise, return an error code. If this routine
-+** returns an error, the value of *pp is undefined.
++** aLeft[] and aRight[] are arrays of indices.  The sort key is
++** aContent[aLeft[]] and aContent[aRight[]].  Upon entry, the following
++** is guaranteed for all J<K:
 +**
-+** The calling routine should invoke walIteratorFree() to destroy the
-+** WalIterator object when it has finished with it.
++**        aContent[aLeft[J]] < aContent[aLeft[K]]
++**        aContent[aRight[J]] < aContent[aRight[K]]
++**
++** This routine overwrites aRight[] with a new (probably longer) sequence
++** of indices such that the aRight[] contains every index that appears in
++** either aLeft[] or the old aRight[] and such that the second condition
++** above is still met.
++**
++** The aContent[aLeft[X]] values will be unique for all X.  And the
++** aContent[aRight[X]] values will be unique too.  But there might be
++** one or more combinations of X and Y such that
++**
++**      aLeft[X]!=aRight[Y]  &&  aContent[aLeft[X]] == aContent[aRight[Y]]
++**
++** When that happens, omit the aLeft[X] and use the aRight[Y] index.
  */
 -SQLITE_PRIVATE int sqlite3WalFindFrame(
 -  Wal *pWal,                      /* WAL handle */
 -  Pgno pgno,                      /* Database page number to read data for */
 -  u32 *piRead                     /* OUT: Frame number (or zero) */
--){
++static void walMerge(
++  const u32 *aContent,            /* Pages in wal - keys for the sort */
++  ht_slot *aLeft,                 /* IN: Left hand input list */
++  int nLeft,                      /* IN: Elements in array *paLeft */
++  ht_slot **paRight,              /* IN/OUT: Right hand input list */
++  int *pnRight,                   /* IN/OUT: Elements in *paRight */
++  ht_slot *aTmp                   /* Temporary buffer */
+ ){
 -  u32 iRead = 0;                  /* If !=0, WAL frame to return data from */
 -  u32 iLast = pWal->hdr.mxFrame;  /* Last page in WAL for this reader */
 -  int iHash;                      /* Used to loop through N hash tables */
--
++  int iLeft = 0;                  /* Current index in aLeft */
++  int iRight = 0;                 /* Current index in aRight */
++  int iOut = 0;                   /* Current index in output buffer */
++  int nRight = *pnRight;
++  ht_slot *aRight = *paRight;
+ 
 -  /* This routine is only be called from within a read transaction. */
 -  assert( pWal->readLock>=0 || pWal->lockError );
-+static int walIteratorInit(Wal *pWal, WalIterator **pp){
-+  WalIterator *p;                 /* Return value */
-+  int nSegment;                   /* Number of segments to merge */
-+  u32 iLast;                      /* Last frame in log */
-+  int nByte;                      /* Number of bytes to allocate */
-+  int i;                          /* Iterator variable */
-+  ht_slot *aTmp;                  /* Temp space used by merge-sort */
-+  int rc = SQLITE_OK;             /* Return Code */
++  assert( nLeft>0 && nRight>0 );
++  while( iRight<nRight || iLeft<nLeft ){
++    ht_slot logpage;
++    Pgno dbpage;
  
 -  /* If the "last page" field of the wal-index header snapshot is 0, then
 -  ** no data will be read from the wal under any circumstances. Return early
 -  ** in this case as an optimization.  Likewise, if pWal->readLock==0, 
 -  ** then the WAL is ignored by the reader so return early, as if the 
 -  ** WAL were empty.
-+  /* This routine only runs while holding the checkpoint lock. And
-+  ** it only runs if there is actually content in the log (mxFrame>0).
-   */
+-  */
 -  if( iLast==0 || pWal->readLock==0 ){
 -    *piRead = 0;
 -    return SQLITE_OK;
-+  assert( pWal->ckptLock && pWal->hdr.mxFrame>0 );
-+  iLast = pWal->hdr.mxFrame;
++    if( (iLeft<nLeft) 
++     && (iRight>=nRight || aContent[aLeft[iLeft]]<aContent[aRight[iRight]])
++    ){
++      logpage = aLeft[iLeft++];
++    }else{
++      logpage = aRight[iRight++];
++    }
++    dbpage = aContent[logpage];
 +
-+  /* Allocate space for the WalIterator object. */
-+  nSegment = walFramePage(iLast) + 1;
-+  nByte = sizeof(WalIterator) 
-+        + (nSegment-1)*sizeof(struct WalSegment)
-+        + iLast*sizeof(ht_slot);
-+  p = (WalIterator *)sqlite3ScratchMalloc(nByte);
-+  if( !p ){
-+    return SQLITE_NOMEM;
++    aTmp[iOut++] = logpage;
++    if( iLeft<nLeft && aContent[aLeft[iLeft]]==dbpage ) iLeft++;
++
++    assert( iLeft>=nLeft || aContent[aLeft[iLeft]]>dbpage );
++    assert( iRight>=nRight || aContent[aRight[iRight]]>dbpage );
    }
-+  memset(p, 0, nByte);
-+  p->nSegment = nSegment;
  
 -  /* Search the hash table or tables for an entry matching page number
 -  ** pgno. Each iteration of the following for() loop searches one
@@ -7308,9 +40875,7 @@
 -  **   (iFrame<=iLast): 
 -  **     This condition filters out entries that were added to the hash
 -  **     table after the current read-transaction had started.
-+  /* Allocate temporary space used by the merge-sort routine. This block
-+  ** of memory will be freed before this function returns.
-   */
+-  */
 -  for(iHash=walFramePage(iLast); iHash>=0 && iRead==0; iHash--){
 -    volatile ht_slot *aHash;      /* Pointer to hash table */
 -    volatile u32 *aPgno;          /* Pointer to array of page numbers */
@@ -7318,62 +40883,93 @@
 -    int iKey;                     /* Hash slot index */
 -    int nCollide;                 /* Number of hash collisions remaining */
 -    int rc;                       /* Error code */
-+  aTmp = (ht_slot *)sqlite3ScratchMalloc(
-+      sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
-+  );
-+  if( !aTmp ){
-+    rc = SQLITE_NOMEM;
-+  }
++  *paRight = aLeft;
++  *pnRight = iOut;
++  memcpy(aLeft, aTmp, sizeof(aTmp[0])*iOut);
++}
  
 -    rc = walHashGet(pWal, iHash, &aHash, &aPgno, &iZero);
 -    if( rc!=SQLITE_OK ){
 -      return rc;
--    }
++/*
++** Sort the elements in list aList using aContent[] as the sort key.
++** Remove elements with duplicate keys, preferring to keep the
++** larger aList[] values.
++**
++** The aList[] entries are indices into aContent[].  The values in
++** aList[] are to be sorted so that for all J<K:
++**
++**      aContent[aList[J]] < aContent[aList[K]]
++**
++** For any X and Y such that
++**
++**      aContent[aList[X]] == aContent[aList[Y]]
++**
++** Keep the larger of the two values aList[X] and aList[Y] and discard
++** the smaller.
++*/
++static void walMergesort(
++  const u32 *aContent,            /* Pages in wal */
++  ht_slot *aBuffer,               /* Buffer of at least *pnList items to use */
++  ht_slot *aList,                 /* IN/OUT: List to sort */
++  int *pnList                     /* IN/OUT: Number of elements in aList[] */
++){
++  struct Sublist {
++    int nList;                    /* Number of elements in aList */
++    ht_slot *aList;               /* Pointer to sub-list content */
++  };
++
++  const int nList = *pnList;      /* Size of input list */
++  int nMerge = 0;                 /* Number of elements in list aMerge */
++  ht_slot *aMerge = 0;            /* List to be merged */
++  int iList;                      /* Index into input list */
++  int iSub = 0;                   /* Index into aSub array */
++  struct Sublist aSub[13];        /* Array of sub-lists */
++
++  memset(aSub, 0, sizeof(aSub));
++  assert( nList<=HASHTABLE_NPAGE && nList>0 );
++  assert( HASHTABLE_NPAGE==(1<<(ArraySize(aSub)-1)) );
++
++  for(iList=0; iList<nList; iList++){
++    nMerge = 1;
++    aMerge = &aList[iList];
++    for(iSub=0; iList & (1<<iSub); iSub++){
++      struct Sublist *p = &aSub[iSub];
++      assert( p->aList && p->nList<=(1<<iSub) );
++      assert( p->aList==&aList[iList&~((2<<iSub)-1)] );
++      walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer);
+     }
 -    nCollide = HASHTABLE_NSLOT;
 -    for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){
 -      u32 iFrame = aHash[iKey] + iZero;
 -      if( iFrame<=iLast && aPgno[aHash[iKey]]==pgno ){
--        /* assert( iFrame>iRead ); -- not true if there is corruption */
+-        assert( iFrame>iRead || CORRUPT_DB );
 -        iRead = iFrame;
-+  for(i=0; rc==SQLITE_OK && i<nSegment; i++){
-+    volatile ht_slot *aHash;
-+    u32 iZero;
-+    volatile u32 *aPgno;
-+
-+    rc = walHashGet(pWal, i, &aHash, &aPgno, &iZero);
-+    if( rc==SQLITE_OK ){
-+      int j;                      /* Counter variable */
-+      int nEntry;                 /* Number of entries in this segment */
-+      ht_slot *aIndex;            /* Sorted index for this segment */
-+
-+      aPgno++;
-+      if( (i+1)==nSegment ){
-+        nEntry = (int)(iLast - iZero);
-+      }else{
-+        nEntry = (int)((u32*)aHash - (u32*)aPgno);
-       }
+-      }
 -      if( (nCollide--)==0 ){
 -        return SQLITE_CORRUPT_BKPT;
-+      aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[iZero];
-+      iZero++;
-+  
-+      for(j=0; j<nEntry; j++){
-+        aIndex[j] = (ht_slot)j;
-       }
-+      walMergesort((u32 *)aPgno, aTmp, aIndex, &nEntry);
-+      p->aSegment[i].iZero = iZero;
-+      p->aSegment[i].nEntry = nEntry;
-+      p->aSegment[i].aIndex = aIndex;
-+      p->aSegment[i].aPgno = (u32 *)aPgno;
+-      }
++    aSub[iSub].aList = aMerge;
++    aSub[iSub].nList = nMerge;
++  }
++
++  for(iSub++; iSub<ArraySize(aSub); iSub++){
++    if( nList & (1<<iSub) ){
++      struct Sublist *p = &aSub[iSub];
++      assert( p->nList<=(1<<iSub) );
++      assert( p->aList==&aList[nList&~((2<<iSub)-1)] );
++      walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer);
      }
    }
-+  sqlite3ScratchFree(aTmp);
++  assert( aMerge==aList );
++  *pnList = nMerge;
  
 -#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
 -  /* If expensive assert() statements are available, do a linear search
 -  ** of the wal-index file content. Make sure the results agree with the
 -  ** result obtained using the hash indexes above.  */
--  {
++#ifdef SQLITE_DEBUG
+   {
 -    u32 iRead2 = 0;
 -    u32 iTest;
 -    for(iTest=iLast; iTest>0; iTest--){
@@ -7381,28 +40977,23 @@
 -        iRead2 = iTest;
 -        break;
 -      }
--    }
++    int i;
++    for(i=1; i<*pnList; i++){
++      assert( aContent[aList[i]] > aContent[aList[i-1]] );
+     }
 -    assert( iRead==iRead2 );
-+  if( rc!=SQLITE_OK ){
-+    walIteratorFree(p);
    }
--#endif
+ #endif
 -
 -  *piRead = iRead;
 -  return SQLITE_OK;
-+  *pp = p;
-+  return rc;
- }
- 
- /*
+-}
+-
+-/*
 -** Read the contents of frame iRead from the wal file into buffer pOut
 -** (which is nOut bytes in size). Return SQLITE_OK if successful, or an
 -** error code otherwise.
-+** Attempt to obtain the exclusive WAL lock defined by parameters lockIdx and
-+** n. If the attempt fails and parameter xBusy is not NULL, then it is a
-+** busy-handler function. Invoke it and retry the lock until either the
-+** lock is successfully obtained or the busy-handler returns 0.
- */
+-*/
 -SQLITE_PRIVATE int sqlite3WalReadFrame(
 -  Wal *pWal,                      /* WAL handle */
 -  u32 iRead,                      /* Frame to read */
@@ -7418,168 +41009,188 @@
 -  iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE;
 -  /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
 -  return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset);
-+static int walBusyLock(
-+  Wal *pWal,                      /* WAL connection */
-+  int (*xBusy)(void*),            /* Function to call when busy */
-+  void *pBusyArg,                 /* Context argument for xBusyHandler */
-+  int lockIdx,                    /* Offset of first byte to lock */
-+  int n                           /* Number of bytes to lock */
-+){
-+  int rc;
-+  do {
-+    rc = walLockExclusive(pWal, lockIdx, n);
-+  }while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) );
-+  return rc;
  }
  
--/* 
+ /* 
 -** Return the size of the database in pages (or zero, if unknown).
-+/*
-+** The cache of the wal-index header must be valid to call this function.
-+** Return the page-size in bytes used by the database.
++** Free an iterator allocated by walIteratorInit().
  */
 -SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal){
 -  if( pWal && ALWAYS(pWal->readLock>=0) ){
 -    return pWal->hdr.nPage;
 -  }
 -  return 0;
-+static int walPagesize(Wal *pWal){
-+  return (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
++static void walIteratorFree(WalIterator *p){
++  sqlite3_free(p);
  }
  
 -
 -/* 
 -** This function starts a write transaction on the WAL.
-+/*
-+** Copy as much content as we can from the WAL back into the database file
-+** in response to an sqlite3_wal_checkpoint() request or the equivalent.
- **
+-**
 -** A read transaction must have already been started by a prior call
 -** to sqlite3WalBeginReadTransaction().
-+** The amount of information copies from WAL to database might be limited
-+** by active readers.  This routine will never overwrite a database page
-+** that a concurrent reader might be using.
++/*
++** Construct a WalInterator object that can be used to loop over all 
++** pages in the WAL in ascending order. The caller must hold the checkpoint
++** lock.
  **
 -** If another thread or process has written into the database since
 -** the read transaction was started, then it is not possible for this
 -** thread to write as doing so would cause a fork.  So this routine
 -** returns SQLITE_BUSY in that case and no write transaction is started.
-+** All I/O barrier operations (a.k.a fsyncs) occur in this routine when
-+** SQLite is in WAL-mode in synchronous=NORMAL.  That means that if 
-+** checkpoints are always run by a background thread or background 
-+** process, foreground threads will never block on a lengthy fsync call.
++** On success, make *pp point to the newly allocated WalInterator object
++** return SQLITE_OK. Otherwise, return an error code. If this routine
++** returns an error, the value of *pp is undefined.
  **
 -** There can only be a single writer active at a time.
-+** Fsync is called on the WAL before writing content out of the WAL and
-+** into the database.  This ensures that if the new content is persistent
-+** in the WAL and can be recovered following a power-loss or hard reset.
-+**
-+** Fsync is also called on the database file if (and only if) the entire
-+** WAL content is copied into the database file.  This second fsync makes
-+** it safe to delete the WAL since the new content will persist in the
-+** database file.
-+**
-+** This routine uses and updates the nBackfill field of the wal-index header.
-+** This is the only routine tha will increase the value of nBackfill.  
-+** (A WAL reset or recovery will revert nBackfill to zero, but not increase
-+** its value.)
-+**
-+** The caller must be holding sufficient locks to ensure that no other
-+** checkpoint is running (in any other thread or process) at the same
-+** time.
++** The calling routine should invoke walIteratorFree() to destroy the
++** WalIterator object when it has finished with it.
  */
 -SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){
 -  int rc;
--
++static int walIteratorInit(Wal *pWal, WalIterator **pp){
++  WalIterator *p;                 /* Return value */
++  int nSegment;                   /* Number of segments to merge */
++  u32 iLast;                      /* Last frame in log */
++  int nByte;                      /* Number of bytes to allocate */
++  int i;                          /* Iterator variable */
++  ht_slot *aTmp;                  /* Temp space used by merge-sort */
++  int rc = SQLITE_OK;             /* Return Code */
+ 
 -  /* Cannot start a write transaction without first holding a read
 -  ** transaction. */
 -  assert( pWal->readLock>=0 );
-+static int walCheckpoint(
-+  Wal *pWal,                      /* Wal connection */
-+  int eMode,                      /* One of PASSIVE, FULL or RESTART */
-+  int (*xBusyCall)(void*),        /* Function to call when busy */
-+  void *pBusyArg,                 /* Context argument for xBusyHandler */
-+  int sync_flags,                 /* Flags for OsSync() (or 0) */
-+  u8 *zBuf                        /* Temporary buffer to use */
-+){
-+  int rc;                         /* Return code */
-+  int szPage;                     /* Database page-size */
-+  WalIterator *pIter = 0;         /* Wal iterator context */
-+  u32 iDbpage = 0;                /* Next database page to write */
-+  u32 iFrame = 0;                 /* Wal frame containing data for iDbpage */
-+  u32 mxSafeFrame;                /* Max frame that can be backfilled */
-+  u32 mxPage;                     /* Max database page to write */
-+  int i;                          /* Loop counter */
-+  volatile WalCkptInfo *pInfo;    /* The checkpoint status information */
-+  int (*xBusy)(void*) = 0;        /* Function to call when waiting for locks */
++  /* This routine only runs while holding the checkpoint lock. And
++  ** it only runs if there is actually content in the log (mxFrame>0).
++  */
++  assert( pWal->ckptLock && pWal->hdr.mxFrame>0 );
++  iLast = pWal->hdr.mxFrame;
  
 -  if( pWal->readOnly ){
 -    return SQLITE_READONLY;
--  }
-+  szPage = walPagesize(pWal);
-+  testcase( szPage<=32768 );
-+  testcase( szPage>=65536 );
-+  pInfo = walCkptInfo(pWal);
-+  if( pInfo->nBackfill>=pWal->hdr.mxFrame ) return SQLITE_OK;
++  /* Allocate space for the WalIterator object. */
++  nSegment = walFramePage(iLast) + 1;
++  nByte = sizeof(WalIterator) 
++        + (nSegment-1)*sizeof(struct WalSegment)
++        + iLast*sizeof(ht_slot);
++  p = (WalIterator *)sqlite3_malloc64(nByte);
++  if( !p ){
++    return SQLITE_NOMEM;
+   }
++  memset(p, 0, nByte);
++  p->nSegment = nSegment;
  
 -  /* Only one writer allowed at a time.  Get the write lock.  Return
 -  ** SQLITE_BUSY if unable.
--  */
--  rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
++  /* Allocate temporary space used by the merge-sort routine. This block
++  ** of memory will be freed before this function returns.
+   */
+-  rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 0);
 -  if( rc ){
-+  /* Allocate the iterator */
-+  rc = walIteratorInit(pWal, &pIter);
-+  if( rc!=SQLITE_OK ){
-     return rc;
+-    return rc;
++  aTmp = (ht_slot *)sqlite3_malloc64(
++      sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast)
++  );
++  if( !aTmp ){
++    rc = SQLITE_NOMEM;
    }
 -  pWal->writeLock = 1;
-+  assert( pIter );
  
 -  /* If another connection has written to the database file since the
 -  ** time the read transaction on this connection was started, then
 -  ** the write is disallowed.
-+  if( eMode!=SQLITE_CHECKPOINT_PASSIVE ) xBusy = xBusyCall;
-+
-+  /* Compute in mxSafeFrame the index of the last frame of the WAL that is
-+  ** safe to write into the database.  Frames beyond mxSafeFrame might
-+  ** overwrite database pages that are in use by active readers and thus
-+  ** cannot be backfilled from the WAL.
-   */
+-  */
 -  if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){
 -    walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
 -    pWal->writeLock = 0;
 -    rc = SQLITE_BUSY_SNAPSHOT;
-+  mxSafeFrame = pWal->hdr.mxFrame;
-+  mxPage = pWal->hdr.nPage;
-+  for(i=1; i<WAL_NREADER; i++){
-+    u32 y = pInfo->aReadMark[i];
-+    if( mxSafeFrame>y ){
-+      assert( y<=pWal->hdr.mxFrame );
-+      rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
-+      if( rc==SQLITE_OK ){
-+        pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
-+        walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
-+      }else if( rc==SQLITE_BUSY ){
-+        mxSafeFrame = y;
-+        xBusy = 0;
++  for(i=0; rc==SQLITE_OK && i<nSegment; i++){
++    volatile ht_slot *aHash;
++    u32 iZero;
++    volatile u32 *aPgno;
++
++    rc = walHashGet(pWal, i, &aHash, &aPgno, &iZero);
++    if( rc==SQLITE_OK ){
++      int j;                      /* Counter variable */
++      int nEntry;                 /* Number of entries in this segment */
++      ht_slot *aIndex;            /* Sorted index for this segment */
++
++      aPgno++;
++      if( (i+1)==nSegment ){
++        nEntry = (int)(iLast - iZero);
 +      }else{
-+        goto walcheckpoint_out;
++        nEntry = (int)((u32*)aHash - (u32*)aPgno);
 +      }
++      aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[iZero];
++      iZero++;
++  
++      for(j=0; j<nEntry; j++){
++        aIndex[j] = (ht_slot)j;
++      }
++      walMergesort((u32 *)aPgno, aTmp, aIndex, &nEntry);
++      p->aSegment[i].iZero = iZero;
++      p->aSegment[i].nEntry = nEntry;
++      p->aSegment[i].aIndex = aIndex;
++      p->aSegment[i].aPgno = (u32 *)aPgno;
 +    }
++  }
++  sqlite3_free(aTmp);
++
++  if( rc!=SQLITE_OK ){
++    walIteratorFree(p);
    }
++  *pp = p;
++  return rc;
++}
  
--  return rc;
--}
-+  if( pInfo->nBackfill<mxSafeFrame
-+   && (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0), 1))==SQLITE_OK
-+  ){
-+    i64 nSize;                    /* Current size of database file */
-+    u32 nBackfill = pInfo->nBackfill;
++/*
++** Attempt to obtain the exclusive WAL lock defined by parameters lockIdx and
++** n. If the attempt fails and parameter xBusy is not NULL, then it is a
++** busy-handler function. Invoke it and retry the lock until either the
++** lock is successfully obtained or the busy-handler returns 0.
++*/
++static int walBusyLock(
++  Wal *pWal,                      /* WAL connection */
++  int (*xBusy)(void*),            /* Function to call when busy */
++  void *pBusyArg,                 /* Context argument for xBusyHandler */
++  int lockIdx,                    /* Offset of first byte to lock */
++  int n                           /* Number of bytes to lock */
++){
++  int rc;
++  do {
++    rc = walLockExclusive(pWal, lockIdx, n, 0);
++  }while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) );
+   return rc;
+ }
  
--/*
+ /*
 -** End a write transaction.  The commit has already been done.  This
 -** routine merely releases the lock.
--*/
++** The cache of the wal-index header must be valid to call this function.
++** Return the page-size in bytes used by the database.
++*/
++static int walPagesize(Wal *pWal){
++  return (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
++}
++
++/*
++** The following is guaranteed when this function is called:
++**
++**   a) the WRITER lock is held,
++**   b) the entire log file has been checkpointed, and
++**   c) any existing readers are reading exclusively from the database
++**      file - there are no readers that may attempt to read a frame from
++**      the log file.
++**
++** This function updates the shared-memory structures so that the next
++** client to write to the database (which may be this one) does so by
++** writing frames into the start of the log file.
++**
++** The value of parameter salt1 is used as the aSalt[1] value in the 
++** new wal-index header. It should be passed a pseudo-random value (i.e. 
++** one obtained from sqlite3_randomness()).
+ */
 -SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal){
 -  if( pWal->writeLock ){
 -    walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
@@ -7587,24 +41198,60 @@
 -    pWal->truncateOnCommit = 0;
 -  }
 -  return SQLITE_OK;
--}
-+    /* Sync the WAL to disk */
-+    if( sync_flags ){
-+      rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
-+    }
++static void walRestartHdr(Wal *pWal, u32 salt1){
++  volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
++  int i;                          /* Loop counter */
++  u32 *aSalt = pWal->hdr.aSalt;   /* Big-endian salt values */
++  pWal->nCkpt++;
++  pWal->hdr.mxFrame = 0;
++  sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
++  memcpy(&pWal->hdr.aSalt[1], &salt1, 4);
++  walIndexWriteHdr(pWal);
++  pInfo->nBackfill = 0;
++  pInfo->aReadMark[1] = 0;
++  for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
++  assert( pInfo->aReadMark[0]==0 );
+ }
  
--/*
+ /*
 -** If any data has been written (but not committed) to the log file, this
 -** function moves the write-pointer back to the start of the transaction.
--**
++** Copy as much content as we can from the WAL back into the database file
++** in response to an sqlite3_wal_checkpoint() request or the equivalent.
+ **
 -** Additionally, the callback function is invoked for each frame written
 -** to the WAL since the start of the transaction. If the callback returns
 -** other than SQLITE_OK, it is not invoked again and the error code is
 -** returned to the caller.
--**
++** The amount of information copies from WAL to database might be limited
++** by active readers.  This routine will never overwrite a database page
++** that a concurrent reader might be using.
+ **
 -** Otherwise, if the callback function does not return an error, this
 -** function returns SQLITE_OK.
--*/
++** All I/O barrier operations (a.k.a fsyncs) occur in this routine when
++** SQLite is in WAL-mode in synchronous=NORMAL.  That means that if 
++** checkpoints are always run by a background thread or background 
++** process, foreground threads will never block on a lengthy fsync call.
++**
++** Fsync is called on the WAL before writing content out of the WAL and
++** into the database.  This ensures that if the new content is persistent
++** in the WAL and can be recovered following a power-loss or hard reset.
++**
++** Fsync is also called on the database file if (and only if) the entire
++** WAL content is copied into the database file.  This second fsync makes
++** it safe to delete the WAL since the new content will persist in the
++** database file.
++**
++** This routine uses and updates the nBackfill field of the wal-index header.
++** This is the only routine that will increase the value of nBackfill.  
++** (A WAL reset or recovery will revert nBackfill to zero, but not increase
++** its value.)
++**
++** The caller must be holding sufficient locks to ensure that no other
++** checkpoint is running (in any other thread or process) at the same
++** time.
+ */
 -SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){
 -  int rc = SQLITE_OK;
 -  if( ALWAYS(pWal->writeLock) ){
@@ -7613,15 +41260,80 @@
 -  
 -    /* Restore the clients cache of the wal-index header to the state it
 -    ** was in before the client began writing to the database. 
-+    /* If the database may grow as a result of this checkpoint, hint
-+    ** about the eventual size of the db file to the VFS layer.
++static int walCheckpoint(
++  Wal *pWal,                      /* Wal connection */
++  int eMode,                      /* One of PASSIVE, FULL or RESTART */
++  int (*xBusy)(void*),            /* Function to call when busy */
++  void *pBusyArg,                 /* Context argument for xBusyHandler */
++  int sync_flags,                 /* Flags for OsSync() (or 0) */
++  u8 *zBuf                        /* Temporary buffer to use */
++){
++  int rc = SQLITE_OK;             /* Return code */
++  int szPage;                     /* Database page-size */
++  WalIterator *pIter = 0;         /* Wal iterator context */
++  u32 iDbpage = 0;                /* Next database page to write */
++  u32 iFrame = 0;                 /* Wal frame containing data for iDbpage */
++  u32 mxSafeFrame;                /* Max frame that can be backfilled */
++  u32 mxPage;                     /* Max database page to write */
++  int i;                          /* Loop counter */
++  volatile WalCkptInfo *pInfo;    /* The checkpoint status information */
++
++  szPage = walPagesize(pWal);
++  testcase( szPage<=32768 );
++  testcase( szPage>=65536 );
++  pInfo = walCkptInfo(pWal);
++  if( pInfo->nBackfill<pWal->hdr.mxFrame ){
++
++    /* Allocate the iterator */
++    rc = walIteratorInit(pWal, &pIter);
++    if( rc!=SQLITE_OK ){
++      return rc;
++    }
++    assert( pIter );
++
++    /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
++    ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
++    assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
++
++    /* Compute in mxSafeFrame the index of the last frame of the WAL that is
++    ** safe to write into the database.  Frames beyond mxSafeFrame might
++    ** overwrite database pages that are in use by active readers and thus
++    ** cannot be backfilled from the WAL.
      */
 -    memcpy(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr));
--
++    mxSafeFrame = pWal->hdr.mxFrame;
++    mxPage = pWal->hdr.nPage;
++    for(i=1; i<WAL_NREADER; i++){
++      /* Thread-sanitizer reports that the following is an unsafe read,
++      ** as some other thread may be in the process of updating the value
++      ** of the aReadMark[] slot. The assumption here is that if that is
++      ** happening, the other client may only be increasing the value,
++      ** not decreasing it. So assuming either that either the "old" or
++      ** "new" version of the value is read, and not some arbitrary value
++      ** that would never be written by a real client, things are still 
++      ** safe.  */
++      u32 y = pInfo->aReadMark[i];
++      if( mxSafeFrame>y ){
++        assert( y<=pWal->hdr.mxFrame );
++        rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1);
++        if( rc==SQLITE_OK ){
++          pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED);
++          walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1);
++        }else if( rc==SQLITE_BUSY ){
++          mxSafeFrame = y;
++          xBusy = 0;
++        }else{
++          goto walcheckpoint_out;
++        }
++      }
++    }
+ 
 -    for(iFrame=pWal->hdr.mxFrame+1; 
 -        ALWAYS(rc==SQLITE_OK) && iFrame<=iMax; 
 -        iFrame++
--    ){
++    if( pInfo->nBackfill<mxSafeFrame
++     && (rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(0),1))==SQLITE_OK
+     ){
 -      /* This call cannot fail. Unless the page for which the page number
 -      ** is passed as the second argument is (a) in the cache and 
 -      ** (b) has an outstanding reference, then xUndo is either a no-op
@@ -7635,18 +41347,13 @@
 -      */
 -      assert( walFramePgno(pWal, iFrame)!=1 );
 -      rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame));
-+    if( rc==SQLITE_OK ){
-+      i64 nReq = ((i64)mxPage * szPage);
-+      rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
-+      if( rc==SQLITE_OK && nSize<nReq ){
-+        sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
-+      }
-     }
+-    }
 -    if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal);
 -  }
--  assert( rc==SQLITE_OK );
 -  return rc;
 -}
++      i64 nSize;                    /* Current size of database file */
++      u32 nBackfill = pInfo->nBackfill;
  
 -/* 
 -** Argument aWalData must point to an array of WAL_SAVEPOINT_NDATA u32 
@@ -7661,6 +41368,10 @@
 -  aWalData[2] = pWal->hdr.aFrameCksum[1];
 -  aWalData[3] = pWal->nCkpt;
 -}
++      /* Sync the WAL to disk */
++      if( sync_flags ){
++        rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
++      }
  
 -/* 
 -** Move the write position of the WAL back to the point identified by
@@ -7670,37 +41381,19 @@
 -*/
 -SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){
 -  int rc = SQLITE_OK;
-+    /* Iterate through the contents of the WAL, copying data to the db file. */
-+    while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
-+      i64 iOffset;
-+      assert( walFramePgno(pWal, iFrame)==iDbpage );
-+      if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ) continue;
-+      iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
-+      /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
-+      rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset);
-+      if( rc!=SQLITE_OK ) break;
-+      iOffset = (iDbpage-1)*(i64)szPage;
-+      testcase( IS_BIG_INT(iOffset) );
-+      rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
-+      if( rc!=SQLITE_OK ) break;
-+    }
++      /* If the database may grow as a result of this checkpoint, hint
++      ** about the eventual size of the db file to the VFS layer.
++      */
++      if( rc==SQLITE_OK ){
++        i64 nReq = ((i64)mxPage * szPage);
++        rc = sqlite3OsFileSize(pWal->pDbFd, &nSize);
++        if( rc==SQLITE_OK && nSize<nReq ){
++          sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq);
++        }
++      }
  
 -  assert( pWal->writeLock );
 -  assert( aWalData[3]!=pWal->nCkpt || aWalData[0]<=pWal->hdr.mxFrame );
-+    /* If work was actually accomplished... */
-+    if( rc==SQLITE_OK ){
-+      if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
-+        i64 szDb = pWal->hdr.nPage*(i64)szPage;
-+        testcase( IS_BIG_INT(szDb) );
-+        rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
-+        if( rc==SQLITE_OK && sync_flags ){
-+          rc = sqlite3OsSync(pWal->pDbFd, sync_flags);
-+        }
-+      }
-+      if( rc==SQLITE_OK ){
-+        pInfo->nBackfill = mxSafeFrame;
-+      }
-+    }
  
 -  if( aWalData[3]!=pWal->nCkpt ){
 -    /* This savepoint was opened immediately after the write-transaction
@@ -7709,25 +41402,51 @@
 -    */
 -    aWalData[0] = 0;
 -    aWalData[3] = pWal->nCkpt;
-+    /* Release the reader lock held while backfilling */
-+    walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
-   }
+-  }
++      /* Iterate through the contents of the WAL, copying data to the db file */
++      while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
++        i64 iOffset;
++        assert( walFramePgno(pWal, iFrame)==iDbpage );
++        if( iFrame<=nBackfill || iFrame>mxSafeFrame || iDbpage>mxPage ){
++          continue;
++        }
++        iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
++        /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
++        rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset);
++        if( rc!=SQLITE_OK ) break;
++        iOffset = (iDbpage-1)*(i64)szPage;
++        testcase( IS_BIG_INT(iOffset) );
++        rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
++        if( rc!=SQLITE_OK ) break;
++      }
  
 -  if( aWalData[0]<pWal->hdr.mxFrame ){
 -    pWal->hdr.mxFrame = aWalData[0];
 -    pWal->hdr.aFrameCksum[0] = aWalData[1];
 -    pWal->hdr.aFrameCksum[1] = aWalData[2];
 -    walCleanupHash(pWal);
-+  if( rc==SQLITE_BUSY ){
-+    /* Reset the return code so as not to report a checkpoint failure
-+    ** just because there are active readers.  */
-+    rc = SQLITE_OK;
-   }
+-  }
++      /* If work was actually accomplished... */
++      if( rc==SQLITE_OK ){
++        if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
++          i64 szDb = pWal->hdr.nPage*(i64)szPage;
++          testcase( IS_BIG_INT(szDb) );
++          rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
++          if( rc==SQLITE_OK && sync_flags ){
++            rc = sqlite3OsSync(pWal->pDbFd, sync_flags);
++          }
++        }
++        if( rc==SQLITE_OK ){
++          pInfo->nBackfill = mxSafeFrame;
++        }
++      }
  
 -  return rc;
 -}
--
--
++      /* Release the reader lock held while backfilling */
++      walUnlockExclusive(pWal, WAL_READ_LOCK(0), 1);
++    }
+ 
 -/*
 -** This function is called just before writing a set of frames to the log
 -** file (see sqlite3WalFrames()). It checks to see if, instead of appending
@@ -7743,25 +41462,31 @@
 -static int walRestartLog(Wal *pWal){
 -  int rc = SQLITE_OK;
 -  int cnt;
--
++    if( rc==SQLITE_BUSY ){
++      /* Reset the return code so as not to report a checkpoint failure
++      ** just because there are active readers.  */
++      rc = SQLITE_OK;
++    }
++  }
+ 
 -  if( pWal->readLock==0 ){
 -    volatile WalCkptInfo *pInfo = walCkptInfo(pWal);
 -    assert( pInfo->nBackfill==pWal->hdr.mxFrame );
 -    if( pInfo->nBackfill>0 ){
--      u32 salt1;
--      sqlite3_randomness(4, &salt1);
--      rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
-+  /* If this is an SQLITE_CHECKPOINT_RESTART operation, and the entire wal
-+  ** file has been copied into the database file, then block until all
-+  ** readers have finished using the wal file. This ensures that the next
-+  ** process to write to the database restarts the wal file.
++  /* If this is an SQLITE_CHECKPOINT_RESTART or TRUNCATE operation, and the
++  ** entire wal file has been copied into the database file, then block 
++  ** until all readers have finished using the wal file. This ensures that 
++  ** the next process to write to the database restarts the wal file.
 +  */
 +  if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){
 +    assert( pWal->writeLock );
 +    if( pInfo->nBackfill<pWal->hdr.mxFrame ){
 +      rc = SQLITE_BUSY;
-+    }else if( eMode==SQLITE_CHECKPOINT_RESTART ){
-+      assert( mxSafeFrame==pWal->hdr.mxFrame );
++    }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){
+       u32 salt1;
+       sqlite3_randomness(4, &salt1);
+-      rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1, 0);
++      assert( pInfo->nBackfill==pWal->hdr.mxFrame );
 +      rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1);
        if( rc==SQLITE_OK ){
 -        /* If all readers are using WAL_READ_LOCK(0) (in other words if no
@@ -7772,20 +41497,25 @@
 -        ** In theory it would be Ok to update the cache of the header only
 -        ** at this point. But updating the actual wal-index header is also
 -        ** safe and means there is no special case for sqlite3WalUndo()
--        ** to handle if this transaction is rolled back.
--        */
--        int i;                    /* Loop counter */
--        u32 *aSalt = pWal->hdr.aSalt;       /* Big-endian salt values */
--
--        pWal->nCkpt++;
--        pWal->hdr.mxFrame = 0;
--        sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
--        aSalt[1] = salt1;
--        walIndexWriteHdr(pWal);
--        pInfo->nBackfill = 0;
--        pInfo->aReadMark[1] = 0;
--        for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
--        assert( pInfo->aReadMark[0]==0 );
+-        ** to handle if this transaction is rolled back.  */
+-        walRestartHdr(pWal, salt1);
++        if( eMode==SQLITE_CHECKPOINT_TRUNCATE ){
++          /* IMPLEMENTATION-OF: R-44699-57140 This mode works the same way as
++          ** SQLITE_CHECKPOINT_RESTART with the addition that it also
++          ** truncates the log file to zero bytes just prior to a
++          ** successful return.
++          **
++          ** In theory, it might be safe to do this without updating the
++          ** wal-index header in shared memory, as all subsequent reader or
++          ** writer clients should see that the entire log file has been
++          ** checkpointed and behave accordingly. This seems unsafe though,
++          ** as it would leave the system in a state where the contents of
++          ** the wal-index header do not match the contents of the 
++          ** file-system. To avoid this, update the wal-index header to
++          ** indicate that the log file contains zero valid frames.  */
++          walRestartHdr(pWal, salt1);
++          rc = sqlite3OsTruncate(pWal->pWalFd, 0);
++        }
          walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
 -      }else if( rc!=SQLITE_BUSY ){
 -        return rc;
@@ -7813,7 +41543,9 @@
 -** Information about the current state of the WAL file and where
 -** the next fsync should occur - passed from sqlite3WalFrames() into
 -** walWriteToLog().
--*/
++** If the WAL file is currently larger than nMax bytes in size, truncate
++** it to exactly nMax bytes. If an error occurs while doing so, ignore it.
+ */
 -typedef struct WalWriter {
 -  Wal *pWal;                   /* The complete WAL information */
 -  sqlite3_file *pFd;           /* The WAL file to which we write */
@@ -7821,23 +41553,40 @@
 -  int syncFlags;               /* Flags for the fsync */
 -  int szPage;                  /* Size of one page */
 -} WalWriter;
--
--/*
++static void walLimitSize(Wal *pWal, i64 nMax){
++  i64 sz;
++  int rx;
++  sqlite3BeginBenignMalloc();
++  rx = sqlite3OsFileSize(pWal->pWalFd, &sz);
++  if( rx==SQLITE_OK && (sz > nMax ) ){
++    rx = sqlite3OsTruncate(pWal->pWalFd, nMax);
++  }
++  sqlite3EndBenignMalloc();
++  if( rx ){
++    sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName);
++  }
++}
+ 
+ /*
 -** Write iAmt bytes of content into the WAL file beginning at iOffset.
 -** Do a sync when crossing the p->iSyncPoint boundary.
 -**
 -** In other words, if iSyncPoint is in between iOffset and iOffset+iAmt,
 -** first write the part before iSyncPoint, then sync, then write the
 -** rest.
-+** If the WAL file is currently larger than nMax bytes in size, truncate
-+** it to exactly nMax bytes. If an error occurs while doing so, ignore it.
++** Close a connection to a log file.
  */
 -static int walWriteToLog(
 -  WalWriter *p,              /* WAL to write to */
 -  void *pContent,            /* Content to be written */
 -  int iAmt,                  /* Number of bytes to write */
 -  sqlite3_int64 iOffset      /* Start writing at this offset */
--){
++SQLITE_PRIVATE int sqlite3WalClose(
++  Wal *pWal,                      /* Wal to close */
++  int sync_flags,                 /* Flags to pass to OsSync() (or 0) */
++  int nBuf,
++  u8 *zBuf                        /* Buffer of at least nBuf bytes */
+ ){
 -  int rc;
 -  if( iOffset<p->iSyncPoint && iOffset+iAmt>=p->iSyncPoint ){
 -    int iFirstAmt = (int)(p->iSyncPoint - iOffset);
@@ -7849,50 +41598,6 @@
 -    assert( p->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) );
 -    rc = sqlite3OsSync(p->pFd, p->syncFlags & SQLITE_SYNC_MASK);
 -    if( iAmt==0 || rc ) return rc;
-+static void walLimitSize(Wal *pWal, i64 nMax){
-+  i64 sz;
-+  int rx;
-+  sqlite3BeginBenignMalloc();
-+  rx = sqlite3OsFileSize(pWal->pWalFd, &sz);
-+  if( rx==SQLITE_OK && (sz > nMax ) ){
-+    rx = sqlite3OsTruncate(pWal->pWalFd, nMax);
-+  }
-+  sqlite3EndBenignMalloc();
-+  if( rx ){
-+    sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName);
-   }
--  rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset);
--  return rc;
- }
- 
- /*
--** Write out a single frame of the WAL
-+** Close a connection to a log file.
- */
--static int walWriteOneFrame(
--  WalWriter *p,               /* Where to write the frame */
--  PgHdr *pPage,               /* The page of the frame to be written */
--  int nTruncate,              /* The commit flag.  Usually 0.  >0 for commit */
--  sqlite3_int64 iOffset       /* Byte offset at which to write */
-+SQLITE_PRIVATE int sqlite3WalClose(
-+  Wal *pWal,                      /* Wal to close */
-+  int sync_flags,                 /* Flags to pass to OsSync() (or 0) */
-+  int nBuf,
-+  u8 *zBuf                        /* Buffer of at least nBuf bytes */
- ){
--  int rc;                         /* Result code from subfunctions */
--  void *pData;                    /* Data actually written */
--  u8 aFrame[WAL_FRAME_HDRSIZE];   /* Buffer to assemble frame-header in */
--#if defined(SQLITE_HAS_CODEC)
--  if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM;
--#else
--  pData = pPage->pData;
--#endif
--  walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame);
--  rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset);
--  if( rc ) return rc;
--  /* Write the page data */
--  rc = walWriteToLog(p, pData, p->szPage, iOffset+sizeof(aFrame));
 +  int rc = SQLITE_OK;
 +  if( pWal ){
 +    int isDelete = 0;             /* True to unlink wal and wal-index files */
@@ -7945,31 +41650,13 @@
 +    WALTRACE(("WAL%p: closed\n", pWal));
 +    sqlite3_free((void *)pWal->apWiData);
 +    sqlite3_free(pWal);
-+  }
+   }
+-  rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset);
    return rc;
  }
  
--/* 
--** Write a set of frames to the log. The caller must hold the write-lock
--** on the log file (obtained using sqlite3WalBeginWriteTransaction()).
--*/
--SQLITE_PRIVATE int sqlite3WalFrames(
--  Wal *pWal,                      /* Wal handle to write to */
--  int szPage,                     /* Database page-size in bytes */
--  PgHdr *pList,                   /* List of dirty pages to write */
--  Pgno nTruncate,                 /* Database size after this commit */
--  int isCommit,                   /* True if this is a commit */
--  int sync_flags                  /* Flags to pass to OsSync() (or 0) */
--){
--  int rc;                         /* Used to catch return codes */
--  u32 iFrame;                     /* Next frame address */
--  PgHdr *p;                       /* Iterator to run through pList with. */
--  PgHdr *pLast = 0;               /* Last frame in list */
--  int nExtra = 0;                 /* Number of extra copies of last page */
--  int szFrame;                    /* The size of a single frame */
--  i64 iOffset;                    /* Next byte to write in WAL file */
--  WalWriter w;                    /* The writer */
-+/*
+ /*
+-** Write out a single frame of the WAL
 +** Try to read the wal-index header.  Return 0 on success and 1 if
 +** there is a problem.
 +**
@@ -7985,20 +41672,58 @@
 +**
 +** If the checksum cannot be verified return non-zero. If the header
 +** is read successfully and the checksum verified, return zero.
-+*/
+ */
+-static int walWriteOneFrame(
+-  WalWriter *p,               /* Where to write the frame */
+-  PgHdr *pPage,               /* The page of the frame to be written */
+-  int nTruncate,              /* The commit flag.  Usually 0.  >0 for commit */
+-  sqlite3_int64 iOffset       /* Byte offset at which to write */
+-){
+-  int rc;                         /* Result code from subfunctions */
+-  void *pData;                    /* Data actually written */
+-  u8 aFrame[WAL_FRAME_HDRSIZE];   /* Buffer to assemble frame-header in */
+-#if defined(SQLITE_HAS_CODEC)
+-  if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM;
+-#else
+-  pData = pPage->pData;
+-#endif
+-  walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame);
+-  rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset);
+-  if( rc ) return rc;
+-  /* Write the page data */
+-  rc = walWriteToLog(p, pData, p->szPage, iOffset+sizeof(aFrame));
+-  return rc;
+-}
 +static int walIndexTryHdr(Wal *pWal, int *pChanged){
 +  u32 aCksum[2];                  /* Checksum on the header content */
 +  WalIndexHdr h1, h2;             /* Two copies of the header content */
 +  WalIndexHdr volatile *aHdr;     /* Header in shared memory */
  
--  assert( pList );
--  assert( pWal->writeLock );
+-/* 
+-** Write a set of frames to the log. The caller must hold the write-lock
+-** on the log file (obtained using sqlite3WalBeginWriteTransaction()).
+-*/
+-SQLITE_PRIVATE int sqlite3WalFrames(
+-  Wal *pWal,                      /* Wal handle to write to */
+-  int szPage,                     /* Database page-size in bytes */
+-  PgHdr *pList,                   /* List of dirty pages to write */
+-  Pgno nTruncate,                 /* Database size after this commit */
+-  int isCommit,                   /* True if this is a commit */
+-  int sync_flags                  /* Flags to pass to OsSync() (or 0) */
+-){
+-  int rc;                         /* Used to catch return codes */
+-  u32 iFrame;                     /* Next frame address */
+-  PgHdr *p;                       /* Iterator to run through pList with. */
+-  PgHdr *pLast = 0;               /* Last frame in list */
+-  int nExtra = 0;                 /* Number of extra copies of last page */
+-  int szFrame;                    /* The size of a single frame */
+-  i64 iOffset;                    /* Next byte to write in WAL file */
+-  WalWriter w;                    /* The writer */
 +  /* The first page of the wal-index must be mapped at this point. */
 +  assert( pWal->nWiData>0 && pWal->apWiData[0] );
  
--  /* If this frame set completes a transaction, then nTruncate>0.  If
--  ** nTruncate==0 then this frame set does not complete the transaction. */
--  assert( (isCommit!=0)==(nTruncate!=0) );
+-  assert( pList );
+-  assert( pWal->writeLock );
 +  /* Read the header. This might happen concurrently with a write to the
 +  ** same area of shared memory on a different CPU in a SMP,
 +  ** meaning it is possible that an inconsistent snapshot is read
@@ -8014,70 +41739,24 @@
 +  walShmBarrier(pWal);
 +  memcpy(&h2, (void *)&aHdr[1], sizeof(h2));
  
--#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
--  { int cnt; for(cnt=0, p=pList; p; p=p->pDirty, cnt++){}
--    WALTRACE(("WAL%p: frame write begin. %d frames. mxFrame=%d. %s\n",
--              pWal, cnt, pWal->hdr.mxFrame, isCommit ? "Commit" : "Spill"));
+-  /* If this frame set completes a transaction, then nTruncate>0.  If
+-  ** nTruncate==0 then this frame set does not complete the transaction. */
+-  assert( (isCommit!=0)==(nTruncate!=0) );
 +  if( memcmp(&h1, &h2, sizeof(h1))!=0 ){
 +    return 1;   /* Dirty read */
 +  }  
 +  if( h1.isInit==0 ){
 +    return 1;   /* Malformed header - probably all zeros */
-   }
--#endif
--
--  /* See if it is possible to write these frames into the start of the
--  ** log file, instead of appending to it at pWal->hdr.mxFrame.
--  */
--  if( SQLITE_OK!=(rc = walRestartLog(pWal)) ){
--    return rc;
++  }
 +  walChecksumBytes(1, (u8*)&h1, sizeof(h1)-sizeof(h1.aCksum), 0, aCksum);
 +  if( aCksum[0]!=h1.aCksum[0] || aCksum[1]!=h1.aCksum[1] ){
 +    return 1;   /* Checksum does not match */
-   }
++  }
  
--  /* If this is the first frame written into the log, write the WAL
--  ** header to the start of the WAL file. See comments at the top of
--  ** this source file for a description of the WAL header format.
--  */
--  iFrame = pWal->hdr.mxFrame;
--  if( iFrame==0 ){
--    u8 aWalHdr[WAL_HDRSIZE];      /* Buffer to assemble wal-header in */
--    u32 aCksum[2];                /* Checksum for wal-header */
--
--    sqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN));
--    sqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION);
--    sqlite3Put4byte(&aWalHdr[8], szPage);
--    sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt);
--    if( pWal->nCkpt==0 ) sqlite3_randomness(8, pWal->hdr.aSalt);
--    memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8);
--    walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum);
--    sqlite3Put4byte(&aWalHdr[24], aCksum[0]);
--    sqlite3Put4byte(&aWalHdr[28], aCksum[1]);
--    
--    pWal->szPage = szPage;
--    pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN;
--    pWal->hdr.aFrameCksum[0] = aCksum[0];
--    pWal->hdr.aFrameCksum[1] = aCksum[1];
--    pWal->truncateOnCommit = 1;
--
--    rc = sqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0);
--    WALTRACE(("WAL%p: wal-header write %s\n", pWal, rc ? "failed" : "ok"));
--    if( rc!=SQLITE_OK ){
--      return rc;
--    }
--
--    /* Sync the header (unless SQLITE_IOCAP_SEQUENTIAL is true or unless
--    ** all syncing is turned off by PRAGMA synchronous=OFF).  Otherwise
--    ** an out-of-order write following a WAL restart could result in
--    ** database corruption.  See the ticket:
--    **
--    **     http://localhost:591/sqlite/info/ff5be73dee
--    */
--    if( pWal->syncHeader && sync_flags ){
--      rc = sqlite3OsSync(pWal->pWalFd, sync_flags & SQLITE_SYNC_MASK);
--      if( rc ) return rc;
--    }
+-#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
+-  { int cnt; for(cnt=0, p=pList; p; p=p->pDirty, cnt++){}
+-    WALTRACE(("WAL%p: frame write begin. %d frames. mxFrame=%d. %s\n",
+-              pWal, cnt, pWal->hdr.mxFrame, isCommit ? "Commit" : "Spill"));
 +  if( memcmp(&pWal->hdr, &h1, sizeof(WalIndexHdr)) ){
 +    *pChanged = 1;
 +    memcpy(&pWal->hdr, &h1, sizeof(WalIndexHdr));
@@ -8085,38 +41764,21 @@
 +    testcase( pWal->szPage<=32768 );
 +    testcase( pWal->szPage>=65536 );
    }
--  assert( (int)pWal->szPage==szPage );
+-#endif
  
--  /* Setup information needed to write frames into the WAL */
--  w.pWal = pWal;
--  w.pFd = pWal->pWalFd;
--  w.iSyncPoint = 0;
--  w.syncFlags = sync_flags;
--  w.szPage = szPage;
--  iOffset = walFrameOffset(iFrame+1, szPage);
--  szFrame = szPage + WAL_FRAME_HDRSIZE;
+-  /* See if it is possible to write these frames into the start of the
+-  ** log file, instead of appending to it at pWal->hdr.mxFrame.
 +  /* The header was successfully read. Return zero. */
 +  return 0;
 +}
- 
--  /* Write all frames into the log file exactly once */
--  for(p=pList; p; p=p->pDirty){
--    int nDbSize;   /* 0 normally.  Positive == commit flag */
--    iFrame++;
--    assert( iOffset==walFrameOffset(iFrame, szPage) );
--    nDbSize = (isCommit && p->pDirty==0) ? nTruncate : 0;
--    rc = walWriteOneFrame(&w, p, nDbSize, iOffset);
--    if( rc ) return rc;
--    pLast = p;
--    iOffset += szFrame;
--  }
++
 +/*
 +** Read the wal-index header from the wal-index and into pWal->hdr.
 +** If the wal-header appears to be corrupt, try to reconstruct the
 +** wal-index from the WAL before returning.
 +**
 +** Set *pChanged to 1 if the wal-index header value in pWal->hdr is
-+** changed by this opertion.  If pWal->hdr is unchanged, set *pChanged
++** changed by this operation.  If pWal->hdr is unchanged, set *pChanged
 +** to 0.
 +**
 +** If the wal-index header is successfully read, return SQLITE_OK. 
@@ -8126,78 +41788,56 @@
 +  int rc;                         /* Return code */
 +  int badHdr;                     /* True if a header read failed */
 +  volatile u32 *page0;            /* Chunk of wal-index containing header */
- 
--  /* If this is the end of a transaction, then we might need to pad
--  ** the transaction and/or sync the WAL file.
--  **
--  ** Padding and syncing only occur if this set of frames complete a
--  ** transaction and if PRAGMA synchronous=FULL.  If synchronous==NORMAL
--  ** or synchonous==OFF, then no padding or syncing are needed.
--  **
--  ** If SQLITE_IOCAP_POWERSAFE_OVERWRITE is defined, then padding is not
--  ** needed and only the sync is done.  If padding is needed, then the
--  ** final frame is repeated (with its commit mark) until the next sector
--  ** boundary is crossed.  Only the part of the WAL prior to the last
--  ** sector boundary is synced; the part of the last frame that extends
--  ** past the sector boundary is written after the sync.
++
 +  /* Ensure that page 0 of the wal-index (the page that contains the 
 +  ** wal-index header) is mapped. Return early if an error occurs here.
    */
--  if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){
--    if( pWal->padToSectorBoundary ){
--      int sectorSize = sqlite3SectorSize(pWal->pWalFd);
--      w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize;
--      while( iOffset<w.iSyncPoint ){
--        rc = walWriteOneFrame(&w, pLast, nTruncate, iOffset);
--        if( rc ) return rc;
--        iOffset += szFrame;
--        nExtra++;
--      }
--    }else{
--      rc = sqlite3OsSync(w.pFd, sync_flags & SQLITE_SYNC_MASK);
--    }
--  }
+-  if( SQLITE_OK!=(rc = walRestartLog(pWal)) ){
 +  assert( pChanged );
 +  rc = walIndexPage(pWal, 0, &page0);
 +  if( rc!=SQLITE_OK ){
-+    return rc;
+     return rc;
+-  }
 +  };
 +  assert( page0 || pWal->writeLock==0 );
  
--  /* If this frame set completes the first transaction in the WAL and
--  ** if PRAGMA journal_size_limit is set, then truncate the WAL to the
--  ** journal size limit, if possible.
+-  /* If this is the first frame written into the log, write the WAL
+-  ** header to the start of the WAL file. See comments at the top of
+-  ** this source file for a description of the WAL header format.
 +  /* If the first page of the wal-index has been mapped, try to read the
 +  ** wal-index header immediately, without holding any lock. This usually
 +  ** works, but may fail if the wal-index header is corrupt or currently 
 +  ** being modified by another thread or process.
    */
--  if( isCommit && pWal->truncateOnCommit && pWal->mxWalSize>=0 ){
--    i64 sz = pWal->mxWalSize;
--    if( walFrameOffset(iFrame+nExtra+1, szPage)>pWal->mxWalSize ){
--      sz = walFrameOffset(iFrame+nExtra+1, szPage);
--    }
--    walLimitSize(pWal, sz);
--    pWal->truncateOnCommit = 0;
--  }
+-  iFrame = pWal->hdr.mxFrame;
+-  if( iFrame==0 ){
+-    u8 aWalHdr[WAL_HDRSIZE];      /* Buffer to assemble wal-header in */
+-    u32 aCksum[2];                /* Checksum for wal-header */
+-
+-    sqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN));
+-    sqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION);
+-    sqlite3Put4byte(&aWalHdr[8], szPage);
+-    sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt);
+-    if( pWal->nCkpt==0 ) sqlite3_randomness(8, pWal->hdr.aSalt);
+-    memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8);
+-    walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum);
+-    sqlite3Put4byte(&aWalHdr[24], aCksum[0]);
+-    sqlite3Put4byte(&aWalHdr[28], aCksum[1]);
+-    
+-    pWal->szPage = szPage;
+-    pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN;
+-    pWal->hdr.aFrameCksum[0] = aCksum[0];
+-    pWal->hdr.aFrameCksum[1] = aCksum[1];
+-    pWal->truncateOnCommit = 1;
 +  badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1);
  
--  /* Append data to the wal-index. It is not necessary to lock the 
--  ** wal-index to do this as the SQLITE_SHM_WRITE lock held on the wal-index
--  ** guarantees that there are no other writers, and no data that may
--  ** be in use by existing readers is being overwritten.
+-    rc = sqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0);
+-    WALTRACE(("WAL%p: wal-header write %s\n", pWal, rc ? "failed" : "ok"));
+-    if( rc!=SQLITE_OK ){
+-      return rc;
 +  /* If the first attempt failed, it might have been due to a race
 +  ** with a writer.  So get a WRITE lock and try again.
-   */
--  iFrame = pWal->hdr.mxFrame;
--  for(p=pList; p && rc==SQLITE_OK; p=p->pDirty){
--    iFrame++;
--    rc = walIndexAppend(pWal, iFrame, p->pgno);
--  }
--  while( rc==SQLITE_OK && nExtra>0 ){
--    iFrame++;
--    nExtra--;
--    rc = walIndexAppend(pWal, iFrame, pLast->pgno);
++  */
 +  assert( badHdr==0 || pWal->writeLock==0 );
 +  if( badHdr ){
 +    if( pWal->readOnly & WAL_SHM_RDONLY ){
@@ -8205,7 +41845,7 @@
 +        walUnlockShared(pWal, WAL_WRITE_LOCK);
 +        rc = SQLITE_READONLY_RECOVERY;
 +      }
-+    }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){
++    }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 1)) ){
 +      pWal->writeLock = 1;
 +      if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
 +        badHdr = walIndexTryHdr(pWal, pChanged);
@@ -8220,23 +41860,19 @@
 +      }
 +      pWal->writeLock = 0;
 +      walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
-+    }
-   }
+     }
++  }
  
--  if( rc==SQLITE_OK ){
--    /* Update the private copy of the header. */
--    pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16));
--    testcase( szPage<=32768 );
--    testcase( szPage>=65536 );
--    pWal->hdr.mxFrame = iFrame;
--    if( isCommit ){
--      pWal->hdr.iChange++;
--      pWal->hdr.nPage = nTruncate;
--    }
--    /* If this is a commit, update the wal-index header too. */
--    if( isCommit ){
--      walIndexWriteHdr(pWal);
--      pWal->iCallback = iFrame;
+-    /* Sync the header (unless SQLITE_IOCAP_SEQUENTIAL is true or unless
+-    ** all syncing is turned off by PRAGMA synchronous=OFF).  Otherwise
+-    ** an out-of-order write following a WAL restart could result in
+-    ** database corruption.  See the ticket:
+-    **
+-    **     http://localhost:591/sqlite/info/ff5be73dee
+-    */
+-    if( pWal->syncHeader && sync_flags ){
+-      rc = sqlite3OsSync(pWal->pWalFd, sync_flags & SQLITE_SYNC_MASK);
+-      if( rc ) return rc;
 -    }
 +  /* If the header is read successfully, check the version number to make
 +  ** sure the wal-index was not constructed with some future format that
@@ -8245,33 +41881,47 @@
 +  if( badHdr==0 && pWal->hdr.iVersion!=WALINDEX_MAX_VERSION ){
 +    rc = SQLITE_CANTOPEN_BKPT;
    }
+-  assert( (int)pWal->szPage==szPage );
  
--  WALTRACE(("WAL%p: frame write %s\n", pWal, rc ? "failed" : "ok"));
-   return rc;
- }
+-  /* Setup information needed to write frames into the WAL */
+-  w.pWal = pWal;
+-  w.pFd = pWal->pWalFd;
+-  w.iSyncPoint = 0;
+-  w.syncFlags = sync_flags;
+-  w.szPage = szPage;
+-  iOffset = walFrameOffset(iFrame+1, szPage);
+-  szFrame = szPage + WAL_FRAME_HDRSIZE;
++  return rc;
++}
  
--/* 
--** This routine is called to implement sqlite3_wal_checkpoint() and
--** related interfaces.
+-  /* Write all frames into the log file exactly once */
+-  for(p=pList; p; p=p->pDirty){
+-    int nDbSize;   /* 0 normally.  Positive == commit flag */
+-    iFrame++;
+-    assert( iOffset==walFrameOffset(iFrame, szPage) );
+-    nDbSize = (isCommit && p->pDirty==0) ? nTruncate : 0;
+-    rc = walWriteOneFrame(&w, p, nDbSize, iOffset);
+-    if( rc ) return rc;
+-    pLast = p;
+-    iOffset += szFrame;
+-  }
 +/*
 +** This is the value that walTryBeginRead returns when it needs to
 +** be retried.
 +*/
 +#define WAL_RETRY  (-1)
-+
+ 
+-  /* If this is the end of a transaction, then we might need to pad
+-  ** the transaction and/or sync the WAL file.
 +/*
 +** Attempt to start a read transaction.  This might fail due to a race or
 +** other transient condition.  When that happens, it returns WAL_RETRY to
 +** indicate to the caller that it is safe to retry immediately.
- **
--** Obtain a CHECKPOINT lock and then backfill as much information as
--** we can from WAL into the database.
++**
 +** On success return SQLITE_OK.  On a permanent failure (such an
 +** I/O error or an SQLITE_BUSY because another process is running
 +** recovery) return a positive error code.
- **
--** If parameter xBusy is not NULL, it is a pointer to a busy-handler
--** callback. In this case this function runs a blocking checkpoint.
++**
 +** The useWal parameter is true to force the use of the WAL and disable
 +** the case where the WAL is bypassed because it has been completely
 +** checkpointed.  If useWal==0 then this routine calls walIndexReadHdr() 
@@ -8312,52 +41962,21 @@
 +** update values of the aReadMark[] array in the header, but if it does
 +** so it takes care to hold an exclusive lock on the corresponding
 +** WAL_READ_LOCK() while changing values.
- */
--SQLITE_PRIVATE int sqlite3WalCheckpoint(
--  Wal *pWal,                      /* Wal connection */
--  int eMode,                      /* PASSIVE, FULL or RESTART */
--  int (*xBusy)(void*),            /* Function to call when busy */
--  void *pBusyArg,                 /* Context argument for xBusyHandler */
--  int sync_flags,                 /* Flags to sync db file with (or 0) */
--  int nBuf,                       /* Size of temporary buffer */
--  u8 *zBuf,                       /* Temporary buffer to use */
--  int *pnLog,                     /* OUT: Number of frames in WAL */
--  int *pnCkpt                     /* OUT: Number of backfilled frames in WAL */
--){
--  int rc;                         /* Return code */
--  int isChanged = 0;              /* True if a new wal-index header is loaded */
--  int eMode2 = eMode;             /* Mode to pass to walCheckpoint() */
--
--  assert( pWal->ckptLock==0 );
--  assert( pWal->writeLock==0 );
++*/
 +static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
 +  volatile WalCkptInfo *pInfo;    /* Checkpoint information in wal-index */
 +  u32 mxReadMark;                 /* Largest aReadMark[] value */
 +  int mxI;                        /* Index of largest aReadMark[] value */
 +  int i;                          /* Loop counter */
 +  int rc = SQLITE_OK;             /* Return code  */
- 
--  if( pWal->readOnly ) return SQLITE_READONLY;
--  WALTRACE(("WAL%p: checkpoint begins\n", pWal));
--  rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
--  if( rc ){
--    /* Usually this is SQLITE_BUSY meaning that another thread or process
--    ** is already running a checkpoint, or maybe a recovery.  But it might
--    ** also be SQLITE_IOERR. */
--    return rc;
--  }
--  pWal->ckptLock = 1;
++
 +  assert( pWal->readLock<0 );     /* Not currently locked */
- 
--  /* If this is a blocking-checkpoint, then obtain the write-lock as well
--  ** to prevent any writers from running while the checkpoint is underway.
--  ** This has to be done before the call to walIndexReadHdr() below.
++
 +  /* Take steps to avoid spinning forever if there is a protocol error.
    **
--  ** If the writer lock cannot be obtained, then a passive checkpoint is
--  ** run instead. Since the checkpointer is not holding the writer lock,
--  ** there is no point in blocking waiting for any readers. Assuming no 
--  ** other error occurs, this function will return SQLITE_BUSY to the caller.
+-  ** Padding and syncing only occur if this set of frames complete a
+-  ** transaction and if PRAGMA synchronous=FULL.  If synchronous==NORMAL
+-  ** or synchronous==OFF, then no padding or syncing are needed.
 +  ** Circumstances that cause a RETRY should only last for the briefest
 +  ** instances of time.  No I/O or other system calls are done while the
 +  ** locks are held, so the locks should not be held for very long. But 
@@ -8365,7 +41984,13 @@
 +  ** paged out or take a page-fault that is time-consuming to resolve, 
 +  ** during the few nanoseconds that it is holding the lock.  In that case,
 +  ** it might take longer than normal for the lock to free.
-+  **
+   **
+-  ** If SQLITE_IOCAP_POWERSAFE_OVERWRITE is defined, then padding is not
+-  ** needed and only the sync is done.  If padding is needed, then the
+-  ** final frame is repeated (with its commit mark) until the next sector
+-  ** boundary is crossed.  Only the part of the WAL prior to the last
+-  ** sector boundary is synced; the part of the last frame that extends
+-  ** past the sector boundary is written after the sync.
 +  ** After 5 RETRYs, we begin calling sqlite3OsSleep().  The first few
 +  ** calls to sqlite3OsSleep() have a delay of 1 microsecond.  Really this
 +  ** is more of a scheduler yield than an actual delay.  But on the 10th
@@ -8373,8 +41998,15 @@
 +  ** so that on the 100th (and last) RETRY we delay for 323 milliseconds.
 +  ** The total delay time before giving up is less than 10 seconds.
    */
--  if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
--    rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1);
+-  if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){
+-    if( pWal->padToSectorBoundary ){
+-      int sectorSize = sqlite3SectorSize(pWal->pWalFd);
+-      w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize;
+-      while( iOffset<w.iSyncPoint ){
+-        rc = walWriteOneFrame(&w, pLast, nTruncate, iOffset);
+-        if( rc ) return rc;
+-        iOffset += szFrame;
+-        nExtra++;
 +  if( cnt>5 ){
 +    int nDelay = 1;                      /* Pause time in microseconds */
 +    if( cnt>100 ){
@@ -8410,13 +42042,23 @@
 +        rc = WAL_RETRY;
 +      }else if( rc==SQLITE_BUSY ){
 +        rc = SQLITE_BUSY_RECOVERY;
-+      }
+       }
+-    }else{
+-      rc = sqlite3OsSync(w.pFd, sync_flags & SQLITE_SYNC_MASK);
 +    }
 +    if( rc!=SQLITE_OK ){
 +      return rc;
-+    }
-+  }
-+
+     }
+   }
+ 
+-  /* If this frame set completes the first transaction in the WAL and
+-  ** if PRAGMA journal_size_limit is set, then truncate the WAL to the
+-  ** journal size limit, if possible.
+-  */
+-  if( isCommit && pWal->truncateOnCommit && pWal->mxWalSize>=0 ){
+-    i64 sz = pWal->mxWalSize;
+-    if( walFrameOffset(iFrame+nExtra+1, szPage)>pWal->mxWalSize ){
+-      sz = walFrameOffset(iFrame+nExtra+1, szPage);
 +  pInfo = walCkptInfo(pWal);
 +  if( !useWal && pInfo->nBackfill==pWal->hdr.mxFrame ){
 +    /* The WAL has been completely backfilled (or it is empty).
@@ -8424,17 +42066,13 @@
 +    */
 +    rc = walLockShared(pWal, WAL_READ_LOCK(0));
 +    walShmBarrier(pWal);
-     if( rc==SQLITE_OK ){
--      pWal->writeLock = 1;
--    }else if( rc==SQLITE_BUSY ){
--      eMode2 = SQLITE_CHECKPOINT_PASSIVE;
--      rc = SQLITE_OK;
++    if( rc==SQLITE_OK ){
 +      if( memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) ){
 +        /* It is not safe to allow the reader to continue here if frames
 +        ** may have been appended to the log before READ_LOCK(0) was obtained.
 +        ** When holding READ_LOCK(0), the reader ignores the entire log file,
 +        ** which implies that the database file contains a trustworthy
-+        ** snapshoT. Since holding READ_LOCK(0) prevents a checkpoint from
++        ** snapshot. Since holding READ_LOCK(0) prevents a checkpoint from
 +        ** happening, this is usually correct.
 +        **
 +        ** However, if frames have been appended to the log (or if the log 
@@ -8451,18 +42089,28 @@
 +    }else if( rc!=SQLITE_BUSY ){
 +      return rc;
      }
+-    walLimitSize(pWal, sz);
+-    pWal->truncateOnCommit = 0;
    }
  
--  /* Read the wal-index header. */
--  if( rc==SQLITE_OK ){
--    rc = walIndexReadHdr(pWal, &isChanged);
--    if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
--      sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
+-  /* Append data to the wal-index. It is not necessary to lock the 
+-  ** wal-index to do this as the SQLITE_SHM_WRITE lock held on the wal-index
+-  ** guarantees that there are no other writers, and no data that may
+-  ** be in use by existing readers is being overwritten.
 +  /* If we get this far, it means that the reader will want to use
 +  ** the WAL to get at content from recent commits.  The job now is
 +  ** to select one of the aReadMark[] entries that is closest to
 +  ** but not exceeding pWal->hdr.mxFrame and lock that entry.
-+  */
+   */
+-  iFrame = pWal->hdr.mxFrame;
+-  for(p=pList; p && rc==SQLITE_OK; p=p->pDirty){
+-    iFrame++;
+-    rc = walIndexAppend(pWal, iFrame, p->pgno);
+-  }
+-  while( rc==SQLITE_OK && nExtra>0 ){
+-    iFrame++;
+-    nExtra--;
+-    rc = walIndexAppend(pWal, iFrame, pLast->pgno);
 +  mxReadMark = 0;
 +  mxI = 0;
 +  for(i=1; i<WAL_NREADER; i++){
@@ -8471,7 +42119,7 @@
 +      assert( thisMark!=READMARK_NOT_USED );
 +      mxReadMark = thisMark;
 +      mxI = i;
-     }
++    }
    }
 +  /* There was once an "if" here. The extra "{" is to preserve indentation. */
 +  {
@@ -8479,7 +42127,7 @@
 +     && (mxReadMark<pWal->hdr.mxFrame || mxI==0)
 +    ){
 +      for(i=1; i<WAL_NREADER; i++){
-+        rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
++        rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1, 0);
 +        if( rc==SQLITE_OK ){
 +          mxReadMark = pInfo->aReadMark[i] = pWal->hdr.mxFrame;
 +          mxI = i;
@@ -8495,14 +42143,23 @@
 +      return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK;
 +    }
  
--  /* Copy data from the log to the database file. */
 -  if( rc==SQLITE_OK ){
--    if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
--      rc = SQLITE_CORRUPT_BKPT;
+-    /* Update the private copy of the header. */
+-    pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16));
+-    testcase( szPage<=32768 );
+-    testcase( szPage>=65536 );
+-    pWal->hdr.mxFrame = iFrame;
+-    if( isCommit ){
+-      pWal->hdr.iChange++;
+-      pWal->hdr.nPage = nTruncate;
 +    rc = walLockShared(pWal, WAL_READ_LOCK(mxI));
 +    if( rc ){
 +      return rc==SQLITE_BUSY ? WAL_RETRY : rc;
-+    }
+     }
+-    /* If this is a commit, update the wal-index header too. */
+-    if( isCommit ){
+-      walIndexWriteHdr(pWal);
+-      pWal->iCallback = iFrame;
 +    /* Now that the read-lock has been obtained, check that neither the
 +    ** value in the aReadMark[] array or the contents of the wal-index
 +    ** header have changed.
@@ -8529,54 +42186,57 @@
 +    ){
 +      walUnlockShared(pWal, WAL_READ_LOCK(mxI));
 +      return WAL_RETRY;
-     }else{
--      rc = walCheckpoint(pWal, eMode2, xBusy, pBusyArg, sync_flags, zBuf);
--    }
--
--    /* If no error occurred, set the output variables. */
--    if( rc==SQLITE_OK || rc==SQLITE_BUSY ){
--      if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame;
--      if( pnCkpt ) *pnCkpt = (int)(walCkptInfo(pWal)->nBackfill);
++    }else{
 +      assert( mxReadMark<=pWal->hdr.mxFrame );
 +      pWal->readLock = (i16)mxI;
      }
    }
-+  return rc;
-+}
+-
+-  WALTRACE(("WAL%p: frame write %s\n", pWal, rc ? "failed" : "ok"));
+   return rc;
+ }
  
--  if( isChanged ){
--    /* If a new wal-index header was loaded before the checkpoint was 
--    ** performed, then the pager-cache associated with pWal is now
--    ** out of date. So zero the cached wal-index header to ensure that
--    ** next time the pager opens a snapshot on this database it knows that
--    ** the cache needs to be reset.
--    */
--    memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
--  }
+-/* 
+-** This routine is called to implement sqlite3_wal_checkpoint() and
+-** related interfaces.
 +/*
 +** Begin a read transaction on the database.
-+**
+ **
+-** Obtain a CHECKPOINT lock and then backfill as much information as
+-** we can from WAL into the database.
 +** This routine used to be called sqlite3OpenSnapshot() and with good reason:
 +** it takes a snapshot of the state of the WAL and wal-index for the current
 +** instant in time.  The current thread will continue to use this snapshot.
 +** Other threads might append new content to the WAL and wal-index but
 +** that extra content is ignored by the current thread.
-+**
+ **
+-** If parameter xBusy is not NULL, it is a pointer to a busy-handler
+-** callback. In this case this function runs a blocking checkpoint.
 +** If the database contents have changes since the previous read
 +** transaction, then *pChanged is set to 1 before returning.  The
 +** Pager layer will use this to know that is cache is stale and
 +** needs to be flushed.
-+*/
+ */
+-SQLITE_PRIVATE int sqlite3WalCheckpoint(
+-  Wal *pWal,                      /* Wal connection */
+-  int eMode,                      /* PASSIVE, FULL, RESTART, or TRUNCATE */
+-  int (*xBusy)(void*),            /* Function to call when busy */
+-  void *pBusyArg,                 /* Context argument for xBusyHandler */
+-  int sync_flags,                 /* Flags to sync db file with (or 0) */
+-  int nBuf,                       /* Size of temporary buffer */
+-  u8 *zBuf,                       /* Temporary buffer to use */
+-  int *pnLog,                     /* OUT: Number of frames in WAL */
+-  int *pnCkpt                     /* OUT: Number of backfilled frames in WAL */
+-){
 +SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
-+  int rc;                         /* Return code */
+   int rc;                         /* Return code */
+-  int isChanged = 0;              /* True if a new wal-index header is loaded */
+-  int eMode2 = eMode;             /* Mode to pass to walCheckpoint() */
+-  int (*xBusy2)(void*) = xBusy;   /* Busy handler for eMode2 */
 +  int cnt = 0;                    /* Number of TryBeginRead attempts */
  
--  /* Release the locks. */
--  sqlite3WalEndWriteTransaction(pWal);
--  walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
--  pWal->ckptLock = 0;
--  WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok"));
--  return (rc==SQLITE_OK && eMode!=eMode2 ? SQLITE_BUSY : rc);
+-  assert( pWal->ckptLock==0 );
+-  assert( pWal->writeLock==0 );
 +  do{
 +    rc = walTryBeginRead(pWal, pChanged, 0, ++cnt);
 +  }while( rc==WAL_RETRY );
@@ -8585,63 +42245,31 @@
 +  testcase( rc==SQLITE_PROTOCOL );
 +  testcase( rc==SQLITE_OK );
 +  return rc;
- }
++}
  
--/* Return the value to pass to a sqlite3_wal_hook callback, the
--** number of frames in the WAL at the point of the last commit since
--** sqlite3WalCallback() was called.  If no commits have occurred since
--** the last call, then return 0.
+-  /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
+-  ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
+-  assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
 +/*
 +** Finish with a read transaction.  All this does is release the
 +** read-lock.
- */
--SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal){
--  u32 ret = 0;
--  if( pWal ){
--    ret = pWal->iCallback;
--    pWal->iCallback = 0;
++*/
 +SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){
 +  sqlite3WalEndWriteTransaction(pWal);
 +  if( pWal->readLock>=0 ){
 +    walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
 +    pWal->readLock = -1;
-   }
--  return (int)ret;
- }
- 
- /*
--** This function is called to change the WAL subsystem into or out
--** of locking_mode=EXCLUSIVE.
--**
--** If op is zero, then attempt to change from locking_mode=EXCLUSIVE
--** into locking_mode=NORMAL.  This means that we must acquire a lock
--** on the pWal->readLock byte.  If the WAL is already in locking_mode=NORMAL
--** or if the acquisition of the lock fails, then return 0.  If the
--** transition out of exclusive-mode is successful, return 1.  This
--** operation must occur while the pager is still holding the exclusive
--** lock on the main database file.
--**
--** If op is one, then change from locking_mode=NORMAL into 
--** locking_mode=EXCLUSIVE.  This means that the pWal->readLock must
--** be released.  Return 1 if the transition is made and 0 if the
--** WAL is already in exclusive-locking mode - meaning that this
--** routine is a no-op.  The pager must already hold the exclusive lock
--** on the main database file before invoking this operation.
++  }
++}
++
++/*
 +** Search the wal file for page pgno. If found, set *piRead to the frame that
 +** contains the page. Otherwise, if pgno is not in the wal file, set *piRead
 +** to zero.
- **
--** If op is negative, then do a dry-run of the op==1 case but do
--** not actually change anything. The pager uses this to see if it
--** should acquire the database exclusive lock prior to invoking
--** the op==1 case.
++**
 +** Return SQLITE_OK if successful, or an error code if an error occurs. If an
 +** error does occur, the final value of *piRead is undefined.
- */
--SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op){
--  int rc;
--  assert( pWal->writeLock==0 );
--  assert( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE || op==-1 );
++*/
 +SQLITE_PRIVATE int sqlite3WalFindFrame(
 +  Wal *pWal,                      /* WAL handle */
 +  Pgno pgno,                      /* Database page number to read data for */
@@ -8651,21 +42279,24 @@
 +  u32 iLast = pWal->hdr.mxFrame;  /* Last page in WAL for this reader */
 +  int iHash;                      /* Used to loop through N hash tables */
  
--  /* pWal->readLock is usually set, but might be -1 if there was a 
--  ** prior error while attempting to acquire are read-lock. This cannot 
--  ** happen if the connection is actually in exclusive mode (as no xShmLock
--  ** locks are taken in this case). Nor should the pager attempt to
--  ** upgrade to exclusive-mode following such an error.
--  */
+-  if( pWal->readOnly ) return SQLITE_READONLY;
+-  WALTRACE(("WAL%p: checkpoint begins\n", pWal));
 +  /* This routine is only be called from within a read transaction. */
-   assert( pWal->readLock>=0 || pWal->lockError );
--  assert( pWal->readLock>=0 || (op<=0 && pWal->exclusiveMode==0) );
++  assert( pWal->readLock>=0 || pWal->lockError );
  
--  if( op==0 ){
--    if( pWal->exclusiveMode ){
--      pWal->exclusiveMode = 0;
--      if( walLockShared(pWal, WAL_READ_LOCK(pWal->readLock))!=SQLITE_OK ){
--        pWal->exclusiveMode = 1;
+-  /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive 
+-  ** "checkpoint" lock on the database file. */
+-  rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1, 0);
+-  if( rc ){
+-    /* EVIDENCE-OF: R-10421-19736 If any other process is running a
+-    ** checkpoint operation at the same time, the lock cannot be obtained and
+-    ** SQLITE_BUSY is returned.
+-    ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
+-    ** it will not be invoked in this case.
+-    */
+-    testcase( rc==SQLITE_BUSY );
+-    testcase( xBusy!=0 );
+-    return rc;
 +  /* If the "last page" field of the wal-index header snapshot is 0, then
 +  ** no data will be read from the wal under any circumstances. Return early
 +  ** in this case as an optimization.  Likewise, if pWal->readLock==0, 
@@ -8675,12 +42306,20 @@
 +  if( iLast==0 || pWal->readLock==0 ){
 +    *piRead = 0;
 +    return SQLITE_OK;
-+  }
-+
+   }
+-  pWal->ckptLock = 1;
+ 
+-  /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
+-  ** TRUNCATE modes also obtain the exclusive "writer" lock on the database
+-  ** file.
 +  /* Search the hash table or tables for an entry matching page number
 +  ** pgno. Each iteration of the following for() loop searches one
 +  ** hash table (each hash table indexes up to HASHTABLE_NPAGE frames).
-+  **
+   **
+-  ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
+-  ** immediately, and a busy-handler is configured, it is invoked and the
+-  ** writer lock retried until either the busy-handler returns 0 or the
+-  ** lock is successfully obtained.
 +  ** This code might run concurrently to the code in walIndexAppend()
 +  ** that adds entries to the wal-index (and possibly to this hash 
 +  ** table). This means the value just read from the hash 
@@ -8701,7 +42340,17 @@
 +  **   (iFrame<=iLast): 
 +  **     This condition filters out entries that were added to the hash
 +  **     table after the current read-transaction had started.
-+  */
+   */
+-  if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
+-    rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1);
+-    if( rc==SQLITE_OK ){
+-      pWal->writeLock = 1;
+-    }else if( rc==SQLITE_BUSY ){
+-      eMode2 = SQLITE_CHECKPOINT_PASSIVE;
+-      xBusy2 = 0;
+-      rc = SQLITE_OK;
+-    }
+-  }
 +  for(iHash=walFramePage(iLast); iHash>=0 && iRead==0; iHash--){
 +    volatile ht_slot *aHash;      /* Pointer to hash table */
 +    volatile u32 *aPgno;          /* Pointer to array of page numbers */
@@ -8709,37 +42358,41 @@
 +    int iKey;                     /* Hash slot index */
 +    int nCollide;                 /* Number of hash collisions remaining */
 +    int rc;                       /* Error code */
-+
+ 
+-  /* Read the wal-index header. */
+-  if( rc==SQLITE_OK ){
+-    rc = walIndexReadHdr(pWal, &isChanged);
+-    if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
+-      sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
 +    rc = walHashGet(pWal, iHash, &aHash, &aPgno, &iZero);
 +    if( rc!=SQLITE_OK ){
 +      return rc;
-+    }
+     }
+-  }
+-
+-  /* Copy data from the log to the database file. */
+-  if( rc==SQLITE_OK ){
+-    if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
+-      rc = SQLITE_CORRUPT_BKPT;
+-    }else{
+-      rc = walCheckpoint(pWal, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
 +    nCollide = HASHTABLE_NSLOT;
 +    for(iKey=walHash(pgno); aHash[iKey]; iKey=walNextHash(iKey)){
 +      u32 iFrame = aHash[iKey] + iZero;
 +      if( iFrame<=iLast && aPgno[aHash[iKey]]==pgno ){
-+        /* assert( iFrame>iRead ); -- not true if there is corruption */
++        assert( iFrame>iRead || CORRUPT_DB );
 +        iRead = iFrame;
 +      }
 +      if( (nCollide--)==0 ){
 +        return SQLITE_CORRUPT_BKPT;
-       }
--      rc = pWal->exclusiveMode==0;
--    }else{
--      /* Already in locking_mode=NORMAL */
--      rc = 0;
++      }
      }
--  }else if( op>0 ){
--    assert( pWal->exclusiveMode==0 );
--    assert( pWal->readLock>=0 );
--    walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
--    pWal->exclusiveMode = 1;
--    rc = 1;
--  }else{
--    rc = pWal->exclusiveMode==0;
-   }
--  return rc;
-+
++  }
+ 
+-    /* If no error occurred, set the output variables. */
+-    if( rc==SQLITE_OK || rc==SQLITE_BUSY ){
+-      if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame;
+-      if( pnCkpt ) *pnCkpt = (int)(walCkptInfo(pWal)->nBackfill);
 +#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
 +  /* If expensive assert() statements are available, do a linear search
 +  ** of the wal-index file content. Make sure the results agree with the
@@ -8752,26 +42405,35 @@
 +        iRead2 = iTest;
 +        break;
 +      }
-+    }
+     }
 +    assert( iRead==iRead2 );
-+  }
+   }
 +#endif
-+
+ 
+-  if( isChanged ){
+-    /* If a new wal-index header was loaded before the checkpoint was 
+-    ** performed, then the pager-cache associated with pWal is now
+-    ** out of date. So zero the cached wal-index header to ensure that
+-    ** next time the pager opens a snapshot on this database it knows that
+-    ** the cache needs to be reset.
+-    */
+-    memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
+-  }
 +  *piRead = iRead;
 +  return SQLITE_OK;
- }
++}
  
--/* 
--** Return true if the argument is non-NULL and the WAL module is using
--** heap-memory for the wal-index. Otherwise, if the argument is NULL or the
--** WAL module is using shared-memory, return false. 
+-  /* Release the locks. */
+-  sqlite3WalEndWriteTransaction(pWal);
+-  walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
+-  pWal->ckptLock = 0;
+-  WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok"));
+-  return (rc==SQLITE_OK && eMode!=eMode2 ? SQLITE_BUSY : rc);
 +/*
 +** Read the contents of frame iRead from the wal file into buffer pOut
 +** (which is nOut bytes in size). Return SQLITE_OK if successful, or an
 +** error code otherwise.
- */
--SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal){
--  return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE );
++*/
 +SQLITE_PRIVATE int sqlite3WalReadFrame(
 +  Wal *pWal,                      /* WAL handle */
 +  u32 iRead,                      /* Frame to read */
@@ -8789,54 +42451,165 @@
 +  return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset);
  }
  
--#ifdef SQLITE_ENABLE_ZIPVFS
--/*
--** If the argument is not NULL, it points to a Wal object that holds a
--** read-lock. This function returns the database page-size if it is known,
--** or zero if it is not (or if pWal is NULL).
+-/* Return the value to pass to a sqlite3_wal_hook callback, the
+-** number of frames in the WAL at the point of the last commit since
+-** sqlite3WalCallback() was called.  If no commits have occurred since
+-** the last call, then return 0.
 +/* 
 +** Return the size of the database in pages (or zero, if unknown).
  */
--SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){
--  assert( pWal==0 || pWal->readLock>=0 );
--  return (pWal ? pWal->szPage : 0);
+-SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal){
+-  u32 ret = 0;
+-  if( pWal ){
+-    ret = pWal->iCallback;
+-    pWal->iCallback = 0;
 +SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal){
 +  if( pWal && ALWAYS(pWal->readLock>=0) ){
 +    return pWal->hdr.nPage;
-+  }
+   }
+-  return (int)ret;
 +  return 0;
  }
+ 
+-/*
+-** This function is called to change the WAL subsystem into or out
+-** of locking_mode=EXCLUSIVE.
++
++/* 
++** This function starts a write transaction on the WAL.
+ **
+-** If op is zero, then attempt to change from locking_mode=EXCLUSIVE
+-** into locking_mode=NORMAL.  This means that we must acquire a lock
+-** on the pWal->readLock byte.  If the WAL is already in locking_mode=NORMAL
+-** or if the acquisition of the lock fails, then return 0.  If the
+-** transition out of exclusive-mode is successful, return 1.  This
+-** operation must occur while the pager is still holding the exclusive
+-** lock on the main database file.
++** A read transaction must have already been started by a prior call
++** to sqlite3WalBeginReadTransaction().
+ **
+-** If op is one, then change from locking_mode=NORMAL into 
+-** locking_mode=EXCLUSIVE.  This means that the pWal->readLock must
+-** be released.  Return 1 if the transition is made and 0 if the
+-** WAL is already in exclusive-locking mode - meaning that this
+-** routine is a no-op.  The pager must already hold the exclusive lock
+-** on the main database file before invoking this operation.
++** If another thread or process has written into the database since
++** the read transaction was started, then it is not possible for this
++** thread to write as doing so would cause a fork.  So this routine
++** returns SQLITE_BUSY in that case and no write transaction is started.
+ **
+-** If op is negative, then do a dry-run of the op==1 case but do
+-** not actually change anything. The pager uses this to see if it
+-** should acquire the database exclusive lock prior to invoking
+-** the op==1 case.
++** There can only be a single writer active at a time.
+ */
+-SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op){
++SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){
+   int rc;
+-  assert( pWal->writeLock==0 );
+-  assert( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE || op==-1 );
+ 
+-  /* pWal->readLock is usually set, but might be -1 if there was a 
+-  ** prior error while attempting to acquire are read-lock. This cannot 
+-  ** happen if the connection is actually in exclusive mode (as no xShmLock
+-  ** locks are taken in this case). Nor should the pager attempt to
+-  ** upgrade to exclusive-mode following such an error.
+-  */
+-  assert( pWal->readLock>=0 || pWal->lockError );
+-  assert( pWal->readLock>=0 || (op<=0 && pWal->exclusiveMode==0) );
++  /* Cannot start a write transaction without first holding a read
++  ** transaction. */
++  assert( pWal->readLock>=0 );
+ 
+-  if( op==0 ){
+-    if( pWal->exclusiveMode ){
+-      pWal->exclusiveMode = 0;
+-      if( walLockShared(pWal, WAL_READ_LOCK(pWal->readLock))!=SQLITE_OK ){
+-        pWal->exclusiveMode = 1;
+-      }
+-      rc = pWal->exclusiveMode==0;
+-    }else{
+-      /* Already in locking_mode=NORMAL */
+-      rc = 0;
+-    }
+-  }else if( op>0 ){
+-    assert( pWal->exclusiveMode==0 );
+-    assert( pWal->readLock>=0 );
+-    walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
+-    pWal->exclusiveMode = 1;
+-    rc = 1;
+-  }else{
+-    rc = pWal->exclusiveMode==0;
++  if( pWal->readOnly ){
++    return SQLITE_READONLY;
+   }
+-  return rc;
+-}
+ 
+-/* 
+-** Return true if the argument is non-NULL and the WAL module is using
+-** heap-memory for the wal-index. Otherwise, if the argument is NULL or the
+-** WAL module is using shared-memory, return false. 
+-*/
+-SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal){
+-  return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE );
+-}
++  /* Only one writer allowed at a time.  Get the write lock.  Return
++  ** SQLITE_BUSY if unable.
++  */
++  rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 0);
++  if( rc ){
++    return rc;
++  }
++  pWal->writeLock = 1;
+ 
+-#ifdef SQLITE_ENABLE_ZIPVFS
+-/*
+-** If the argument is not NULL, it points to a Wal object that holds a
+-** read-lock. This function returns the database page-size if it is known,
+-** or zero if it is not (or if pWal is NULL).
+-*/
+-SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){
+-  assert( pWal==0 || pWal->readLock>=0 );
+-  return (pWal ? pWal->szPage : 0);
+-}
 -#endif
++  /* If another connection has written to the database file since the
++  ** time the read transaction on this connection was started, then
++  ** the write is disallowed.
++  */
++  if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){
++    walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
++    pWal->writeLock = 0;
++    rc = SQLITE_BUSY_SNAPSHOT;
++  }
  
 -#endif /* #ifndef SQLITE_OMIT_WAL */
++  return rc;
++}
  
 -/************** End of wal.c *************************************************/
 -/************** Begin file btmutex.c *****************************************/
--/*
+ /*
 -** 2007 August 27
 -**
 -** The author disclaims copyright to this source code.  In place of
 -** a legal notice, here is a blessing:
-+/* 
-+** This function starts a write transaction on the WAL.
- **
+-**
 -**    May you do good and not evil.
 -**    May you find forgiveness for yourself and forgive others.
 -**    May you share freely, never taking more than you give.
-+** A read transaction must have already been started by a prior call
-+** to sqlite3WalBeginReadTransaction().
- **
+-**
 -*************************************************************************
-+** If another thread or process has written into the database since
-+** the read transaction was started, then it is not possible for this
-+** thread to write as doing so would cause a fork.  So this routine
-+** returns SQLITE_BUSY in that case and no write transaction is started.
- **
+-**
 -** This file contains code used to implement mutexes on Btree objects.
 -** This code really belongs in btree.c.  But btree.c is getting too
 -** big and we want to break it down some.  This packaged seemed like
 -** a good breakout.
-+** There can only be a single writer active at a time.
++** End a write transaction.  The commit has already been done.  This
++** routine merely releases the lock.
  */
 -/************** Include btreeInt.h in the middle of btmutex.c ****************/
 -/************** Begin file btreeInt.h ****************************************/
@@ -8851,7 +42624,7 @@
 -**    May you share freely, never taking more than you give.
 -**
 -*************************************************************************
--** This file implements a external (disk-based) database using BTrees.
+-** This file implements an external (disk-based) database using BTrees.
 -** For a detailed discussion of BTrees, refer to
 -**
 -**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
@@ -8977,7 +42750,7 @@
 -**
 -** The flags define the format of this btree page.  The leaf flag means that
 -** this page has no children.  The zerodata flag means that this page carries
--** only keys and no data.  The intkey flag means that the key is a integer
+-** only keys and no data.  The intkey flag means that the key is an integer
 -** which is stored in the key size entry of the cell header rather than in
 -** the payload area.
 -**
@@ -9044,43 +42817,6 @@
 -**    SIZE    DESCRIPTION
 -**      4     Page number of next overflow page
 -**      *     Data
-+SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){
-+  int rc;
-+
-+  /* Cannot start a write transaction without first holding a read
-+  ** transaction. */
-+  assert( pWal->readLock>=0 );
-+
-+  if( pWal->readOnly ){
-+    return SQLITE_READONLY;
-+  }
-+
-+  /* Only one writer allowed at a time.  Get the write lock.  Return
-+  ** SQLITE_BUSY if unable.
-+  */
-+  rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
-+  if( rc ){
-+    return rc;
-+  }
-+  pWal->writeLock = 1;
-+
-+  /* If another connection has written to the database file since the
-+  ** time the read transaction on this connection was started, then
-+  ** the write is disallowed.
-+  */
-+  if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){
-+    walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
-+    pWal->writeLock = 0;
-+    rc = SQLITE_BUSY_SNAPSHOT;
-+  }
-+
-+  return rc;
-+}
-+
-+/*
-+** End a write transaction.  The commit has already been done.  This
-+** routine merely releases the lock.
-+*/
 +SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal){
 +  if( pWal->writeLock ){
 +    walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
@@ -9141,7 +42877,6 @@
 +    }
 +    if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal);
 +  }
-+  assert( rc==SQLITE_OK );
 +  return rc;
 +}
  
@@ -9175,7 +42910,10 @@
 -#define MX_CELL(pBt) ((pBt->pageSize-8)/6)
 +SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){
 +  int rc = SQLITE_OK;
-+
+ 
+-/* Forward declarations */
+-typedef struct MemPage MemPage;
+-typedef struct BtLock BtLock;
 +  assert( pWal->writeLock );
 +  assert( aWalData[3]!=pWal->nCkpt || aWalData[0]<=pWal->hdr.mxFrame );
 +
@@ -9198,10 +42936,6 @@
 +  return rc;
 +}
  
--/* Forward declarations */
--typedef struct MemPage MemPage;
--typedef struct BtLock BtLock;
- 
  /*
 -** This is a magic string that appears at the beginning of every
 -** SQLite database in order to identify the file as a real database.
@@ -9236,7 +42970,7 @@
 +    if( pInfo->nBackfill>0 ){
 +      u32 salt1;
 +      sqlite3_randomness(4, &salt1);
-+      rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
++      rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1, 0);
 +      if( rc==SQLITE_OK ){
 +        /* If all readers are using WAL_READ_LOCK(0) (in other words if no
 +        ** readers are currently using the WAL), then the transactions
@@ -9246,20 +42980,8 @@
 +        ** In theory it would be Ok to update the cache of the header only
 +        ** at this point. But updating the actual wal-index header is also
 +        ** safe and means there is no special case for sqlite3WalUndo()
-+        ** to handle if this transaction is rolled back.
-+        */
-+        int i;                    /* Loop counter */
-+        u32 *aSalt = pWal->hdr.aSalt;       /* Big-endian salt values */
-+
-+        pWal->nCkpt++;
-+        pWal->hdr.mxFrame = 0;
-+        sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
-+        aSalt[1] = salt1;
-+        walIndexWriteHdr(pWal);
-+        pInfo->nBackfill = 0;
-+        pInfo->aReadMark[1] = 0;
-+        for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
-+        assert( pInfo->aReadMark[0]==0 );
++        ** to handle if this transaction is rolled back.  */
++        walRestartHdr(pWal, salt1);
 +        walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
 +      }else if( rc!=SQLITE_BUSY ){
 +        return rc;
@@ -9320,12 +43042,14 @@
 -struct MemPage {
 -  u8 isInit;           /* True if previously initialized. MUST BE FIRST! */
 -  u8 nOverflow;        /* Number of overflow cell bodies in aCell[] */
--  u8 intKey;           /* True if intkey flag is set */
--  u8 leaf;             /* True if leaf flag is set */
--  u8 hasData;          /* True if this page stores data */
+-  u8 intKey;           /* True if table b-trees.  False for index b-trees */
+-  u8 intKeyLeaf;       /* True if the leaf of an intKey table */
+-  u8 noPayload;        /* True if internal intKey page (thus w/o data) */
+-  u8 leaf;             /* True if a leaf page */
 -  u8 hdrOffset;        /* 100 for page 1.  0 otherwise */
 -  u8 childPtrSize;     /* 0 if leaf==1.  4 if leaf==0 */
 -  u8 max1bytePayload;  /* min(maxLocal,127) */
+-  u8 bBusy;            /* Prevent endless loops on corrupt database files */
 -  u16 maxLocal;        /* Copy of BtShared.maxLocal or BtShared.maxLeaf */
 -  u16 minLocal;        /* Copy of BtShared.minLocal or BtShared.minLeaf */
 -  u16 cellOffset;      /* Index in aData of first cell pointer */
@@ -9461,6 +43185,7 @@
 -  u8 locked;         /* True if db currently has pBt locked */
 -  int wantToLock;    /* Number of nested calls to sqlite3BtreeEnter() */
 -  int nBackup;       /* Number of backup operations reading this btree */
+-  u32 iDataVersion;  /* Combines with pBt->pPager->iDataVersion */
 -  Btree *pNext;      /* List of other sharable Btrees from the same db */
 -  Btree *pPrev;      /* Back pointer of the same list */
 -#ifndef SQLITE_OMIT_SHARED_CACHE
@@ -9565,7 +43290,7 @@
 +  **
 +  ** Padding and syncing only occur if this set of frames complete a
 +  ** transaction and if PRAGMA synchronous=FULL.  If synchronous==NORMAL
-+  ** or synchonous==OFF, then no padding or syncing are needed.
++  ** or synchronous==OFF, then no padding or syncing are needed.
 +  **
 +  ** If SQLITE_IOCAP_POWERSAFE_OVERWRITE is defined, then padding is not
 +  ** needed and only the sync is done.  If padding is needed, then the
@@ -9694,6 +43419,9 @@
 -#endif
 -  u8 inTransaction;     /* Transaction state */
 -  u8 max1bytePayload;   /* Maximum first byte of cell for a 1-byte payload */
+-#ifdef SQLITE_HAS_CODEC
+-  u8 optimalReserve;    /* Desired amount of reserved space per page */
+-#endif
 -  u16 btsFlags;         /* Boolean parameters.  See BTS_* macros below */
 -  u16 maxLocal;         /* Maximum local payload in non-LEAFDATA tables */
 -  u16 minLocal;         /* Minimum local payload in non-LEAFDATA tables */
@@ -9713,11 +43441,11 @@
 -  BtLock *pLock;        /* List of locks held on this shared-btree struct */
 -  Btree *pWriter;       /* Btree with currently open write transaction */
 -#endif
--  u8 *pTmpSpace;        /* BtShared.pageSize bytes of space for tmp use */
+-  u8 *pTmpSpace;        /* Temp space sufficient to hold a single cell */
 -};
 +SQLITE_PRIVATE int sqlite3WalCheckpoint(
 +  Wal *pWal,                      /* Wal connection */
-+  int eMode,                      /* PASSIVE, FULL or RESTART */
++  int eMode,                      /* PASSIVE, FULL, RESTART, or TRUNCATE */
 +  int (*xBusy)(void*),            /* Function to call when busy */
 +  void *pBusyArg,                 /* Context argument for xBusyHandler */
 +  int sync_flags,                 /* Flags to sync db file with (or 0) */
@@ -9729,6 +43457,7 @@
 +  int rc;                         /* Return code */
 +  int isChanged = 0;              /* True if a new wal-index header is loaded */
 +  int eMode2 = eMode;             /* Mode to pass to walCheckpoint() */
++  int (*xBusy2)(void*) = xBusy;   /* Busy handler for eMode2 */
  
 -/*
 -** Allowed values for BtShared.btsFlags
@@ -9750,25 +43479,16 @@
 -*/
 -typedef struct CellInfo CellInfo;
 -struct CellInfo {
--  i64 nKey;      /* The key for INTKEY tables, or number of bytes in key */
--  u8 *pCell;     /* Pointer to the start of cell content */
--  u32 nData;     /* Number of bytes of data */
--  u32 nPayload;  /* Total amount of payload */
--  u16 nHeader;   /* Size of the cell content header in bytes */
--  u16 nLocal;    /* Amount of payload held locally */
+-  i64 nKey;      /* The key for INTKEY tables, or nPayload otherwise */
+-  u8 *pPayload;  /* Pointer to the start of payload */
+-  u32 nPayload;  /* Bytes of payload */
+-  u16 nLocal;    /* Amount of payload held locally, not on overflow */
 -  u16 iOverflow; /* Offset to overflow page number.  Zero if no overflow */
 -  u16 nSize;     /* Size of the cell content on the main b-tree page */
 -};
-+  if( pWal->readOnly ) return SQLITE_READONLY;
-+  WALTRACE(("WAL%p: checkpoint begins\n", pWal));
-+  rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
-+  if( rc ){
-+    /* Usually this is SQLITE_BUSY meaning that another thread or process
-+    ** is already running a checkpoint, or maybe a recovery.  But it might
-+    ** also be SQLITE_IOERR. */
-+    return rc;
-+  }
-+  pWal->ckptLock = 1;
++  /* EVIDENCE-OF: R-62920-47450 The busy-handler callback is never invoked
++  ** in the SQLITE_CHECKPOINT_PASSIVE mode. */
++  assert( eMode!=SQLITE_CHECKPOINT_PASSIVE || xBusy==0 );
  
 -/*
 -** Maximum depth of an SQLite B-Tree structure. Any B-Tree deeper than
@@ -9780,24 +43500,8 @@
 -** assumed that the database is corrupt.
 -*/
 -#define BTCURSOR_MAX_DEPTH 20
-+  /* If this is a blocking-checkpoint, then obtain the write-lock as well
-+  ** to prevent any writers from running while the checkpoint is underway.
-+  ** This has to be done before the call to walIndexReadHdr() below.
-+  **
-+  ** If the writer lock cannot be obtained, then a passive checkpoint is
-+  ** run instead. Since the checkpointer is not holding the writer lock,
-+  ** there is no point in blocking waiting for any readers. Assuming no 
-+  ** other error occurs, this function will return SQLITE_BUSY to the caller.
-+  */
-+  if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
-+    rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1);
-+    if( rc==SQLITE_OK ){
-+      pWal->writeLock = 1;
-+    }else if( rc==SQLITE_BUSY ){
-+      eMode2 = SQLITE_CHECKPOINT_PASSIVE;
-+      rc = SQLITE_OK;
-+    }
-+  }
++  if( pWal->readOnly ) return SQLITE_READONLY;
++  WALTRACE(("WAL%p: checkpoint begins\n", pWal));
  
 -/*
 -** A cursor is a pointer to a particular entry within a particular
@@ -9812,6 +43516,11 @@
 -**
 -** Fields in this structure are accessed under the BtShared.mutex
 -** found at self->pBt->mutex. 
+-**
+-** skipNext meaning:
+-**    eState==SKIPNEXT && skipNext>0:  Next sqlite3BtreeNext() is no-op.
+-**    eState==SKIPNEXT && skipNext<0:  Next sqlite3BtreePrevious() is no-op.
+-**    eState==FAULT:                   Cursor fault with skipNext as error code.
 -*/
 -struct BtCursor {
 -  Btree *pBtree;            /* The Btree to which this cursor belongs */
@@ -9824,7 +43533,8 @@
 -  void *pKey;               /* Saved key that was cursor last known position */
 -  Pgno pgnoRoot;            /* The root page of this tree */
 -  int nOvflAlloc;           /* Allocated size of aOverflow[] array */
--  int skipNext;    /* Prev() is noop if negative. Next() is noop if positive */
+-  int skipNext;    /* Prev() is noop if negative. Next() is noop if positive.
+-                   ** Error code if eState==CURSOR_FAULT */
 -  u8 curFlags;              /* zero or more BTCF_* flags defined below */
 -  u8 eState;                /* One of the CURSOR_XXX constants (see below) */
 -  u8 hints;                             /* As configured by CursorSetHints() */
@@ -9832,13 +43542,21 @@
 -  u16 aiIdx[BTCURSOR_MAX_DEPTH];        /* Current index in apPage[i] */
 -  MemPage *apPage[BTCURSOR_MAX_DEPTH];  /* Pages from root to current page */
 -};
-+  /* Read the wal-index header. */
-+  if( rc==SQLITE_OK ){
-+    rc = walIndexReadHdr(pWal, &isChanged);
-+    if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
-+      sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
-+    }
++  /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive 
++  ** "checkpoint" lock on the database file. */
++  rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1, 0);
++  if( rc ){
++    /* EVIDENCE-OF: R-10421-19736 If any other process is running a
++    ** checkpoint operation at the same time, the lock cannot be obtained and
++    ** SQLITE_BUSY is returned.
++    ** EVIDENCE-OF: R-53820-33897 Even if there is a busy-handler configured,
++    ** it will not be invoked in this case.
++    */
++    testcase( rc==SQLITE_BUSY );
++    testcase( xBusy!=0 );
++    return rc;
 +  }
++  pWal->ckptLock = 1;
  
 -/*
 -** Legal values for BtCursor.curFlags
@@ -9848,13 +43566,25 @@
 -#define BTCF_ValidOvfl    0x04   /* True if aOverflow is valid */
 -#define BTCF_AtLast       0x08   /* Cursor is pointing ot the last entry */
 -#define BTCF_Incrblob     0x10   /* True if an incremental I/O handle */
-+  /* Copy data from the log to the database file. */
-+  if( rc==SQLITE_OK ){
-+    if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
-+      rc = SQLITE_CORRUPT_BKPT;
-+    }else{
-+      rc = walCheckpoint(pWal, eMode2, xBusy, pBusyArg, sync_flags, zBuf);
++  /* IMPLEMENTATION-OF: R-59782-36818 The SQLITE_CHECKPOINT_FULL, RESTART and
++  ** TRUNCATE modes also obtain the exclusive "writer" lock on the database
++  ** file.
++  **
++  ** EVIDENCE-OF: R-60642-04082 If the writer lock cannot be obtained
++  ** immediately, and a busy-handler is configured, it is invoked and the
++  ** writer lock retried until either the busy-handler returns 0 or the
++  ** lock is successfully obtained.
++  */
++  if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
++    rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1);
++    if( rc==SQLITE_OK ){
++      pWal->writeLock = 1;
++    }else if( rc==SQLITE_BUSY ){
++      eMode2 = SQLITE_CHECKPOINT_PASSIVE;
++      xBusy2 = 0;
++      rc = SQLITE_OK;
 +    }
++  }
  
 -/*
 -** Potential values for BtCursor.eState.
@@ -9880,21 +43610,22 @@
 -**   seek the cursor to the saved position.
 -**
 -** CURSOR_FAULT:
--**   A unrecoverable error (an I/O error or a malloc failure) has occurred
+-**   An unrecoverable error (an I/O error or a malloc failure) has occurred
 -**   on a different connection that shares the BtShared cache with this
 -**   cursor.  The error has left the cache in an inconsistent state.
 -**   Do nothing else with this cursor.  Any attempt to use the cursor
--**   should return the error code stored in BtCursor.skip
+-**   should return the error code stored in BtCursor.skipNext
 -*/
 -#define CURSOR_INVALID           0
 -#define CURSOR_VALID             1
 -#define CURSOR_SKIPNEXT          2
 -#define CURSOR_REQUIRESEEK       3
 -#define CURSOR_FAULT             4
-+    /* If no error occurred, set the output variables. */
-+    if( rc==SQLITE_OK || rc==SQLITE_BUSY ){
-+      if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame;
-+      if( pnCkpt ) *pnCkpt = (int)(walCkptInfo(pWal)->nBackfill);
++  /* Read the wal-index header. */
++  if( rc==SQLITE_OK ){
++    rc = walIndexReadHdr(pWal, &isChanged);
++    if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){
++      sqlite3OsUnfetch(pWal->pDbFd, 0, 0);
 +    }
 +  }
  
@@ -9902,15 +43633,13 @@
 -** The database page the PENDING_BYTE occupies. This page is never used.
 -*/
 -# define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt)
-+  if( isChanged ){
-+    /* If a new wal-index header was loaded before the checkpoint was 
-+    ** performed, then the pager-cache associated with pWal is now
-+    ** out of date. So zero the cached wal-index header to ensure that
-+    ** next time the pager opens a snapshot on this database it knows that
-+    ** the cache needs to be reset.
-+    */
-+    memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
-+  }
++  /* Copy data from the log to the database file. */
++  if( rc==SQLITE_OK ){
++    if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){
++      rc = SQLITE_CORRUPT_BKPT;
++    }else{
++      rc = walCheckpoint(pWal, eMode2, xBusy2, pBusyArg, sync_flags, zBuf);
++    }
  
 -/*
 -** These macros define the location of the pointer-map entry for a 
@@ -9926,6 +43655,23 @@
 -** then pgno is returned. So (pgno==PTRMAP_PAGENO(pgsz, pgno)) can be
 -** used to test if pgno is a pointer-map page. PTRMAP_ISPAGE implements
 -** this test.
++    /* If no error occurred, set the output variables. */
++    if( rc==SQLITE_OK || rc==SQLITE_BUSY ){
++      if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame;
++      if( pnCkpt ) *pnCkpt = (int)(walCkptInfo(pWal)->nBackfill);
++    }
++  }
++
++  if( isChanged ){
++    /* If a new wal-index header was loaded before the checkpoint was 
++    ** performed, then the pager-cache associated with pWal is now
++    ** out of date. So zero the cached wal-index header to ensure that
++    ** next time the pager opens a snapshot on this database it knows that
++    ** the cache needs to be reset.
++    */
++    memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
++  }
++
 +  /* Release the locks. */
 +  sqlite3WalEndWriteTransaction(pWal);
 +  walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
@@ -10103,6 +43849,8 @@
 -  int mxErr;        /* Stop accumulating errors when this reaches zero */
 -  int nErr;         /* Number of messages written to zErrMsg so far */
 -  int mallocFailed; /* A memory allocation error has occurred */
+-  const char *zPfx; /* Error message prefix */
+-  int v1, v2;       /* Values for up to two %d fields in zPfx */
 -  StrAccum errMsg;  /* Accumulate the error message text here */
 -};
 -
@@ -10132,7 +43880,7 @@
  #ifndef SQLITE_OMIT_SHARED_CACHE
  #if SQLITE_THREADSAFE
  
-@@ -93233,10 +96142,24 @@
+@@ -98030,10 +101008,24 @@
  */
  SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3 *db){
    int rc = sqlite3_overload_function(db, "MATCH", 2);
@@ -10157,7 +43905,7 @@
  }
  
  /*
-@@ -98888,24 +101811,6 @@
+@@ -103838,24 +106830,6 @@
    return azModeName[eMode];
  }
  
@@ -10182,20 +43930,19 @@
  /*
  ** Process a pragma statement.  
  **
-@@ -98939,6 +101844,12 @@
-   sqlite3 *db = pParse->db;    /* The database connection */
+@@ -103890,6 +106864,11 @@
    Db *pDb;                     /* The specific database being pragmaed */
    Vdbe *v = sqlite3GetVdbe(pParse);  /* Prepared statement */
+   const struct sPragmaNames *pPragma;
 +/* BEGIN SQLCIPHER */
 +#ifdef SQLITE_HAS_CODEC
 +  extern int sqlcipher_codec_pragma(sqlite3*, int, Parse *, const char *, const char *);
 +#endif
 +/* END SQLCIPHER */
-+
  
    if( v==0 ) return;
    sqlite3VdbeRunOnlyOnce(v);
-@@ -98999,8 +101910,18 @@
+@@ -103961,8 +106940,18 @@
      }
      pParse->nErr++;
      pParse->rc = rc;
@@ -10214,7 +43961,7 @@
  
    /* Locate the pragma in the lookup table */
    lwr = 0;
-@@ -99632,54 +102553,6 @@
+@@ -104602,54 +107591,6 @@
  
  #ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
    /*



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]